drsuapi.idl: fix source_dsa spelling
[samba4-gss.git] / source4 / kdc / authn_policy_util.c
blob60de61a27c24c6a3c573760f4799a8b0f73a16bf
1 /*
2 Unix SMB/CIFS implementation.
3 Samba Active Directory authentication policy utility functions
5 Copyright (C) Catalyst.Net Ltd 2023
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.
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.
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/>.
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"
33 bool authn_policy_silos_and_policies_in_effect(struct ldb_context *samdb)
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.
41 const int functional_level = dsdb_dc_functional_level(samdb);
42 return functional_level >= DS_DOMAIN_FUNCTION_2012_R2;
45 bool authn_policy_allowed_ntlm_network_auth_in_effect(struct ldb_context *samdb)
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.
53 const int functional_level = dsdb_dc_functional_level(samdb);
54 return functional_level >= DS_DOMAIN_FUNCTION_2016;
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.
62 struct authn_silo_attrs {
63 const char *policy;
64 const char *attrs[];
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.
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[];
82 struct authn_attrs {
83 const struct authn_silo_attrs *silo;
84 const struct authn_policy_attrs *policy;
88 * Get the authentication attributes that apply to an account of a certain
89 * class.
91 static const struct authn_attrs authn_policy_get_attrs(const struct ldb_message *msg)
93 const struct authn_attrs null_authn_attrs = {
94 .silo = NULL,
95 .policy = NULL,
97 const struct ldb_message_element *objectclass_el = NULL;
98 unsigned i;
100 objectclass_el = ldb_msg_find_element(msg, "objectClass");
101 if (objectclass_el == NULL || objectclass_el->num_values == 0) {
102 return null_authn_attrs;
106 * Iterate over the objectClasses, starting at the most-derived class.
108 for (i = objectclass_el->num_values; i > 0; --i) {
109 const struct ldb_val *objectclass_val = &objectclass_el->values[i - 1];
110 const char *objectclass = NULL;
112 objectclass = (const char *)objectclass_val->data;
113 if (objectclass == NULL) {
114 continue;
117 #define COMMON_AUTHN_SILO_ATTRS \
118 "msDS-AuthNPolicySiloEnforced", \
119 "msDS-AuthNPolicySiloMembers", \
120 "name"
122 #define COMMON_AUTHN_POLICY_ATTRS \
123 "msDS-AuthNPolicyEnforced", \
124 "msDS-StrongNTLMPolicy", \
125 "name"
128 * See which of three classes this object is most closely
129 * derived from.
131 if (strcasecmp(objectclass, "user") == 0) {
132 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,
141 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,
156 return (struct authn_attrs) {
157 .silo = &user_authn_silo_attrs,
158 .policy = &user_authn_policy_attrs,
162 if (strcasecmp(objectclass, "computer") == 0) {
163 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,
172 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,
185 return (struct authn_attrs) {
186 .silo = &computer_authn_silo_attrs,
187 .policy = &computer_authn_policy_attrs,
191 if (strcasecmp(objectclass, "msDS-ManagedServiceAccount") == 0) {
192 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,
201 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,
216 return (struct authn_attrs) {
217 .silo = &service_authn_silo_attrs,
218 .policy = &service_authn_policy_attrs,
223 #undef COMMON_AUTHN_SILO_ATTRS
224 #undef COMMON_AUTHN_POLICY_ATTRS
226 /* No match — this object is not a user. */
227 return null_authn_attrs;
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.
236 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)
243 TALLOC_CTX *tmp_ctx = NULL;
244 int ret = 0;
245 const struct ldb_message_element *authn_silo = NULL;
246 struct ldb_dn *authn_silo_dn = NULL;
247 struct ldb_message *authn_silo_msg = NULL;
248 const struct ldb_message_element *members = NULL;
249 const char *linearized_dn = NULL;
250 struct ldb_val linearized_dn_val;
252 *silo_msg_out = NULL;
253 *is_enforced = true;
255 if (!authn_policy_silos_and_policies_in_effect(samdb)) {
256 return 0;
259 tmp_ctx = talloc_new(mem_ctx);
260 if (tmp_ctx == NULL) {
261 ret = ENOMEM;
262 goto out;
265 authn_silo = ldb_msg_find_element(msg, "msDS-AssignedAuthNPolicySilo");
266 /* Is the account assigned to a silo? */
267 if (authn_silo == NULL || !authn_silo->num_values) {
268 goto out;
271 authn_silo_dn = ldb_dn_from_ldb_val(tmp_ctx, samdb, &authn_silo->values[0]);
272 if (authn_silo_dn == NULL) {
273 ret = ENOMEM;
274 goto out;
277 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 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
285 /* Not found. */
286 ret = 0;
287 goto out;
289 if (ret) {
290 goto out;
293 members = ldb_msg_find_element(authn_silo_msg,
294 "msDS-AuthNPolicySiloMembers");
295 if (members == NULL) {
296 goto out;
299 linearized_dn = ldb_dn_get_linearized(msg->dn);
300 if (linearized_dn == NULL) {
301 ret = ENOMEM;
302 goto out;
305 linearized_dn_val = data_blob_string_const(linearized_dn);
306 /* Is the account a member of the silo? */
307 if (!ldb_msg_find_val(members, &linearized_dn_val)) {
308 goto out;
311 /* Is the silo actually enforced? */
312 *is_enforced = ldb_msg_find_attr_as_bool(
313 authn_silo_msg,
314 "msDS-AuthNPolicySiloEnforced",
315 false);
317 *silo_msg_out = talloc_move(mem_ctx, &authn_silo_msg);
319 out:
320 talloc_free(tmp_ctx);
321 return ret;
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.
329 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)
336 TALLOC_CTX *tmp_ctx = NULL;
337 int ret = 0;
338 const struct ldb_message *authn_silo_msg = NULL;
339 const struct ldb_message_element *authn_policy = NULL;
340 const char *silo_name = NULL;
341 const char *policy_name = NULL;
342 struct ldb_dn *authn_policy_dn = NULL;
343 struct ldb_message *authn_policy_msg = NULL;
344 bool belongs_to_silo = false;
345 bool is_enforced = true;
347 *authn_policy_msg_out = NULL;
348 *authn_policy_out = (struct authn_policy) {};
350 tmp_ctx = talloc_new(mem_ctx);
351 if (tmp_ctx == NULL) {
352 ret = ENOMEM;
353 goto out;
356 /* See whether the account is assigned to a silo. */
357 ret = authn_policy_get_assigned_silo(samdb,
358 tmp_ctx,
359 msg,
360 authn_attrs.silo->attrs,
361 &authn_silo_msg,
362 &is_enforced);
363 if (ret) {
364 goto out;
367 if (authn_silo_msg != NULL) {
368 belongs_to_silo = true;
370 silo_name = ldb_msg_find_attr_as_string(authn_silo_msg, "name", NULL);
372 /* Get the applicable authentication policy. */
373 authn_policy = ldb_msg_find_element(
374 authn_silo_msg,
375 authn_attrs.silo->policy);
376 } else {
378 * If no silo is assigned, take the policy that is directly
379 * assigned to the account.
381 authn_policy = ldb_msg_find_element(msg, "msDS-AssignedAuthNPolicy");
384 if (authn_policy == NULL || !authn_policy->num_values) {
385 /* No policy applies; we’re done. */
386 goto out;
389 authn_policy_dn = ldb_dn_from_ldb_val(tmp_ctx, samdb, &authn_policy->values[0]);
390 if (authn_policy_dn == NULL) {
391 ret = ENOMEM;
392 goto out;
395 /* Look up the policy object. */
396 ret = dsdb_search_one(samdb,
397 tmp_ctx,
398 &authn_policy_msg,
399 authn_policy_dn,
400 LDB_SCOPE_BASE,
401 authn_attrs.policy->attrs,
402 0, NULL);
403 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
404 /* Not found. */
405 ret = 0;
406 goto out;
408 if (ret) {
409 goto out;
412 policy_name = ldb_msg_find_attr_as_string(authn_policy_msg, "name", NULL);
414 if (!belongs_to_silo) {
415 is_enforced = ldb_msg_find_attr_as_bool(
416 authn_policy_msg,
417 "msDS-AuthNPolicyEnforced",
418 false);
421 authn_policy_out->silo_name = talloc_move(mem_ctx, &silo_name);
422 authn_policy_out->policy_name = talloc_move(mem_ctx, &policy_name);
423 authn_policy_out->enforced = is_enforced;
425 *authn_policy_msg_out = talloc_move(mem_ctx, &authn_policy_msg);
427 out:
428 talloc_free(tmp_ctx);
429 return ret;
433 * Reference an existing authentication policy onto a talloc context, returning
434 * ‘true’ on success.
436 static bool authn_policy_ref(TALLOC_CTX *mem_ctx,
437 struct authn_policy *policy_out,
438 const struct authn_policy *policy)
440 const char *silo_name = NULL;
441 const char *policy_name = NULL;
443 if (policy->silo_name != NULL) {
444 silo_name = talloc_strdup(mem_ctx, policy->silo_name);
445 if (silo_name == NULL) {
446 return false;
450 if (policy->policy_name != NULL) {
451 policy_name = talloc_strdup(mem_ctx, policy->policy_name);
452 if (policy_name == NULL) {
454 * We can’t free ‘silo_name’ here, as it is declared
455 * const. It will be freed with the parent context.
457 return false;
461 *policy_out = (struct authn_policy) {
462 .silo_name = silo_name,
463 .policy_name = policy_name,
464 .enforced = policy->enforced,
467 return true;
470 /* Create a structure containing auditing information. */
471 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)
481 struct authn_audit_info *audit_info = NULL;
482 bool ok;
484 if (audit_info_out == NULL) {
485 return NT_STATUS_OK;
488 audit_info = talloc_zero(mem_ctx, struct authn_audit_info);
489 if (audit_info == NULL) {
490 return NT_STATUS_NO_MEMORY;
493 if (client_info != NULL) {
495 * Keep a reference to the client’s user information so that it
496 * is available to be logged later.
498 audit_info->client_info = talloc_reference(audit_info, client_info);
499 if (audit_info->client_info == NULL) {
500 talloc_free(audit_info);
501 return NT_STATUS_NO_MEMORY;
505 if (policy != NULL) {
506 audit_info->policy = talloc_zero(audit_info, struct authn_policy);
507 if (audit_info->policy == NULL) {
508 talloc_free(audit_info);
509 return NT_STATUS_NO_MEMORY;
512 ok = authn_policy_ref(audit_info, audit_info->policy, policy);
513 if (!ok) {
514 talloc_free(audit_info);
515 return NT_STATUS_NO_MEMORY;
519 audit_info->event = event;
520 audit_info->reason = reason;
521 audit_info->policy_status = policy_status;
522 audit_info->location = location;
523 audit_info->tgt_lifetime_raw = tgt_lifetime_raw;
525 *audit_info_out = audit_info;
526 return NT_STATUS_OK;
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)
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.
555 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)
569 TALLOC_CTX *tmp_ctx = NULL;
570 NTSTATUS status = NT_STATUS_OK;
571 NTSTATUS status2;
572 enum ndr_err_code ndr_err;
573 struct security_descriptor *descriptor = NULL;
574 struct security_token *security_token = NULL;
575 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 const uint32_t access_desired = SEC_ADS_CONTROL_ACCESS;
580 uint32_t access_granted;
581 enum authn_audit_event event = restriction_event;
582 enum authn_audit_reason reason = AUTHN_AUDIT_REASON_NONE;
584 if (audit_info_out != NULL) {
585 *audit_info_out = NULL;
588 tmp_ctx = talloc_new(mem_ctx);
589 if (tmp_ctx == NULL) {
590 status = NT_STATUS_NO_MEMORY;
591 goto out;
594 if (!(client_info->info->user_flags & NETLOGON_GUEST)) {
595 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
598 if (device_info != NULL && !(device_info->info->user_flags & NETLOGON_GUEST)) {
599 session_info_flags |= AUTH_SESSION_INFO_DEVICE_AUTHENTICATED;
602 if (authn_policy_flags.force_compounded_authentication) {
603 session_info_flags |= AUTH_SESSION_INFO_FORCE_COMPOUNDED_AUTHENTICATION;
606 descriptor = talloc(tmp_ctx, struct security_descriptor);
607 if (descriptor == NULL) {
608 status = NT_STATUS_NO_MEMORY;
609 goto out;
612 ndr_err = ndr_pull_struct_blob(descriptor_blob,
613 tmp_ctx,
614 descriptor,
615 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
616 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
617 status = ndr_map_error2ntstatus(ndr_err);
618 DBG_ERR("Failed to unmarshall "
619 "security descriptor for authentication policy: %s\n",
620 nt_errstr(status));
621 reason = AUTHN_AUDIT_REASON_DESCRIPTOR_INVALID;
622 goto out;
625 /* Require that the security descriptor has an owner set. */
626 if (descriptor->owner_sid == NULL) {
627 status = NT_STATUS_INVALID_PARAMETER;
628 reason = AUTHN_AUDIT_REASON_DESCRIPTOR_NO_OWNER;
629 goto out;
632 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 if (!NT_STATUS_IS_OK(status)) {
641 reason = AUTHN_AUDIT_REASON_SECURITY_TOKEN_FAILURE;
642 goto out;
645 status = sec_access_check_ds(descriptor, security_token,
646 access_desired, &access_granted,
647 NULL, NULL);
648 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
649 status = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
650 reason = AUTHN_AUDIT_REASON_ACCESS_DENIED;
651 goto out;
653 if (!NT_STATUS_IS_OK(status)) {
654 goto out;
657 event = AUTHN_AUDIT_EVENT_OK;
658 out:
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.
665 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 if (!NT_STATUS_IS_OK(status2)) {
675 status = status2;
676 } else if (!authn_policy_is_enforced(policy)) {
677 status = NT_STATUS_OK;
680 talloc_free(tmp_ctx);
681 return status;
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)
710 /* Return an authentication policy moved onto a talloc context. */
711 static struct authn_policy authn_policy_move(TALLOC_CTX *mem_ctx,
712 struct authn_policy *policy)
714 return (struct authn_policy) {
715 .silo_name = talloc_move(mem_ctx, &policy->silo_name),
716 .policy_name = talloc_move(mem_ctx, &policy->policy_name),
717 .enforced = policy->enforced,
721 /* Authentication policies for Kerberos clients. */
724 * Get the applicable authentication policy for an account acting as a Kerberos
725 * client.
727 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)
732 TALLOC_CTX *tmp_ctx = NULL;
733 int ret = 0;
734 struct authn_attrs authn_attrs;
735 struct ldb_message *authn_policy_msg = NULL;
736 struct authn_kerberos_client_policy *client_policy = NULL;
737 struct authn_policy policy;
739 *policy_out = NULL;
741 if (!authn_policy_silos_and_policies_in_effect(samdb)) {
742 return 0;
746 * Get the silo and policy attributes that apply to objects of this
747 * account’s objectclass.
749 authn_attrs = authn_policy_get_attrs(msg);
750 if (authn_attrs.silo == NULL || authn_attrs.policy == NULL) {
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.
756 goto out;
759 if (authn_attrs.policy->allowed_to_authenticate_from == NULL &&
760 authn_attrs.policy->tgt_lifetime == NULL)
762 /* No relevant policy attributes apply. */
763 goto out;
766 tmp_ctx = talloc_new(mem_ctx);
767 if (tmp_ctx == NULL) {
768 ret = ENOMEM;
769 goto out;
772 ret = samba_kdc_authn_policy_msg(samdb,
773 tmp_ctx,
774 msg,
775 authn_attrs,
776 &authn_policy_msg,
777 &policy);
778 if (ret) {
779 goto out;
782 if (authn_policy_msg == NULL) {
783 /* No policy applies. */
784 goto out;
787 client_policy = talloc_zero(tmp_ctx, struct authn_kerberos_client_policy);
788 if (client_policy == NULL) {
789 ret = ENOMEM;
790 goto out;
793 client_policy->policy = authn_policy_move(client_policy, &policy);
795 if (authn_attrs.policy->allowed_to_authenticate_from != NULL) {
796 const struct ldb_val *allowed_from = ldb_msg_find_ldb_val(
797 authn_policy_msg,
798 authn_attrs.policy->allowed_to_authenticate_from);
800 if (allowed_from != NULL && allowed_from->data != NULL) {
801 client_policy->allowed_to_authenticate_from = data_blob_const(
802 talloc_steal(client_policy, allowed_from->data),
803 allowed_from->length);
807 if (authn_attrs.policy->tgt_lifetime != NULL) {
808 client_policy->tgt_lifetime_raw = ldb_msg_find_attr_as_int64(
809 authn_policy_msg,
810 authn_attrs.policy->tgt_lifetime,
814 *policy_out = talloc_move(mem_ctx, &client_policy);
816 out:
817 talloc_free(tmp_ctx);
818 return ret;
821 /* Get device restrictions enforced by an authentication policy. */
822 static const DATA_BLOB *authn_policy_kerberos_device_restrictions(const struct authn_kerberos_client_policy *policy)
824 const DATA_BLOB *restrictions = NULL;
826 if (policy == NULL) {
827 return NULL;
830 restrictions = &policy->allowed_to_authenticate_from;
831 if (restrictions->data == NULL) {
832 return NULL;
835 return restrictions;
838 /* Return whether an authentication policy enforces device restrictions. */
839 bool authn_policy_device_restrictions_present(const struct authn_kerberos_client_policy *policy)
841 return authn_policy_kerberos_device_restrictions(policy) != NULL;
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.
849 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)
857 NTSTATUS status = NT_STATUS_OK;
858 const DATA_BLOB *restrictions = NULL;
860 restrictions = authn_policy_kerberos_device_restrictions(client_policy);
861 if (restrictions == NULL) {
862 goto out;
865 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 out:
879 return status;
882 /* Authentication policies for NTLM clients. */
885 * Get the applicable authentication policy for an account acting as an NTLM
886 * client.
888 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)
893 TALLOC_CTX *tmp_ctx = NULL;
894 int ret = 0;
895 struct authn_attrs authn_attrs;
896 struct ldb_message *authn_policy_msg = NULL;
897 struct authn_ntlm_client_policy *client_policy = NULL;
898 struct authn_policy policy;
900 *policy_out = NULL;
902 if (!authn_policy_silos_and_policies_in_effect(samdb)) {
903 return 0;
907 * Get the silo and policy attributes that apply to objects of this
908 * account’s objectclass.
910 authn_attrs = authn_policy_get_attrs(msg);
911 if (authn_attrs.silo == NULL || authn_attrs.policy == NULL) {
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.
917 goto out;
920 if (authn_attrs.policy->allowed_to_authenticate_from == NULL &&
921 authn_attrs.policy->allowed_ntlm_network_auth == NULL)
923 /* No relevant policy attributes apply. */
924 goto out;
927 tmp_ctx = talloc_new(mem_ctx);
928 if (tmp_ctx == NULL) {
929 ret = ENOMEM;
930 goto out;
933 ret = samba_kdc_authn_policy_msg(samdb,
934 tmp_ctx,
935 msg,
936 authn_attrs,
937 &authn_policy_msg,
938 &policy);
939 if (ret) {
940 goto out;
943 if (authn_policy_msg == NULL) {
944 /* No policy applies. */
945 goto out;
948 client_policy = talloc_zero(tmp_ctx, struct authn_ntlm_client_policy);
949 if (client_policy == NULL) {
950 ret = ENOMEM;
951 goto out;
954 client_policy->policy = authn_policy_move(client_policy, &policy);
956 if (authn_attrs.policy->allowed_to_authenticate_from != NULL) {
957 const struct ldb_val *allowed_from = ldb_msg_find_ldb_val(
958 authn_policy_msg,
959 authn_attrs.policy->allowed_to_authenticate_from);
961 if (allowed_from != NULL && allowed_from->data != NULL) {
962 client_policy->allowed_to_authenticate_from = data_blob_const(
963 talloc_steal(client_policy, allowed_from->data),
964 allowed_from->length);
968 if (authn_attrs.policy->allowed_ntlm_network_auth != NULL &&
969 authn_policy_allowed_ntlm_network_auth_in_effect(samdb))
971 client_policy->allowed_ntlm_network_auth = ldb_msg_find_attr_as_bool(
972 authn_policy_msg,
973 authn_attrs.policy->allowed_ntlm_network_auth,
974 false);
977 *policy_out = talloc_move(mem_ctx, &client_policy);
979 out:
980 talloc_free(tmp_ctx);
981 return ret;
984 /* Return whether an authentication policy enforces device restrictions. */
985 static bool authn_policy_ntlm_device_restrictions_present(const struct authn_ntlm_client_policy *policy)
987 if (policy == NULL) {
988 return false;
991 return policy->allowed_to_authenticate_from.data != NULL;
994 /* Check whether the client is allowed to authenticate using NTLM. */
995 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)
999 NTSTATUS status;
1000 NTSTATUS status2;
1002 if (client_audit_info_out != NULL) {
1003 *client_audit_info_out = NULL;
1006 if (client_policy == NULL) {
1007 return NT_STATUS_OK;
1011 * Access control restrictions cannot be applied to NTLM.
1013 * If NTLM authentication is disallowed and the policy enforces a device
1014 * restriction, deny the authentication.
1017 if (!authn_policy_ntlm_device_restrictions_present(client_policy)) {
1018 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);
1029 * (Although MS-APDS doesn’t state it, AllowedNTLMNetworkAuthentication
1030 * applies to interactive logons too.)
1032 if (client_policy->allowed_ntlm_network_auth) {
1033 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);
1043 status = NT_STATUS_ACCOUNT_RESTRICTION;
1044 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 if (!NT_STATUS_IS_OK(status2)) {
1053 status = status2;
1054 } else if (!authn_policy_is_enforced(&client_policy->policy)) {
1055 status = NT_STATUS_OK;
1058 return status;
1061 /* Authentication policies for servers. */
1064 * Get the applicable authentication policy for an account acting as a
1065 * server.
1067 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)
1072 TALLOC_CTX *tmp_ctx = NULL;
1073 int ret = 0;
1074 struct authn_attrs authn_attrs;
1075 struct ldb_message *authn_policy_msg = NULL;
1076 struct authn_server_policy *server_policy = NULL;
1077 struct authn_policy policy;
1079 *policy_out = NULL;
1081 if (!authn_policy_silos_and_policies_in_effect(samdb)) {
1082 return 0;
1086 * Get the silo and policy attributes that apply to objects of this
1087 * account’s objectclass.
1089 authn_attrs = authn_policy_get_attrs(msg);
1090 if (authn_attrs.silo == NULL || authn_attrs.policy == NULL) {
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.
1096 goto out;
1099 if (authn_attrs.policy->allowed_to_authenticate_to == NULL) {
1100 /* The relevant policy attribute doesn’t apply. */
1101 goto out;
1104 tmp_ctx = talloc_new(mem_ctx);
1105 if (tmp_ctx == NULL) {
1106 ret = ENOMEM;
1107 goto out;
1110 ret = samba_kdc_authn_policy_msg(samdb,
1111 tmp_ctx,
1112 msg,
1113 authn_attrs,
1114 &authn_policy_msg,
1115 &policy);
1116 if (ret) {
1117 goto out;
1120 if (authn_policy_msg == NULL) {
1121 /* No policy applies. */
1122 goto out;
1125 server_policy = talloc_zero(tmp_ctx, struct authn_server_policy);
1126 if (server_policy == NULL) {
1127 ret = ENOMEM;
1128 goto out;
1131 server_policy->policy = authn_policy_move(server_policy, &policy);
1133 if (authn_attrs.policy->allowed_to_authenticate_to != NULL) {
1134 const struct ldb_val *allowed_to = ldb_msg_find_ldb_val(
1135 authn_policy_msg,
1136 authn_attrs.policy->allowed_to_authenticate_to);
1138 if (allowed_to != NULL && allowed_to->data != NULL) {
1139 server_policy->allowed_to_authenticate_to = data_blob_const(
1140 talloc_steal(server_policy, allowed_to->data),
1141 allowed_to->length);
1145 *policy_out = talloc_move(mem_ctx, &server_policy);
1147 out:
1148 talloc_free(tmp_ctx);
1149 return ret;
1152 /* Get restrictions enforced by an authentication policy. */
1153 static const DATA_BLOB *authn_policy_restrictions(const struct authn_server_policy *policy)
1155 const DATA_BLOB *restrictions = NULL;
1157 if (policy == NULL) {
1158 return NULL;
1161 restrictions = &policy->allowed_to_authenticate_to;
1162 if (restrictions->data == NULL) {
1163 return NULL;
1166 return restrictions;
1169 /* Return whether an authentication policy enforces restrictions. */
1170 bool authn_policy_restrictions_present(const struct authn_server_policy *policy)
1172 return authn_policy_restrictions(policy) != NULL;
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.
1180 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)
1191 NTSTATUS status = NT_STATUS_OK;
1192 const DATA_BLOB *restrictions = NULL;
1193 enum authn_audit_event event;
1195 restrictions = authn_policy_restrictions(server_policy);
1196 if (restrictions == NULL) {
1197 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);
1206 switch (auth_type) {
1207 case AUTHN_POLICY_AUTH_TYPE_KERBEROS:
1208 event = AUTHN_AUDIT_EVENT_KERBEROS_SERVER_RESTRICTION;
1209 break;
1210 case AUTHN_POLICY_AUTH_TYPE_NTLM:
1211 event = AUTHN_AUDIT_EVENT_NTLM_SERVER_RESTRICTION;
1212 break;
1213 default:
1214 return NT_STATUS_INVALID_PARAMETER_4;
1217 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 return status;
1232 /* Create a structure containing auditing information. */
1233 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)
1243 const struct authn_policy *policy = NULL;
1244 struct authn_int64_optional tgt_lifetime_raw = authn_int64_none();
1246 if (client_policy != NULL) {
1247 policy = &client_policy->policy;
1248 tgt_lifetime_raw = authn_int64_some(client_policy->tgt_lifetime_raw);
1251 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);
1262 /* Create a structure containing auditing information. */
1263 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)
1273 const struct authn_policy *policy = NULL;
1275 if (client_policy != NULL) {
1276 policy = &client_policy->policy;
1279 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);
1290 /* Create a structure containing auditing information. */
1291 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)
1301 const struct authn_policy *policy = NULL;
1303 if (server_policy != NULL) {
1304 policy = &server_policy->policy;
1307 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);