LCOV - code coverage report
Current view: top level - source4/kdc - authn_policy_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 368 448 82.1 %
Date: 2024-04-21 15:09:00 Functions: 22 23 95.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba Active Directory authentication policy utility functions
       4             : 
       5             :    Copyright (C) Catalyst.Net Ltd 2023
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "lib/replace/replace.h"
      22             : #include "source4/kdc/authn_policy_util.h"
      23             : #include "auth/authn_policy_impl.h"
      24             : #include "lib/util/debug.h"
      25             : #include "lib/util/samba_util.h"
      26             : #include "libcli/security/security.h"
      27             : #include "libcli/util/werror.h"
      28             : #include "auth/common_auth.h"
      29             : #include "source4/auth/session.h"
      30             : #include "source4/dsdb/samdb/samdb.h"
      31             : #include "source4/dsdb/samdb/ldb_modules/util.h"
      32             : 
      33      232081 : bool authn_policy_silos_and_policies_in_effect(struct ldb_context *samdb)
      34             : {
      35             :         /*
      36             :          * Authentication Silos and Authentication Policies are not
      37             :          * honoured by Samba unless the DC is at FL 2012 R2.  This is
      38             :          * to match Windows, which will offer these features as soon
      39             :          * as the DC is upgraded.
      40             :          */
      41      232081 :         const int functional_level = dsdb_dc_functional_level(samdb);
      42      232081 :         return functional_level >= DS_DOMAIN_FUNCTION_2012_R2;
      43             : }
      44             : 
      45         100 : bool authn_policy_allowed_ntlm_network_auth_in_effect(struct ldb_context *samdb)
      46             : {
      47             :         /*
      48             :          * The allowed NTLM network authentication Policies are not
      49             :          * honoured by Samba unless the DC is at FL2016.  This
      50             :          * is to match Windows, which will enforce these restrictions
      51             :          * as soon as the DC is upgraded.
      52             :          */
      53         100 :         const int functional_level = dsdb_dc_functional_level(samdb);
      54         100 :         return functional_level >= DS_DOMAIN_FUNCTION_2016;
      55             : }
      56             : 
      57             : /*
      58             :  * Depending on the type of the account, we need to refer to different
      59             :  * attributes of authentication silo objects. This structure keeps track of the
      60             :  * attributes to use for a certain account type.
      61             :  */
      62             : struct authn_silo_attrs {
      63             :         const char *policy;
      64             :         const char *attrs[];
      65             : };
      66             : 
      67             : /*
      68             :  * Depending on the type of the account, we need to refer to different
      69             :  * attributes of authentication policy objects. This structure keeps track of
      70             :  * the attributes to use for a certain account type.
      71             :  */
      72             : struct authn_policy_attrs {
      73             :         /* This applies at FL2016 and up. */
      74             :         const char *allowed_ntlm_network_auth;
      75             :         /* The remainder apply at FL2012_R2 and up. */
      76             :         const char *allowed_to_authenticate_from;
      77             :         const char *allowed_to_authenticate_to;
      78             :         const char *tgt_lifetime;
      79             :         const char *attrs[];
      80             : };
      81             : 
      82             : struct authn_attrs {
      83             :         const struct authn_silo_attrs *silo;
      84             :         const struct authn_policy_attrs *policy;
      85             : };
      86             : 
      87             : /*
      88             :  * Get the authentication attributes that apply to an account of a certain
      89             :  * class.
      90             :  */
      91       70736 : static const struct authn_attrs authn_policy_get_attrs(const struct ldb_message *msg)
      92             : {
      93       70736 :         const struct authn_attrs null_authn_attrs = {
      94             :                 .silo = NULL,
      95             :                 .policy = NULL,
      96             :         };
      97       70736 :         const struct ldb_message_element *objectclass_el = NULL;
      98        5056 :         unsigned i;
      99             : 
     100       70736 :         objectclass_el = ldb_msg_find_element(msg, "objectClass");
     101       70736 :         if (objectclass_el == NULL || objectclass_el->num_values == 0) {
     102           0 :                 return null_authn_attrs;
     103             :         }
     104             : 
     105             :         /*
     106             :          * Iterate over the objectClasses, starting at the most-derived class.
     107             :          */
     108       70771 :         for (i = objectclass_el->num_values; i > 0; --i) {
     109       70771 :                 const struct ldb_val *objectclass_val = &objectclass_el->values[i - 1];
     110       70771 :                 const char *objectclass = NULL;
     111             : 
     112       70771 :                 objectclass = (const char *)objectclass_val->data;
     113       70771 :                 if (objectclass == NULL) {
     114           0 :                         continue;
     115             :                 }
     116             : 
     117             : #define COMMON_AUTHN_SILO_ATTRS \
     118             :         "msDS-AuthNPolicySiloEnforced", \
     119             :         "msDS-AuthNPolicySiloMembers", \
     120             :         "name"
     121             : 
     122             : #define COMMON_AUTHN_POLICY_ATTRS \
     123             :         "msDS-AuthNPolicyEnforced", \
     124             :         "msDS-StrongNTLMPolicy", \
     125             :         "name"
     126             : 
     127             :                 /*
     128             :                  * See which of three classes this object is most closely
     129             :                  * derived from.
     130             :                  */
     131       70771 :                 if (strcasecmp(objectclass, "user") == 0) {
     132        2913 :                         static const struct authn_silo_attrs user_authn_silo_attrs = {
     133             :                                 .policy = "msDS-UserAuthNPolicy",
     134             :                                 .attrs = {
     135             :                                         COMMON_AUTHN_SILO_ATTRS,
     136             :                                         "msDS-UserAuthNPolicy",
     137             :                                         NULL,
     138             :                                 },
     139             :                         };
     140             : 
     141        2913 :                         static const struct authn_policy_attrs user_authn_policy_attrs = {
     142             :                                 .allowed_ntlm_network_auth = "msDS-UserAllowedNTLMNetworkAuthentication",
     143             :                                 .allowed_to_authenticate_from = "msDS-UserAllowedToAuthenticateFrom",
     144             :                                 .allowed_to_authenticate_to = "msDS-UserAllowedToAuthenticateTo",
     145             :                                 .tgt_lifetime = "msDS-UserTGTLifetime",
     146             :                                 .attrs = {
     147             :                                         COMMON_AUTHN_POLICY_ATTRS,
     148             :                                         "msDS-UserAllowedNTLMNetworkAuthentication",
     149             :                                         "msDS-UserAllowedToAuthenticateFrom",
     150             :                                         "msDS-UserAllowedToAuthenticateTo",
     151             :                                         "msDS-UserTGTLifetime",
     152             :                                         NULL,
     153             :                                 },
     154             :                         };
     155             : 
     156       40962 :                         return (struct authn_attrs) {
     157             :                                 .silo = &user_authn_silo_attrs,
     158             :                                 .policy = &user_authn_policy_attrs,
     159             :                         };
     160             :                 }
     161             : 
     162       29809 :                 if (strcasecmp(objectclass, "computer") == 0) {
     163        2143 :                         static const struct authn_silo_attrs computer_authn_silo_attrs = {
     164             :                                 .policy = "msDS-ComputerAuthNPolicy",
     165             :                                 .attrs = {
     166             :                                         COMMON_AUTHN_SILO_ATTRS,
     167             :                                         "msDS-ComputerAuthNPolicy",
     168             :                                         NULL,
     169             :                                 },
     170             :                         };
     171             : 
     172        2143 :                         static const struct authn_policy_attrs computer_authn_policy_attrs = {
     173             :                                 .allowed_ntlm_network_auth = NULL,
     174             :                                 .allowed_to_authenticate_from = NULL,
     175             :                                 .allowed_to_authenticate_to = "msDS-ComputerAllowedToAuthenticateTo",
     176             :                                 .tgt_lifetime = "msDS-ComputerTGTLifetime",
     177             :                                 .attrs = {
     178             :                                         COMMON_AUTHN_POLICY_ATTRS,
     179             :                                         "msDS-ComputerAllowedToAuthenticateTo",
     180             :                                         "msDS-ComputerTGTLifetime",
     181             :                                         NULL,
     182             :                                 },
     183             :                         };
     184             : 
     185       29669 :                         return (struct authn_attrs) {
     186             :                                 .silo = &computer_authn_silo_attrs,
     187             :                                 .policy = &computer_authn_policy_attrs,
     188             :                         };
     189             :                 }
     190             : 
     191         140 :                 if (strcasecmp(objectclass, "msDS-ManagedServiceAccount") == 0) {
     192           0 :                         static const struct authn_silo_attrs service_authn_silo_attrs = {
     193             :                                 .policy = "msDS-ServiceAuthNPolicy",
     194             :                                 .attrs = {
     195             :                                         COMMON_AUTHN_SILO_ATTRS,
     196             :                                         "msDS-ServiceAuthNPolicy",
     197             :                                         NULL,
     198             :                                 },
     199             :                         };
     200             : 
     201           0 :                         static const struct authn_policy_attrs service_authn_policy_attrs = {
     202             :                                 .allowed_ntlm_network_auth = "msDS-ServiceAllowedNTLMNetworkAuthentication",
     203             :                                 .allowed_to_authenticate_from = "msDS-ServiceAllowedToAuthenticateFrom",
     204             :                                 .allowed_to_authenticate_to = "msDS-ServiceAllowedToAuthenticateTo",
     205             :                                 .tgt_lifetime = "msDS-ServiceTGTLifetime",
     206             :                                 .attrs = {
     207             :                                         COMMON_AUTHN_POLICY_ATTRS,
     208             :                                         "msDS-ServiceAllowedNTLMNetworkAuthentication",
     209             :                                         "msDS-ServiceAllowedToAuthenticateFrom",
     210             :                                         "msDS-ServiceAllowedToAuthenticateTo",
     211             :                                         "msDS-ServiceTGTLifetime",
     212             :                                         NULL,
     213             :                                 },
     214             :                         };
     215             : 
     216         105 :                         return (struct authn_attrs) {
     217             :                                 .silo = &service_authn_silo_attrs,
     218             :                                 .policy = &service_authn_policy_attrs,
     219             :                         };
     220             :                 }
     221             :         }
     222             : 
     223             : #undef COMMON_AUTHN_SILO_ATTRS
     224             : #undef COMMON_AUTHN_POLICY_ATTRS
     225             : 
     226             :         /* No match — this object is not a user. */
     227           0 :         return null_authn_attrs;
     228             : }
     229             : 
     230             : /*
     231             :  * Look up the silo assigned to an account. If one exists, returns its details
     232             :  * and whether it is enforced or not. ‘silo_attrs’ comprises the attributes to
     233             :  * include in the search result, the relevant set of which can differ depending
     234             :  * on the account’s objectClass.
     235             :  */
     236       85524 : int authn_policy_get_assigned_silo(struct ldb_context *samdb,
     237             :                                    TALLOC_CTX *mem_ctx,
     238             :                                    const struct ldb_message *msg,
     239             :                                    const char * const *silo_attrs,
     240             :                                    const struct ldb_message **silo_msg_out,
     241             :                                    bool *is_enforced)
     242             : {
     243       85524 :         TALLOC_CTX *tmp_ctx = NULL;
     244       85524 :         int ret = 0;
     245       85524 :         const struct ldb_message_element *authn_silo = NULL;
     246       85524 :         struct ldb_dn *authn_silo_dn = NULL;
     247       85524 :         struct ldb_message *authn_silo_msg = NULL;
     248       85524 :         const struct ldb_message_element *members = NULL;
     249       85524 :         const char *linearized_dn = NULL;
     250        6226 :         struct ldb_val linearized_dn_val;
     251             : 
     252       85524 :         *silo_msg_out = NULL;
     253       85524 :         *is_enforced = true;
     254             : 
     255       85524 :         if (!authn_policy_silos_and_policies_in_effect(samdb)) {
     256           0 :                 return 0;
     257             :         }
     258             : 
     259       85524 :         tmp_ctx = talloc_new(mem_ctx);
     260       85524 :         if (tmp_ctx == NULL) {
     261           0 :                 ret = ENOMEM;
     262           0 :                 goto out;
     263             :         }
     264             : 
     265       85524 :         authn_silo = ldb_msg_find_element(msg, "msDS-AssignedAuthNPolicySilo");
     266             :         /* Is the account assigned to a silo? */
     267       85524 :         if (authn_silo == NULL || !authn_silo->num_values) {
     268       85429 :                 goto out;
     269             :         }
     270             : 
     271          95 :         authn_silo_dn = ldb_dn_from_ldb_val(tmp_ctx, samdb, &authn_silo->values[0]);
     272          95 :         if (authn_silo_dn == NULL) {
     273           0 :                 ret = ENOMEM;
     274           0 :                 goto out;
     275             :         }
     276             : 
     277          95 :         ret = dsdb_search_one(samdb,
     278             :                               tmp_ctx,
     279             :                               &authn_silo_msg,
     280             :                               authn_silo_dn,
     281             :                               LDB_SCOPE_BASE,
     282             :                               silo_attrs,
     283             :                               0, NULL);
     284          95 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     285             :                 /* Not found. */
     286           0 :                 ret = 0;
     287           0 :                 goto out;
     288             :         }
     289          95 :         if (ret) {
     290           0 :                 goto out;
     291             :         }
     292             : 
     293          95 :         members = ldb_msg_find_element(authn_silo_msg,
     294             :                                        "msDS-AuthNPolicySiloMembers");
     295          95 :         if (members == NULL) {
     296          14 :                 goto out;
     297             :         }
     298             : 
     299          81 :         linearized_dn = ldb_dn_get_linearized(msg->dn);
     300          81 :         if (linearized_dn == NULL) {
     301           0 :                 ret = ENOMEM;
     302           0 :                 goto out;
     303             :         }
     304             : 
     305          81 :         linearized_dn_val = data_blob_string_const(linearized_dn);
     306             :         /* Is the account a member of the silo? */
     307          81 :         if (!ldb_msg_find_val(members, &linearized_dn_val)) {
     308           0 :                 goto out;
     309             :         }
     310             : 
     311             :         /* Is the silo actually enforced? */
     312          81 :         *is_enforced = ldb_msg_find_attr_as_bool(
     313             :                 authn_silo_msg,
     314             :                 "msDS-AuthNPolicySiloEnforced",
     315             :                 false);
     316             : 
     317          81 :         *silo_msg_out = talloc_move(mem_ctx, &authn_silo_msg);
     318             : 
     319       85524 : out:
     320       85524 :         talloc_free(tmp_ctx);
     321       85524 :         return ret;
     322             : }
     323             : 
     324             : /*
     325             :  * Look up the authentication policy assigned to an account, returning its
     326             :  * details if it exists. ‘authn_attrs’ specifies which attributes are relevant,
     327             :  * and should be chosen based on the account’s objectClass.
     328             :  */
     329       68286 : static int samba_kdc_authn_policy_msg(struct ldb_context *samdb,
     330             :                                       TALLOC_CTX *mem_ctx,
     331             :                                       const struct ldb_message *msg,
     332             :                                       const struct authn_attrs authn_attrs,
     333             :                                       struct ldb_message **authn_policy_msg_out,
     334             :                                       struct authn_policy *authn_policy_out)
     335             : {
     336       68286 :         TALLOC_CTX *tmp_ctx = NULL;
     337       68286 :         int ret = 0;
     338       68286 :         const struct ldb_message *authn_silo_msg = NULL;
     339       68286 :         const struct ldb_message_element *authn_policy = NULL;
     340       68286 :         const char *silo_name = NULL;
     341       68286 :         const char *policy_name = NULL;
     342       68286 :         struct ldb_dn *authn_policy_dn = NULL;
     343       68286 :         struct ldb_message *authn_policy_msg = NULL;
     344       68286 :         bool belongs_to_silo = false;
     345       68286 :         bool is_enforced = true;
     346             : 
     347       68286 :         *authn_policy_msg_out = NULL;
     348       68286 :         *authn_policy_out = (struct authn_policy) {};
     349             : 
     350       68286 :         tmp_ctx = talloc_new(mem_ctx);
     351       68286 :         if (tmp_ctx == NULL) {
     352           0 :                 ret = ENOMEM;
     353           0 :                 goto out;
     354             :         }
     355             : 
     356             :         /* See whether the account is assigned to a silo. */
     357       73342 :         ret = authn_policy_get_assigned_silo(samdb,
     358             :                                              tmp_ctx,
     359             :                                              msg,
     360       68286 :                                              authn_attrs.silo->attrs,
     361             :                                              &authn_silo_msg,
     362             :                                              &is_enforced);
     363       68286 :         if (ret) {
     364           0 :                 goto out;
     365             :         }
     366             : 
     367       68286 :         if (authn_silo_msg != NULL) {
     368          53 :                 belongs_to_silo = true;
     369             : 
     370          53 :                 silo_name = ldb_msg_find_attr_as_string(authn_silo_msg, "name", NULL);
     371             : 
     372             :                 /* Get the applicable authentication policy. */
     373          53 :                 authn_policy = ldb_msg_find_element(
     374             :                         authn_silo_msg,
     375          53 :                         authn_attrs.silo->policy);
     376             :         } else {
     377             :                 /*
     378             :                  * If no silo is assigned, take the policy that is directly
     379             :                  * assigned to the account.
     380             :                  */
     381       68233 :                 authn_policy = ldb_msg_find_element(msg, "msDS-AssignedAuthNPolicy");
     382             :         }
     383             : 
     384       68286 :         if (authn_policy == NULL || !authn_policy->num_values) {
     385             :                 /* No policy applies; we’re done. */
     386       67447 :                 goto out;
     387             :         }
     388             : 
     389         839 :         authn_policy_dn = ldb_dn_from_ldb_val(tmp_ctx, samdb, &authn_policy->values[0]);
     390         839 :         if (authn_policy_dn == NULL) {
     391           0 :                 ret = ENOMEM;
     392           0 :                 goto out;
     393             :         }
     394             : 
     395             :         /* Look up the policy object. */
     396         839 :         ret = dsdb_search_one(samdb,
     397             :                               tmp_ctx,
     398             :                               &authn_policy_msg,
     399             :                               authn_policy_dn,
     400             :                               LDB_SCOPE_BASE,
     401         839 :                               authn_attrs.policy->attrs,
     402             :                               0, NULL);
     403         839 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     404             :                 /* Not found. */
     405           0 :                 ret = 0;
     406           0 :                 goto out;
     407             :         }
     408         839 :         if (ret) {
     409           0 :                 goto out;
     410             :         }
     411             : 
     412         839 :         policy_name = ldb_msg_find_attr_as_string(authn_policy_msg, "name", NULL);
     413             : 
     414         839 :         if (!belongs_to_silo) {
     415         803 :                 is_enforced = ldb_msg_find_attr_as_bool(
     416             :                         authn_policy_msg,
     417             :                         "msDS-AuthNPolicyEnforced",
     418             :                         false);
     419             :         }
     420             : 
     421         839 :         authn_policy_out->silo_name = talloc_move(mem_ctx, &silo_name);
     422         839 :         authn_policy_out->policy_name = talloc_move(mem_ctx, &policy_name);
     423         839 :         authn_policy_out->enforced = is_enforced;
     424             : 
     425         839 :         *authn_policy_msg_out = talloc_move(mem_ctx, &authn_policy_msg);
     426             : 
     427       68286 : out:
     428       68286 :         talloc_free(tmp_ctx);
     429       68286 :         return ret;
     430             : }
     431             : 
     432             : /*
     433             :  * Reference an existing authentication policy onto a talloc context, returning
     434             :  * ‘true’ on success.
     435             :  */
     436         771 : static bool authn_policy_ref(TALLOC_CTX *mem_ctx,
     437             :                              struct authn_policy *policy_out,
     438             :                              const struct authn_policy *policy)
     439             : {
     440         771 :         const char *silo_name = NULL;
     441         771 :         const char *policy_name = NULL;
     442             : 
     443         771 :         if (policy->silo_name != NULL) {
     444          12 :                 silo_name = talloc_strdup(mem_ctx, policy->silo_name);
     445          12 :                 if (silo_name == NULL) {
     446           0 :                         return false;
     447             :                 }
     448             :         }
     449             : 
     450         771 :         if (policy->policy_name != NULL) {
     451         771 :                 policy_name = talloc_strdup(mem_ctx, policy->policy_name);
     452         771 :                 if (policy_name == NULL) {
     453             :                         /*
     454             :                          * We can’t free ‘silo_name’ here, as it is declared
     455             :                          * const. It will be freed with the parent context.
     456             :                          */
     457           0 :                         return false;
     458             :                 }
     459             :         }
     460             : 
     461         771 :         *policy_out = (struct authn_policy) {
     462             :                 .silo_name = silo_name,
     463             :                 .policy_name = policy_name,
     464         771 :                 .enforced = policy->enforced,
     465             :         };
     466             : 
     467         771 :         return true;
     468             : }
     469             : 
     470             : /* Create a structure containing auditing information. */
     471         771 : static NTSTATUS _authn_policy_audit_info(TALLOC_CTX *mem_ctx,
     472             :                                          const struct authn_policy *policy,
     473             :                                          const struct authn_int64_optional tgt_lifetime_raw,
     474             :                                          const struct auth_user_info_dc *client_info,
     475             :                                          const enum authn_audit_event event,
     476             :                                          const enum authn_audit_reason reason,
     477             :                                          const NTSTATUS policy_status,
     478             :                                          const char *location,
     479             :                                          struct authn_audit_info **audit_info_out)
     480             : {
     481         771 :         struct authn_audit_info *audit_info = NULL;
     482           0 :         bool ok;
     483             : 
     484         771 :         if (audit_info_out == NULL) {
     485           0 :                 return NT_STATUS_OK;
     486             :         }
     487             : 
     488         771 :         audit_info = talloc_zero(mem_ctx, struct authn_audit_info);
     489         771 :         if (audit_info == NULL) {
     490           0 :                 return NT_STATUS_NO_MEMORY;
     491             :         }
     492             : 
     493         771 :         if (client_info != NULL) {
     494             :                 /*
     495             :                  * Keep a reference to the client’s user information so that it
     496             :                  * is available to be logged later.
     497             :                  */
     498         668 :                 audit_info->client_info = talloc_reference(audit_info, client_info);
     499         668 :                 if (audit_info->client_info == NULL) {
     500           0 :                         talloc_free(audit_info);
     501           0 :                         return NT_STATUS_NO_MEMORY;
     502             :                 }
     503             :         }
     504             : 
     505         771 :         if (policy != NULL) {
     506         771 :                 audit_info->policy = talloc_zero(audit_info, struct authn_policy);
     507         771 :                 if (audit_info->policy == NULL) {
     508           0 :                         talloc_free(audit_info);
     509           0 :                         return NT_STATUS_NO_MEMORY;
     510             :                 }
     511             : 
     512         771 :                 ok = authn_policy_ref(audit_info, audit_info->policy, policy);
     513         771 :                 if (!ok) {
     514           0 :                         talloc_free(audit_info);
     515           0 :                         return NT_STATUS_NO_MEMORY;
     516             :                 }
     517             :         }
     518             : 
     519         771 :         audit_info->event = event;
     520         771 :         audit_info->reason = reason;
     521         771 :         audit_info->policy_status = policy_status;
     522         771 :         audit_info->location = location;
     523         771 :         audit_info->tgt_lifetime_raw = tgt_lifetime_raw;
     524             : 
     525         771 :         *audit_info_out = audit_info;
     526         771 :         return NT_STATUS_OK;
     527             : }
     528             : 
     529             : /* Create a structure containing auditing information. */
     530             : #define authn_policy_audit_info( \
     531             :         mem_ctx, \
     532             :         policy, \
     533             :         tgt_lifetime_raw, \
     534             :         client_info, \
     535             :         event, \
     536             :         reason, \
     537             :         policy_status, \
     538             :         audit_info_out) \
     539             :         _authn_policy_audit_info( \
     540             :                 mem_ctx, \
     541             :                 policy, \
     542             :                 tgt_lifetime_raw, \
     543             :                 client_info, \
     544             :                 event, \
     545             :                 reason, \
     546             :                 policy_status, \
     547             :                 __location__, \
     548             :                 audit_info_out)
     549             : 
     550             : /*
     551             :  * Perform an access check against the security descriptor set in an
     552             :  * authentication policy. ‘client_info’ must be talloc-allocated so that we can
     553             :  * make a reference to it.
     554             :  */
     555         652 : static NTSTATUS _authn_policy_access_check(TALLOC_CTX *mem_ctx,
     556             :                                            struct ldb_context *samdb,
     557             :                                            struct loadparm_context* lp_ctx,
     558             :                                            const struct auth_user_info_dc *client_info,
     559             :                                            const struct auth_user_info_dc *device_info,
     560             :                                            const struct auth_claims auth_claims,
     561             :                                            const struct authn_policy *policy,
     562             :                                            const struct authn_int64_optional tgt_lifetime_raw,
     563             :                                            const enum authn_audit_event restriction_event,
     564             :                                            const struct authn_policy_flags authn_policy_flags,
     565             :                                            const DATA_BLOB *descriptor_blob,
     566             :                                            const char *location,
     567             :                                            struct authn_audit_info **audit_info_out)
     568             : {
     569         652 :         TALLOC_CTX *tmp_ctx = NULL;
     570         652 :         NTSTATUS status = NT_STATUS_OK;
     571           0 :         NTSTATUS status2;
     572           0 :         enum ndr_err_code ndr_err;
     573         652 :         struct security_descriptor *descriptor = NULL;
     574         652 :         struct security_token *security_token = NULL;
     575         652 :         uint32_t session_info_flags =
     576             :                 AUTH_SESSION_INFO_DEFAULT_GROUPS |
     577             :                 AUTH_SESSION_INFO_DEVICE_DEFAULT_GROUPS |
     578             :                 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
     579         652 :         const uint32_t access_desired = SEC_ADS_CONTROL_ACCESS;
     580           0 :         uint32_t access_granted;
     581         652 :         enum authn_audit_event event = restriction_event;
     582         652 :         enum authn_audit_reason reason = AUTHN_AUDIT_REASON_NONE;
     583             : 
     584         652 :         if (audit_info_out != NULL) {
     585         652 :                 *audit_info_out = NULL;
     586             :         }
     587             : 
     588         652 :         tmp_ctx = talloc_new(mem_ctx);
     589         652 :         if (tmp_ctx == NULL) {
     590           0 :                 status = NT_STATUS_NO_MEMORY;
     591           0 :                 goto out;
     592             :         }
     593             : 
     594         652 :         if (!(client_info->info->user_flags & NETLOGON_GUEST)) {
     595         652 :                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     596             :         }
     597             : 
     598         652 :         if (device_info != NULL && !(device_info->info->user_flags & NETLOGON_GUEST)) {
     599         145 :                 session_info_flags |= AUTH_SESSION_INFO_DEVICE_AUTHENTICATED;
     600             :         }
     601             : 
     602         652 :         if (authn_policy_flags.force_compounded_authentication) {
     603         162 :                 session_info_flags |= AUTH_SESSION_INFO_FORCE_COMPOUNDED_AUTHENTICATION;
     604             :         }
     605             : 
     606         652 :         descriptor = talloc(tmp_ctx, struct security_descriptor);
     607         652 :         if (descriptor == NULL) {
     608           0 :                 status = NT_STATUS_NO_MEMORY;
     609           0 :                 goto out;
     610             :         }
     611             : 
     612         652 :         ndr_err = ndr_pull_struct_blob(descriptor_blob,
     613             :                                        tmp_ctx,
     614             :                                        descriptor,
     615             :                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     616         652 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     617           0 :                 status = ndr_map_error2ntstatus(ndr_err);
     618           0 :                 DBG_ERR("Failed to unmarshall "
     619             :                         "security descriptor for authentication policy: %s\n",
     620             :                         nt_errstr(status));
     621           0 :                 reason = AUTHN_AUDIT_REASON_DESCRIPTOR_INVALID;
     622           0 :                 goto out;
     623             :         }
     624             : 
     625             :         /* Require that the security descriptor has an owner set. */
     626         652 :         if (descriptor->owner_sid == NULL) {
     627          12 :                 status = NT_STATUS_INVALID_PARAMETER;
     628          12 :                 reason = AUTHN_AUDIT_REASON_DESCRIPTOR_NO_OWNER;
     629          12 :                 goto out;
     630             :         }
     631             : 
     632         640 :         status = auth_generate_security_token(tmp_ctx,
     633             :                                               lp_ctx,
     634             :                                               samdb,
     635             :                                               client_info,
     636             :                                               device_info,
     637             :                                               auth_claims,
     638             :                                               session_info_flags,
     639             :                                               &security_token);
     640         640 :         if (!NT_STATUS_IS_OK(status)) {
     641          17 :                 reason = AUTHN_AUDIT_REASON_SECURITY_TOKEN_FAILURE;
     642          17 :                 goto out;
     643             :         }
     644             : 
     645         623 :         status = sec_access_check_ds(descriptor, security_token,
     646             :                                         access_desired, &access_granted,
     647             :                                         NULL, NULL);
     648         623 :         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     649         356 :                 status = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
     650         356 :                 reason = AUTHN_AUDIT_REASON_ACCESS_DENIED;
     651         356 :                 goto out;
     652             :         }
     653         267 :         if (!NT_STATUS_IS_OK(status)) {
     654           0 :                 goto out;
     655             :         }
     656             : 
     657         267 :         event = AUTHN_AUDIT_EVENT_OK;
     658         652 : out:
     659             :         /*
     660             :          * Create the structure with auditing information here while we have all
     661             :          * the relevant information to hand. It will contain references to
     662             :          * information regarding the client and the policy, to be consulted
     663             :          * after the referents have possibly been freed.
     664             :          */
     665         652 :         status2 = _authn_policy_audit_info(mem_ctx,
     666             :                                            policy,
     667             :                                            tgt_lifetime_raw,
     668             :                                            client_info,
     669             :                                            event,
     670             :                                            reason,
     671             :                                            status,
     672             :                                            location,
     673             :                                            audit_info_out);
     674         652 :         if (!NT_STATUS_IS_OK(status2)) {
     675           0 :                 status = status2;
     676         652 :         } else if (!authn_policy_is_enforced(policy)) {
     677           6 :                 status = NT_STATUS_OK;
     678             :         }
     679             : 
     680         652 :         talloc_free(tmp_ctx);
     681         652 :         return status;
     682             : }
     683             : 
     684             : #define authn_policy_access_check(mem_ctx, \
     685             :         samdb, \
     686             :         lp_ctx, \
     687             :         client_info, \
     688             :         device_info, \
     689             :         auth_claims, \
     690             :         policy, \
     691             :         tgt_lifetime_raw, \
     692             :         restriction_event, \
     693             :         authn_policy_flags, \
     694             :         descriptor_blob, \
     695             :         audit_info_out) \
     696             :         _authn_policy_access_check(mem_ctx, \
     697             :                 samdb, \
     698             :                 lp_ctx, \
     699             :                 client_info, \
     700             :                 device_info, \
     701             :                 auth_claims, \
     702             :                 policy, \
     703             :                 tgt_lifetime_raw, \
     704             :                 restriction_event, \
     705             :                 authn_policy_flags,     \
     706             :                 descriptor_blob, \
     707             :                 __location__, \
     708             :                 audit_info_out)
     709             : 
     710             : /* Return an authentication policy moved onto a talloc context. */
     711         839 : static struct authn_policy authn_policy_move(TALLOC_CTX *mem_ctx,
     712             :                                              struct authn_policy *policy)
     713             : {
     714        1678 :         return (struct authn_policy) {
     715         839 :                 .silo_name = talloc_move(mem_ctx, &policy->silo_name),
     716         839 :                 .policy_name = talloc_move(mem_ctx, &policy->policy_name),
     717         839 :                 .enforced = policy->enforced,
     718             :         };
     719             : }
     720             : 
     721             : /* Authentication policies for Kerberos clients. */
     722             : 
     723             : /*
     724             :  * Get the applicable authentication policy for an account acting as a Kerberos
     725             :  * client.
     726             :  */
     727       51158 : int authn_policy_kerberos_client(struct ldb_context *samdb,
     728             :                                  TALLOC_CTX *mem_ctx,
     729             :                                  const struct ldb_message *msg,
     730             :                                  const struct authn_kerberos_client_policy **policy_out)
     731             : {
     732       51158 :         TALLOC_CTX *tmp_ctx = NULL;
     733       51158 :         int ret = 0;
     734        1755 :         struct authn_attrs authn_attrs;
     735       51158 :         struct ldb_message *authn_policy_msg = NULL;
     736       51158 :         struct authn_kerberos_client_policy *client_policy = NULL;
     737        1755 :         struct authn_policy policy;
     738             : 
     739       51158 :         *policy_out = NULL;
     740             : 
     741       51158 :         if (!authn_policy_silos_and_policies_in_effect(samdb)) {
     742       23277 :                 return 0;
     743             :         }
     744             : 
     745             :         /*
     746             :          * Get the silo and policy attributes that apply to objects of this
     747             :          * account’s objectclass.
     748             :          */
     749       27881 :         authn_attrs = authn_policy_get_attrs(msg);
     750       27881 :         if (authn_attrs.silo == NULL || authn_attrs.policy == NULL) {
     751             :                 /*
     752             :                  * No applicable silo or policy attributes (somehow). Either
     753             :                  * this account isn’t derived from ‘user’, or the message is
     754             :                  * missing an objectClass element.
     755             :                  */
     756           0 :                 goto out;
     757             :         }
     758             : 
     759       27881 :         if (authn_attrs.policy->allowed_to_authenticate_from == NULL &&
     760        3173 :             authn_attrs.policy->tgt_lifetime == NULL)
     761             :         {
     762             :                 /* No relevant policy attributes apply. */
     763           0 :                 goto out;
     764             :         }
     765             : 
     766       27881 :         tmp_ctx = talloc_new(mem_ctx);
     767       27881 :         if (tmp_ctx == NULL) {
     768           0 :                 ret = ENOMEM;
     769           0 :                 goto out;
     770             :         }
     771             : 
     772       27881 :         ret = samba_kdc_authn_policy_msg(samdb,
     773             :                                          tmp_ctx,
     774             :                                          msg,
     775             :                                          authn_attrs,
     776             :                                          &authn_policy_msg,
     777             :                                          &policy);
     778       27881 :         if (ret) {
     779           0 :                 goto out;
     780             :         }
     781             : 
     782       27881 :         if (authn_policy_msg == NULL) {
     783             :                 /* No policy applies. */
     784       27430 :                 goto out;
     785             :         }
     786             : 
     787         451 :         client_policy = talloc_zero(tmp_ctx, struct authn_kerberos_client_policy);
     788         451 :         if (client_policy == NULL) {
     789           0 :                 ret = ENOMEM;
     790           0 :                 goto out;
     791             :         }
     792             : 
     793         451 :         client_policy->policy = authn_policy_move(client_policy, &policy);
     794             : 
     795         451 :         if (authn_attrs.policy->allowed_to_authenticate_from != NULL) {
     796         434 :                 const struct ldb_val *allowed_from = ldb_msg_find_ldb_val(
     797             :                         authn_policy_msg,
     798         434 :                         authn_attrs.policy->allowed_to_authenticate_from);
     799             : 
     800         434 :                 if (allowed_from != NULL && allowed_from->data != NULL) {
     801         397 :                         client_policy->allowed_to_authenticate_from = data_blob_const(
     802         397 :                                 talloc_steal(client_policy, allowed_from->data),
     803         397 :                                 allowed_from->length);
     804             :                 }
     805             :         }
     806             : 
     807         451 :         if (authn_attrs.policy->tgt_lifetime != NULL) {
     808         451 :                 client_policy->tgt_lifetime_raw = ldb_msg_find_attr_as_int64(
     809             :                         authn_policy_msg,
     810         451 :                         authn_attrs.policy->tgt_lifetime,
     811             :                         0);
     812             :         }
     813             : 
     814         451 :         *policy_out = talloc_move(mem_ctx, &client_policy);
     815             : 
     816       27881 : out:
     817       27881 :         talloc_free(tmp_ctx);
     818       27881 :         return ret;
     819             : }
     820             : 
     821             : /* Get device restrictions enforced by an authentication policy. */
     822       49923 : static const DATA_BLOB *authn_policy_kerberos_device_restrictions(const struct authn_kerberos_client_policy *policy)
     823             : {
     824       49923 :         const DATA_BLOB *restrictions = NULL;
     825             : 
     826       49923 :         if (policy == NULL) {
     827       47323 :                 return NULL;
     828             :         }
     829             : 
     830         845 :         restrictions = &policy->allowed_to_authenticate_from;
     831         845 :         if (restrictions->data == NULL) {
     832          54 :                 return NULL;
     833             :         }
     834             : 
     835         791 :         return restrictions;
     836             : }
     837             : 
     838             : /* Return whether an authentication policy enforces device restrictions. */
     839       49529 : bool authn_policy_device_restrictions_present(const struct authn_kerberos_client_policy *policy)
     840             : {
     841       49529 :         return authn_policy_kerberos_device_restrictions(policy) != NULL;
     842             : }
     843             : 
     844             : /*
     845             :  * Perform an access check for the device with which the client is
     846             :  * authenticating. ‘device_info’ must be talloc-allocated so that we can make a
     847             :  * reference to it.
     848             :  */
     849         394 : NTSTATUS authn_policy_authenticate_from_device(TALLOC_CTX *mem_ctx,
     850             :                                                struct ldb_context *samdb,
     851             :                                                struct loadparm_context* lp_ctx,
     852             :                                                const struct auth_user_info_dc *device_info,
     853             :                                                const struct auth_claims auth_claims,
     854             :                                                const struct authn_kerberos_client_policy *client_policy,
     855             :                                                struct authn_audit_info **client_audit_info_out)
     856             : {
     857         394 :         NTSTATUS status = NT_STATUS_OK;
     858         394 :         const DATA_BLOB *restrictions = NULL;
     859             : 
     860         394 :         restrictions = authn_policy_kerberos_device_restrictions(client_policy);
     861         394 :         if (restrictions == NULL) {
     862           0 :                 goto out;
     863             :         }
     864             : 
     865         394 :         status = authn_policy_access_check(mem_ctx,
     866             :                                            samdb,
     867             :                                            lp_ctx,
     868             :                                            device_info,
     869             :                                            /* The device itself has no device. */
     870             :                                            NULL /* device_info */,
     871             :                                            auth_claims,
     872             :                                            &client_policy->policy,
     873             :                                            authn_int64_some(client_policy->tgt_lifetime_raw),
     874             :                                            AUTHN_AUDIT_EVENT_KERBEROS_DEVICE_RESTRICTION,
     875             :                                            (struct authn_policy_flags) {},
     876             :                                            restrictions,
     877             :                                            client_audit_info_out);
     878         394 : out:
     879         394 :         return status;
     880             : }
     881             : 
     882             : /* Authentication policies for NTLM clients. */
     883             : 
     884             : /*
     885             :  * Get the applicable authentication policy for an account acting as an NTLM
     886             :  * client.
     887             :  */
     888       27130 : int authn_policy_ntlm_client(struct ldb_context *samdb,
     889             :                              TALLOC_CTX *mem_ctx,
     890             :                              const struct ldb_message *msg,
     891             :                              const struct authn_ntlm_client_policy **policy_out)
     892             : {
     893       27130 :         TALLOC_CTX *tmp_ctx = NULL;
     894       27130 :         int ret = 0;
     895        1404 :         struct authn_attrs authn_attrs;
     896       27130 :         struct ldb_message *authn_policy_msg = NULL;
     897       27130 :         struct authn_ntlm_client_policy *client_policy = NULL;
     898        1404 :         struct authn_policy policy;
     899             : 
     900       27130 :         *policy_out = NULL;
     901             : 
     902       27130 :         if (!authn_policy_silos_and_policies_in_effect(samdb)) {
     903        8767 :                 return 0;
     904             :         }
     905             : 
     906             :         /*
     907             :          * Get the silo and policy attributes that apply to objects of this
     908             :          * account’s objectclass.
     909             :          */
     910       18363 :         authn_attrs = authn_policy_get_attrs(msg);
     911       18363 :         if (authn_attrs.silo == NULL || authn_attrs.policy == NULL) {
     912             :                 /*
     913             :                  * No applicable silo or policy attributes (somehow). Either
     914             :                  * this account isn’t derived from ‘user’, or the message is
     915             :                  * missing an objectClass element.
     916             :                  */
     917           0 :                 goto out;
     918             :         }
     919             : 
     920       18363 :         if (authn_attrs.policy->allowed_to_authenticate_from == NULL &&
     921        2450 :             authn_attrs.policy->allowed_ntlm_network_auth == NULL)
     922             :         {
     923             :                 /* No relevant policy attributes apply. */
     924        2450 :                 goto out;
     925             :         }
     926             : 
     927       15913 :         tmp_ctx = talloc_new(mem_ctx);
     928       15913 :         if (tmp_ctx == NULL) {
     929           0 :                 ret = ENOMEM;
     930           0 :                 goto out;
     931             :         }
     932             : 
     933       15913 :         ret = samba_kdc_authn_policy_msg(samdb,
     934             :                                          tmp_ctx,
     935             :                                          msg,
     936             :                                          authn_attrs,
     937             :                                          &authn_policy_msg,
     938             :                                          &policy);
     939       15913 :         if (ret) {
     940           0 :                 goto out;
     941             :         }
     942             : 
     943       15913 :         if (authn_policy_msg == NULL) {
     944             :                 /* No policy applies. */
     945       15813 :                 goto out;
     946             :         }
     947             : 
     948         100 :         client_policy = talloc_zero(tmp_ctx, struct authn_ntlm_client_policy);
     949         100 :         if (client_policy == NULL) {
     950           0 :                 ret = ENOMEM;
     951           0 :                 goto out;
     952             :         }
     953             : 
     954         100 :         client_policy->policy = authn_policy_move(client_policy, &policy);
     955             : 
     956         100 :         if (authn_attrs.policy->allowed_to_authenticate_from != NULL) {
     957         100 :                 const struct ldb_val *allowed_from = ldb_msg_find_ldb_val(
     958             :                         authn_policy_msg,
     959         100 :                         authn_attrs.policy->allowed_to_authenticate_from);
     960             : 
     961         100 :                 if (allowed_from != NULL && allowed_from->data != NULL) {
     962          68 :                         client_policy->allowed_to_authenticate_from = data_blob_const(
     963          68 :                                 talloc_steal(client_policy, allowed_from->data),
     964          68 :                                 allowed_from->length);
     965             :                 }
     966             :         }
     967             : 
     968         200 :         if (authn_attrs.policy->allowed_ntlm_network_auth != NULL &&
     969         100 :             authn_policy_allowed_ntlm_network_auth_in_effect(samdb))
     970             :         {
     971         100 :                 client_policy->allowed_ntlm_network_auth = ldb_msg_find_attr_as_bool(
     972             :                         authn_policy_msg,
     973         100 :                         authn_attrs.policy->allowed_ntlm_network_auth,
     974             :                         false);
     975             :         }
     976             : 
     977         100 :         *policy_out = talloc_move(mem_ctx, &client_policy);
     978             : 
     979       18363 : out:
     980       18363 :         talloc_free(tmp_ctx);
     981       18363 :         return ret;
     982             : }
     983             : 
     984             : /* Return whether an authentication policy enforces device restrictions. */
     985         100 : static bool authn_policy_ntlm_device_restrictions_present(const struct authn_ntlm_client_policy *policy)
     986             : {
     987         100 :         if (policy == NULL) {
     988           0 :                 return false;
     989             :         }
     990             : 
     991         100 :         return policy->allowed_to_authenticate_from.data != NULL;
     992             : }
     993             : 
     994             : /* Check whether the client is allowed to authenticate using NTLM. */
     995       27130 : NTSTATUS authn_policy_ntlm_apply_device_restriction(TALLOC_CTX *mem_ctx,
     996             :                                                     const struct authn_ntlm_client_policy *client_policy,
     997             :                                                     struct authn_audit_info **client_audit_info_out)
     998             : {
     999        1404 :         NTSTATUS status;
    1000        1404 :         NTSTATUS status2;
    1001             : 
    1002       27130 :         if (client_audit_info_out != NULL) {
    1003       27130 :                 *client_audit_info_out = NULL;
    1004             :         }
    1005             : 
    1006       27130 :         if (client_policy == NULL) {
    1007       27030 :                 return NT_STATUS_OK;
    1008             :         }
    1009             : 
    1010             :         /*
    1011             :          * Access control restrictions cannot be applied to NTLM.
    1012             :          *
    1013             :          * If NTLM authentication is disallowed and the policy enforces a device
    1014             :          * restriction, deny the authentication.
    1015             :          */
    1016             : 
    1017         100 :         if (!authn_policy_ntlm_device_restrictions_present(client_policy)) {
    1018          32 :                 return authn_policy_audit_info(mem_ctx,
    1019             :                                                &client_policy->policy,
    1020             :                                                authn_int64_none() /* tgt_lifetime_raw */,
    1021             :                                                NULL /* client_info */,
    1022             :                                                AUTHN_AUDIT_EVENT_OK,
    1023             :                                                AUTHN_AUDIT_REASON_NONE,
    1024             :                                                NT_STATUS_OK,
    1025             :                                                client_audit_info_out);
    1026             :         }
    1027             : 
    1028             :         /*
    1029             :          * (Although MS-APDS doesn’t state it, AllowedNTLMNetworkAuthentication
    1030             :          * applies to interactive logons too.)
    1031             :          */
    1032          68 :         if (client_policy->allowed_ntlm_network_auth) {
    1033          30 :                 return authn_policy_audit_info(mem_ctx,
    1034             :                                                &client_policy->policy,
    1035             :                                                authn_int64_none() /* tgt_lifetime_raw */,
    1036             :                                                NULL /* client_info */,
    1037             :                                                AUTHN_AUDIT_EVENT_OK,
    1038             :                                                AUTHN_AUDIT_REASON_NONE,
    1039             :                                                NT_STATUS_OK,
    1040             :                                                client_audit_info_out);
    1041             :         }
    1042             : 
    1043          38 :         status = NT_STATUS_ACCOUNT_RESTRICTION;
    1044          38 :         status2 = authn_policy_audit_info(mem_ctx,
    1045             :                                           &client_policy->policy,
    1046             :                                           authn_int64_none() /* tgt_lifetime_raw */,
    1047             :                                           NULL /* client_info */,
    1048             :                                           AUTHN_AUDIT_EVENT_NTLM_DEVICE_RESTRICTION,
    1049             :                                           AUTHN_AUDIT_REASON_NONE,
    1050             :                                           status,
    1051             :                                           client_audit_info_out);
    1052          38 :         if (!NT_STATUS_IS_OK(status2)) {
    1053           0 :                 status = status2;
    1054          38 :         } else if (!authn_policy_is_enforced(&client_policy->policy)) {
    1055           0 :                 status = NT_STATUS_OK;
    1056             :         }
    1057             : 
    1058          38 :         return status;
    1059             : }
    1060             : 
    1061             : /* Authentication policies for servers. */
    1062             : 
    1063             : /*
    1064             :  * Get the applicable authentication policy for an account acting as a
    1065             :  * server.
    1066             :  */
    1067       39101 : int authn_policy_server(struct ldb_context *samdb,
    1068             :                         TALLOC_CTX *mem_ctx,
    1069             :                         const struct ldb_message *msg,
    1070             :                         const struct authn_server_policy **policy_out)
    1071             : {
    1072       39101 :         TALLOC_CTX *tmp_ctx = NULL;
    1073       39101 :         int ret = 0;
    1074        1897 :         struct authn_attrs authn_attrs;
    1075       39101 :         struct ldb_message *authn_policy_msg = NULL;
    1076       39101 :         struct authn_server_policy *server_policy = NULL;
    1077        1897 :         struct authn_policy policy;
    1078             : 
    1079       39101 :         *policy_out = NULL;
    1080             : 
    1081       39101 :         if (!authn_policy_silos_and_policies_in_effect(samdb)) {
    1082       14609 :                 return 0;
    1083             :         }
    1084             : 
    1085             :         /*
    1086             :          * Get the silo and policy attributes that apply to objects of this
    1087             :          * account’s objectclass.
    1088             :          */
    1089       24492 :         authn_attrs = authn_policy_get_attrs(msg);
    1090       24492 :         if (authn_attrs.silo == NULL || authn_attrs.policy == NULL) {
    1091             :                 /*
    1092             :                  * No applicable silo or policy attributes (somehow). Either
    1093             :                  * this account isn’t derived from ‘user’, or the message is
    1094             :                  * missing an objectClass element.
    1095             :                  */
    1096           0 :                 goto out;
    1097             :         }
    1098             : 
    1099       24492 :         if (authn_attrs.policy->allowed_to_authenticate_to == NULL) {
    1100             :                 /* The relevant policy attribute doesn’t apply. */
    1101           0 :                 goto out;
    1102             :         }
    1103             : 
    1104       24492 :         tmp_ctx = talloc_new(mem_ctx);
    1105       24492 :         if (tmp_ctx == NULL) {
    1106           0 :                 ret = ENOMEM;
    1107           0 :                 goto out;
    1108             :         }
    1109             : 
    1110       24492 :         ret = samba_kdc_authn_policy_msg(samdb,
    1111             :                                          tmp_ctx,
    1112             :                                          msg,
    1113             :                                          authn_attrs,
    1114             :                                          &authn_policy_msg,
    1115             :                                          &policy);
    1116       24492 :         if (ret) {
    1117           0 :                 goto out;
    1118             :         }
    1119             : 
    1120       24492 :         if (authn_policy_msg == NULL) {
    1121             :                 /* No policy applies. */
    1122       24204 :                 goto out;
    1123             :         }
    1124             : 
    1125         288 :         server_policy = talloc_zero(tmp_ctx, struct authn_server_policy);
    1126         288 :         if (server_policy == NULL) {
    1127           0 :                 ret = ENOMEM;
    1128           0 :                 goto out;
    1129             :         }
    1130             : 
    1131         288 :         server_policy->policy = authn_policy_move(server_policy, &policy);
    1132             : 
    1133         288 :         if (authn_attrs.policy->allowed_to_authenticate_to != NULL) {
    1134         288 :                 const struct ldb_val *allowed_to = ldb_msg_find_ldb_val(
    1135             :                         authn_policy_msg,
    1136         288 :                         authn_attrs.policy->allowed_to_authenticate_to);
    1137             : 
    1138         288 :                 if (allowed_to != NULL && allowed_to->data != NULL) {
    1139         280 :                         server_policy->allowed_to_authenticate_to = data_blob_const(
    1140         280 :                                 talloc_steal(server_policy, allowed_to->data),
    1141         280 :                                 allowed_to->length);
    1142             :                 }
    1143             :         }
    1144             : 
    1145         288 :         *policy_out = talloc_move(mem_ctx, &server_policy);
    1146             : 
    1147       24492 : out:
    1148       24492 :         talloc_free(tmp_ctx);
    1149       24492 :         return ret;
    1150             : }
    1151             : 
    1152             : /* Get restrictions enforced by an authentication policy. */
    1153       51213 : static const DATA_BLOB *authn_policy_restrictions(const struct authn_server_policy *policy)
    1154             : {
    1155       51213 :         const DATA_BLOB *restrictions = NULL;
    1156             : 
    1157       51213 :         if (policy == NULL) {
    1158       48984 :                 return NULL;
    1159             :         }
    1160             : 
    1161         436 :         restrictions = &policy->allowed_to_authenticate_to;
    1162         436 :         if (restrictions->data == NULL) {
    1163           8 :                 return NULL;
    1164             :         }
    1165             : 
    1166         428 :         return restrictions;
    1167             : }
    1168             : 
    1169             : /* Return whether an authentication policy enforces restrictions. */
    1170       50947 : bool authn_policy_restrictions_present(const struct authn_server_policy *policy)
    1171             : {
    1172       50947 :         return authn_policy_restrictions(policy) != NULL;
    1173             : }
    1174             : 
    1175             : /*
    1176             :  * Perform an access check for the client attempting to authenticate to the
    1177             :  * server. ‘user_info’ must be talloc-allocated so that we can make a reference
    1178             :  * to it.
    1179             :  */
    1180         266 : NTSTATUS authn_policy_authenticate_to_service(TALLOC_CTX *mem_ctx,
    1181             :                                               struct ldb_context *samdb,
    1182             :                                               struct loadparm_context* lp_ctx,
    1183             :                                               const enum authn_policy_auth_type auth_type,
    1184             :                                               const struct auth_user_info_dc *user_info,
    1185             :                                               const struct auth_user_info_dc *device_info,
    1186             :                                               const struct auth_claims auth_claims,
    1187             :                                               const struct authn_server_policy *server_policy,
    1188             :                                               const struct authn_policy_flags authn_policy_flags,
    1189             :                                               struct authn_audit_info **server_audit_info_out)
    1190             : {
    1191         266 :         NTSTATUS status = NT_STATUS_OK;
    1192         266 :         const DATA_BLOB *restrictions = NULL;
    1193           0 :         enum authn_audit_event event;
    1194             : 
    1195         266 :         restrictions = authn_policy_restrictions(server_policy);
    1196         266 :         if (restrictions == NULL) {
    1197           8 :                 return authn_server_policy_audit_info(mem_ctx,
    1198             :                                                       server_policy,
    1199             :                                                       user_info,
    1200             :                                                       AUTHN_AUDIT_EVENT_OK,
    1201             :                                                       AUTHN_AUDIT_REASON_NONE,
    1202             :                                                       NT_STATUS_OK,
    1203             :                                                       server_audit_info_out);
    1204             :         }
    1205             : 
    1206         258 :         switch (auth_type) {
    1207         162 :         case AUTHN_POLICY_AUTH_TYPE_KERBEROS:
    1208         162 :                 event = AUTHN_AUDIT_EVENT_KERBEROS_SERVER_RESTRICTION;
    1209         162 :                 break;
    1210          96 :         case AUTHN_POLICY_AUTH_TYPE_NTLM:
    1211          96 :                 event = AUTHN_AUDIT_EVENT_NTLM_SERVER_RESTRICTION;
    1212          96 :                 break;
    1213           0 :         default:
    1214           0 :                 return NT_STATUS_INVALID_PARAMETER_4;
    1215             :         }
    1216             : 
    1217         258 :         status = authn_policy_access_check(mem_ctx,
    1218             :                                            samdb,
    1219             :                                            lp_ctx,
    1220             :                                            user_info,
    1221             :                                            device_info,
    1222             :                                            auth_claims,
    1223             :                                            &server_policy->policy,
    1224             :                                            authn_int64_none() /* tgt_lifetime_raw */,
    1225             :                                            event,
    1226             :                                            authn_policy_flags,
    1227             :                                            restrictions,
    1228             :                                            server_audit_info_out);
    1229         258 :         return status;
    1230             : }
    1231             : 
    1232             : /* Create a structure containing auditing information. */
    1233           3 : NTSTATUS _authn_kerberos_client_policy_audit_info(
    1234             :         TALLOC_CTX *mem_ctx,
    1235             :         const struct authn_kerberos_client_policy *client_policy,
    1236             :         const struct auth_user_info_dc *client_info,
    1237             :         const enum authn_audit_event event,
    1238             :         const enum authn_audit_reason reason,
    1239             :         const NTSTATUS policy_status,
    1240             :         const char *location,
    1241             :         struct authn_audit_info **audit_info_out)
    1242             : {
    1243           3 :         const struct authn_policy *policy = NULL;
    1244           3 :         struct authn_int64_optional tgt_lifetime_raw = authn_int64_none();
    1245             : 
    1246           3 :         if (client_policy != NULL) {
    1247           3 :                 policy = &client_policy->policy;
    1248           3 :                 tgt_lifetime_raw = authn_int64_some(client_policy->tgt_lifetime_raw);
    1249             :         }
    1250             : 
    1251           3 :         return _authn_policy_audit_info(mem_ctx,
    1252             :                                         policy,
    1253             :                                         tgt_lifetime_raw,
    1254             :                                         client_info,
    1255             :                                         event,
    1256             :                                         reason,
    1257             :                                         policy_status,
    1258             :                                         location,
    1259             :                                         audit_info_out);
    1260             : }
    1261             : 
    1262             : /* Create a structure containing auditing information. */
    1263           0 : NTSTATUS _authn_ntlm_client_policy_audit_info(
    1264             :         TALLOC_CTX *mem_ctx,
    1265             :         const struct authn_ntlm_client_policy *client_policy,
    1266             :         const struct auth_user_info_dc *client_info,
    1267             :         const enum authn_audit_event event,
    1268             :         const enum authn_audit_reason reason,
    1269             :         const NTSTATUS policy_status,
    1270             :         const char *location,
    1271             :         struct authn_audit_info **audit_info_out)
    1272             : {
    1273           0 :         const struct authn_policy *policy = NULL;
    1274             : 
    1275           0 :         if (client_policy != NULL) {
    1276           0 :                 policy = &client_policy->policy;
    1277             :         }
    1278             : 
    1279           0 :         return _authn_policy_audit_info(mem_ctx,
    1280             :                                         policy,
    1281             :                                         authn_int64_none() /* tgt_lifetime_raw */,
    1282             :                                         client_info,
    1283             :                                         event,
    1284             :                                         reason,
    1285             :                                         policy_status,
    1286             :                                         location,
    1287             :                                         audit_info_out);
    1288             : }
    1289             : 
    1290             : /* Create a structure containing auditing information. */
    1291          16 : NTSTATUS _authn_server_policy_audit_info(
    1292             :         TALLOC_CTX *mem_ctx,
    1293             :         const struct authn_server_policy *server_policy,
    1294             :         const struct auth_user_info_dc *client_info,
    1295             :         const enum authn_audit_event event,
    1296             :         const enum authn_audit_reason reason,
    1297             :         const NTSTATUS policy_status,
    1298             :         const char *location,
    1299             :         struct authn_audit_info **audit_info_out)
    1300             : {
    1301          16 :         const struct authn_policy *policy = NULL;
    1302             : 
    1303          16 :         if (server_policy != NULL) {
    1304          16 :                 policy = &server_policy->policy;
    1305             :         }
    1306             : 
    1307          16 :         return _authn_policy_audit_info(mem_ctx,
    1308             :                                         policy,
    1309             :                                         authn_int64_none() /* tgt_lifetime_raw */,
    1310             :                                         client_info,
    1311             :                                         event,
    1312             :                                         reason,
    1313             :                                         policy_status,
    1314             :                                         location,
    1315             :                                         audit_info_out);
    1316             : }

Generated by: LCOV version 1.14