4 Copyright (c) 2010, Simo Sorce <idra@samba.org>
5 Copyright (c) 2014-2015 Guenther Deschner <gd@samba.org>
6 Copyright (c) 2014-2016 Andreas Schneider <asn@samba.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #define TEVENT_DEPRECATED 1
25 #include "param/param.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "system/kerberos.h"
28 #include "lib/replace/system/filesys.h"
31 #include <kadm5/kadm_err.h>
33 #include "kdc/sdb_kdb.h"
34 #include "auth/kerberos/kerberos.h"
35 #include "auth/kerberos/pac_utils.h"
36 #include "kdc/samba_kdc.h"
37 #include "kdc/pac-glue.h"
38 #include "kdc/db-glue.h"
39 #include "auth/auth.h"
40 #include "kdc/kpasswd_glue.h"
41 #include "auth/auth_sam.h"
43 #include "mit_samba.h"
46 #define DBGC_CLASS DBGC_KERBEROS
48 void mit_samba_context_free(struct mit_samba_context
*ctx
)
50 /* free MIT's krb5_context */
52 krb5_free_context(ctx
->context
);
55 /* then free everything else */
60 * Implement a callback to log to the MIT KDC log facility
62 * http://web.mit.edu/kerberos/krb5-devel/doc/plugindev/general.html#logging-from-kdc-and-kadmind-plugin-modules
64 static void mit_samba_debug(void *private_ptr
, int msg_level
, const char *msg
)
72 com_err("mitkdc", is_error
, "%s", msg
);
75 krb5_error_code
mit_samba_context_init(struct mit_samba_context
**_ctx
)
78 struct mit_samba_context
*ctx
;
79 const char *s4_conf_file
;
81 struct samba_kdc_base_context base_ctx
= {};
83 ctx
= talloc_zero(NULL
, struct mit_samba_context
);
89 base_ctx
.ev_ctx
= tevent_context_init(ctx
);
90 if (!base_ctx
.ev_ctx
) {
94 tevent_loop_allow_nesting(base_ctx
.ev_ctx
);
95 base_ctx
.lp_ctx
= loadparm_init_global(false);
96 if (!base_ctx
.lp_ctx
) {
101 debug_set_callback(NULL
, mit_samba_debug
);
103 /* init s4 configuration */
104 s4_conf_file
= lpcfg_configfile(base_ctx
.lp_ctx
);
105 if (s4_conf_file
!= NULL
) {
106 char *p
= talloc_strdup(ctx
, s4_conf_file
);
111 lpcfg_load(base_ctx
.lp_ctx
, p
);
114 lpcfg_load_default(base_ctx
.lp_ctx
);
117 status
= samba_kdc_setup_db_ctx(ctx
, &base_ctx
, &ctx
->db_ctx
);
118 if (!NT_STATUS_IS_OK(status
)) {
123 /* init MIT's krb_context and log facilities */
124 ret
= smb_krb5_init_context_basic(ctx
,
135 mit_samba_context_free(ctx
);
142 int mit_samba_generate_salt(krb5_data
*salt
)
149 salt
->data
= malloc(salt
->length
);
150 if (salt
->data
== NULL
) {
154 generate_random_buffer((uint8_t *)salt
->data
, salt
->length
);
159 int mit_samba_generate_random_password(krb5_data
*pwd
)
164 const unsigned length
= 24;
170 tmp_ctx
= talloc_named(NULL
,
172 "mit_samba_generate_random_password context");
173 if (tmp_ctx
== NULL
) {
177 password
= generate_random_password(tmp_ctx
, length
, length
);
178 if (password
== NULL
) {
179 talloc_free(tmp_ctx
);
183 data
= strdup(password
);
184 talloc_free(tmp_ctx
);
189 *pwd
= smb_krb5_make_data(data
, length
);
194 krb5_error_code
mit_samba_get_principal(struct mit_samba_context
*ctx
,
195 krb5_const_principal principal
,
197 krb5_db_entry
**_kentry
)
199 struct sdb_entry sentry
= {};
200 krb5_db_entry
*kentry
;
203 krb5_principal referral_principal
= NULL
;
205 kentry
= calloc(1, sizeof(krb5_db_entry
));
206 if (kentry
== NULL
) {
211 * The MIT KDC code that wants the canonical name in all lookups, and
212 * takes care to canonicalize only when appropriate.
214 sflags
|= SDB_F_FORCE_CANON
;
216 if (kflags
& KRB5_KDB_FLAG_REFERRAL_OK
) {
217 sflags
|= SDB_F_CANON
;
220 if (kflags
& KRB5_KDB_FLAG_CLIENT
) {
221 sflags
|= SDB_F_GET_CLIENT
;
222 sflags
|= SDB_F_FOR_AS_REQ
;
224 int equal
= smb_krb5_principal_is_tgs(ctx
->context
, principal
);
230 sflags
|= SDB_F_GET_KRBTGT
;
232 sflags
|= SDB_F_GET_SERVER
;
233 sflags
|= SDB_F_FOR_TGS_REQ
;
237 /* always set this or the created_by data will not be populated by samba's
238 * backend and we will fail to parse the entry later */
239 sflags
|= SDB_F_ADMIN_DATA
;
242 fetch_referral_principal
:
243 ret
= samba_kdc_fetch(ctx
->context
, ctx
->db_ctx
,
244 principal
, sflags
, 0, &sentry
);
248 case SDB_ERR_NOENTRY
:
249 ret
= KRB5_KDB_NOENTRY
;
251 case SDB_ERR_WRONG_REALM
: {
252 char *dest_realm
= NULL
;
253 const char *our_realm
= lpcfg_realm(ctx
->db_ctx
->lp_ctx
);
255 if (sflags
& SDB_F_FOR_AS_REQ
) {
257 * If this is a request for a TGT, we are done. The KDC
258 * will return the correct error to the client.
264 if (referral_principal
!= NULL
) {
265 sdb_entry_free(&sentry
);
266 ret
= KRB5_KDB_NOENTRY
;
271 * We get a TGS request
273 * cifs/dc7.SAMBA2008R2.EXAMPLE.COM@ADDOM.SAMBA.EXAMPLE.COM
275 * to our DC for the realm
277 * ADDOM.SAMBA.EXAMPLE.COM
279 * We look up if we have an entry in the database and get an
280 * entry with the principal:
282 * cifs/dc7.SAMBA2008R2.EXAMPLE.COM@SAMBA2008R2.EXAMPLE.COM
284 * and the error: SDB_ERR_WRONG_REALM.
286 * In the case of a TGS-REQ we need to return a referral ticket
287 * for the next trust hop to the client. This ticket will have
288 * the following principal:
290 * krbtgt/SAMBA2008R2.EXAMPLE.COM@ADDOM.SAMBA.EXAMPLE.COM
292 * We just redo the lookup in the database with the referral
293 * principal and return success.
295 dest_realm
= smb_krb5_principal_get_realm(
296 ctx
, ctx
->context
, sentry
.principal
);
297 sdb_entry_free(&sentry
);
298 if (dest_realm
== NULL
) {
299 ret
= KRB5_KDB_NOENTRY
;
303 ret
= smb_krb5_make_principal(ctx
->context
,
309 TALLOC_FREE(dest_realm
);
314 principal
= referral_principal
;
315 goto fetch_referral_principal
;
317 case SDB_ERR_NOT_FOUND_HERE
:
318 /* FIXME: RODC support */
323 ret
= sdb_entry_to_krb5_db_entry(ctx
->context
, &sentry
, kentry
);
325 sdb_entry_free(&sentry
);
328 krb5_free_principal(ctx
->context
, referral_principal
);
329 referral_principal
= NULL
;
339 krb5_error_code
mit_samba_get_firstkey(struct mit_samba_context
*ctx
,
340 krb5_db_entry
**_kentry
)
342 struct sdb_entry sentry
= {};
343 krb5_db_entry
*kentry
;
346 kentry
= malloc(sizeof(krb5_db_entry
));
347 if (kentry
== NULL
) {
351 ret
= samba_kdc_firstkey(ctx
->context
, ctx
->db_ctx
, SDB_F_ADMIN_DATA
, &sentry
);
355 case SDB_ERR_NOENTRY
:
357 return KRB5_KDB_NOENTRY
;
358 case SDB_ERR_NOT_FOUND_HERE
:
359 /* FIXME: RODC support */
365 ret
= sdb_entry_to_krb5_db_entry(ctx
->context
, &sentry
, kentry
);
367 sdb_entry_free(&sentry
);
377 krb5_error_code
mit_samba_get_nextkey(struct mit_samba_context
*ctx
,
378 krb5_db_entry
**_kentry
)
380 struct sdb_entry sentry
= {};
381 krb5_db_entry
*kentry
;
384 kentry
= malloc(sizeof(krb5_db_entry
));
385 if (kentry
== NULL
) {
389 ret
= samba_kdc_nextkey(ctx
->context
, ctx
->db_ctx
, SDB_F_ADMIN_DATA
, &sentry
);
393 case SDB_ERR_NOENTRY
:
395 return KRB5_KDB_NOENTRY
;
396 case SDB_ERR_NOT_FOUND_HERE
:
397 /* FIXME: RODC support */
403 ret
= sdb_entry_to_krb5_db_entry(ctx
->context
, &sentry
, kentry
);
405 sdb_entry_free(&sentry
);
415 krb5_error_code
mit_samba_get_pac(struct mit_samba_context
*smb_ctx
,
416 krb5_context context
,
418 krb5_db_entry
*client
,
419 krb5_db_entry
*server
,
420 krb5_keyblock
*replaced_reply_key
,
424 const struct auth_user_info_dc
*user_info_dc
= NULL
;
425 struct auth_user_info_dc
*user_info_dc_shallow_copy
= NULL
;
426 DATA_BLOB
*logon_info_blob
= NULL
;
427 DATA_BLOB
*upn_dns_info_blob
= NULL
;
428 DATA_BLOB
*cred_ndr
= NULL
;
429 DATA_BLOB
**cred_ndr_ptr
= NULL
;
430 DATA_BLOB cred_blob
= data_blob_null
;
431 DATA_BLOB
*pcred_blob
= NULL
;
432 DATA_BLOB
*pac_attrs_blob
= NULL
;
433 DATA_BLOB
*requester_sid_blob
= NULL
;
434 const DATA_BLOB
*client_claims_blob
= NULL
;
436 krb5_error_code code
;
437 struct samba_kdc_entry
*skdc_entry
;
438 struct samba_kdc_entry
*server_entry
= NULL
;
440 /* Only include resource groups in a service ticket. */
441 enum auth_group_inclusion group_inclusion
;
442 enum samba_asserted_identity asserted_identity
=
443 (flags
& KRB5_KDB_FLAG_PROTOCOL_TRANSITION
) ?
444 SAMBA_ASSERTED_IDENTITY_SERVICE
:
445 SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY
;
447 if (client
== NULL
) {
450 skdc_entry
= talloc_get_type_abort(client
->e_data
,
451 struct samba_kdc_entry
);
453 if (server
== NULL
) {
457 int result
= smb_krb5_principal_is_tgs(smb_ctx
->context
, server
->princ
);
464 server_entry
= talloc_get_type_abort(server
->e_data
,
465 struct samba_kdc_entry
);
467 /* Only include resource groups in a service ticket. */
469 group_inclusion
= AUTH_EXCLUDE_RESOURCE_GROUPS
;
470 } else if (server_entry
->supported_enctypes
& KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED
) {
471 group_inclusion
= AUTH_INCLUDE_RESOURCE_GROUPS
;
473 group_inclusion
= AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED
;
476 tmp_ctx
= talloc_named(smb_ctx
,
478 "mit_samba_get_pac context");
479 if (tmp_ctx
== NULL
) {
483 /* Check if we have a PREAUTH key */
484 if (replaced_reply_key
!= NULL
) {
485 cred_ndr_ptr
= &cred_ndr
;
488 code
= samba_kdc_get_user_info_from_db(tmp_ctx
,
489 server_entry
->kdc_db_ctx
->samdb
,
494 talloc_free(tmp_ctx
);
498 /* Make a shallow copy of the user_info_dc structure. */
499 nt_status
= authsam_shallow_copy_user_info_dc(tmp_ctx
,
501 &user_info_dc_shallow_copy
);
504 if (!NT_STATUS_IS_OK(nt_status
)) {
505 DBG_ERR("Failed to allocate shallow copy of user_info_dc: %s\n",
506 nt_errstr(nt_status
));
507 talloc_free(tmp_ctx
);
508 return map_errno_from_nt_status(nt_status
);
512 nt_status
= samba_kdc_add_asserted_identity(asserted_identity
,
513 user_info_dc_shallow_copy
);
514 if (!NT_STATUS_IS_OK(nt_status
)) {
515 DBG_ERR("Failed to add asserted identity: %s\n",
516 nt_errstr(nt_status
));
517 talloc_free(tmp_ctx
);
521 nt_status
= samba_kdc_add_claims_valid(user_info_dc_shallow_copy
);
522 if (!NT_STATUS_IS_OK(nt_status
)) {
523 DBG_ERR("Failed to add Claims Valid: %s\n",
524 nt_errstr(nt_status
));
525 talloc_free(tmp_ctx
);
529 /* We no longer need to modify this, so assign to const variable */
530 user_info_dc
= user_info_dc_shallow_copy
;
532 nt_status
= samba_kdc_get_logon_info_blob(tmp_ctx
,
536 if (!NT_STATUS_IS_OK(nt_status
)) {
537 talloc_free(tmp_ctx
);
541 if (cred_ndr_ptr
!= NULL
) {
542 nt_status
= samba_kdc_get_cred_ndr_blob(tmp_ctx
,
545 if (!NT_STATUS_IS_OK(nt_status
)) {
546 talloc_free(tmp_ctx
);
551 nt_status
= samba_kdc_get_upn_info_blob(tmp_ctx
,
554 if (!NT_STATUS_IS_OK(nt_status
)) {
555 talloc_free(tmp_ctx
);
560 nt_status
= samba_kdc_get_pac_attrs_blob(tmp_ctx
,
561 PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY
,
563 if (!NT_STATUS_IS_OK(nt_status
)) {
564 talloc_free(tmp_ctx
);
568 nt_status
= samba_kdc_get_requester_sid_blob(tmp_ctx
,
570 &requester_sid_blob
);
571 if (!NT_STATUS_IS_OK(nt_status
)) {
572 talloc_free(tmp_ctx
);
577 nt_status
= samba_kdc_get_claims_blob(tmp_ctx
,
579 &client_claims_blob
);
580 if (!NT_STATUS_IS_OK(nt_status
)) {
581 talloc_free(tmp_ctx
);
585 if (replaced_reply_key
!= NULL
&& cred_ndr
!= NULL
) {
586 code
= samba_kdc_encrypt_pac_credentials(context
,
592 talloc_free(tmp_ctx
);
595 pcred_blob
= &cred_blob
;
598 code
= samba_make_krb5_pac(context
,
604 NULL
/* deleg_blob */,
606 NULL
/* device_info_blob */,
607 NULL
/* device_claims_blob */,
610 talloc_free(tmp_ctx
);
614 krb5_error_code
mit_samba_update_pac(struct mit_samba_context
*ctx
,
615 krb5_context context
,
617 krb5_db_entry
*client
,
618 krb5_db_entry
*server
,
619 krb5_db_entry
*krbtgt
,
623 TALLOC_CTX
*tmp_ctx
= NULL
;
624 krb5_error_code code
;
625 struct samba_kdc_entry
*client_skdc_entry
= NULL
;
626 struct samba_kdc_entry
*server_skdc_entry
= NULL
;
627 struct samba_kdc_entry
*krbtgt_skdc_entry
= NULL
;
628 struct samba_kdc_entry_pac client_pac_entry
= {};
629 bool is_in_db
= false;
630 bool is_trusted
= false;
633 /* Create a memory context early so code can use talloc_stackframe() */
634 tmp_ctx
= talloc_named(ctx
, 0, "mit_samba_update_pac context");
635 if (tmp_ctx
== NULL
) {
639 if (client
!= NULL
) {
641 talloc_get_type_abort(client
->e_data
,
642 struct samba_kdc_entry
);
645 if (krbtgt
== NULL
) {
650 talloc_get_type_abort(krbtgt
->e_data
,
651 struct samba_kdc_entry
);
653 if (server
== NULL
) {
658 talloc_get_type_abort(server
->e_data
,
659 struct samba_kdc_entry
);
662 * If the krbtgt was generated by an RODC, and we are not that
663 * RODC, then we need to regenerate the PAC - we can't trust
664 * it, and confirm that the RODC was permitted to print this ticket
666 * Because of the samba_kdc_validate_pac_blob() step we can be
667 * sure that the record in 'client' or 'server' matches the SID in the
670 code
= samba_krbtgt_is_in_db(krbtgt_skdc_entry
,
677 if (kdc_flags
& KRB5_KDB_FLAG_PROTOCOL_TRANSITION
) {
678 flags
|= SAMBA_KDC_FLAG_PROTOCOL_TRANSITION
;
681 if (kdc_flags
& KRB5_KDB_FLAG_CONSTRAINED_DELEGATION
) {
682 flags
|= SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION
;
685 client_pac_entry
= samba_kdc_entry_pac_from_trusted(old_pac
,
687 samba_kdc_entry_is_trust(krbtgt_skdc_entry
),
690 code
= samba_kdc_verify_pac(tmp_ctx
,
692 krbtgt_skdc_entry
->kdc_db_ctx
->samdb
,
700 code
= samba_kdc_update_pac(tmp_ctx
,
702 krbtgt_skdc_entry
->kdc_db_ctx
->samdb
,
703 krbtgt_skdc_entry
->kdc_db_ctx
->lp_ctx
,
708 NULL
/* delegated_proxy_principal */,
709 (struct samba_kdc_entry_pac
) {} /* delegated_proxy */,
710 (struct samba_kdc_entry_pac
) {} /* device */,
712 NULL
/* server_audit_info_out */,
713 NULL
/* status_out */);
715 if (code
== ENOATTR
) {
717 * We can't tell the KDC to not issue a PAC. It will
718 * just return the newly allocated empty PAC.
725 talloc_free(tmp_ctx
);
729 /* provide header, function is exported but there are no public headers */
731 krb5_error_code
encode_krb5_padata_sequence(krb5_pa_data
*const *rep
, krb5_data
**code
);
733 /* this function allocates 'data' using malloc.
734 * The caller is responsible for freeing it */
735 static void samba_kdc_build_edata_reply(NTSTATUS nt_status
, DATA_BLOB
*e_data
)
737 krb5_error_code ret
= 0;
738 krb5_pa_data pa
, *ppa
[2];
747 pa
.magic
= KV5M_PA_DATA
;
748 pa
.pa_type
= KRB5_PADATA_PW_SALT
/* KERB_ERR_TYPE_EXTENDED */;
750 pa
.contents
= malloc(pa
.length
);
755 SIVAL(pa
.contents
, 0, NT_STATUS_V(nt_status
));
756 SIVAL(pa
.contents
, 4, 0);
757 SIVAL(pa
.contents
, 8, 1);
762 ret
= encode_krb5_padata_sequence(ppa
, &d
);
768 e_data
->data
= (uint8_t *)d
->data
;
769 e_data
->length
= d
->length
;
771 /* free d, not d->data - gd */
777 krb5_error_code
mit_samba_check_client_access(struct mit_samba_context
*ctx
,
778 krb5_db_entry
*client
,
779 const char *client_name
,
780 krb5_db_entry
*server
,
781 const char *server_name
,
782 const char *netbios_name
,
783 bool password_change
,
786 struct samba_kdc_entry
*skdc_entry
;
789 skdc_entry
= talloc_get_type(client
->e_data
, struct samba_kdc_entry
);
791 nt_status
= samba_kdc_check_client_access(skdc_entry
,
796 if (!NT_STATUS_IS_OK(nt_status
)) {
797 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_MEMORY
)) {
801 samba_kdc_build_edata_reply(nt_status
, e_data
);
803 return samba_kdc_map_policy_err(nt_status
);
809 krb5_error_code
mit_samba_check_s4u2proxy(struct mit_samba_context
*ctx
,
810 const krb5_db_entry
*server
,
811 krb5_const_principal target_principal
)
813 struct samba_kdc_entry
*server_skdc_entry
=
814 talloc_get_type_abort(server
->e_data
, struct samba_kdc_entry
);
815 krb5_error_code code
;
817 code
= samba_kdc_check_s4u2proxy(ctx
->context
,
825 krb5_error_code
mit_samba_check_allowed_to_delegate_from(
826 struct mit_samba_context
*ctx
,
827 krb5_const_principal client_principal
,
828 krb5_const_principal server_principal
,
830 const krb5_db_entry
*proxy
)
832 struct samba_kdc_entry
*proxy_skdc_entry
=
833 talloc_get_type_abort(proxy
->e_data
, struct samba_kdc_entry
);
834 struct auth_user_info_dc
*user_info_dc
= NULL
;
835 TALLOC_CTX
*mem_ctx
= NULL
;
836 krb5_error_code code
;
838 mem_ctx
= talloc_new(NULL
);
839 if (mem_ctx
== NULL
) {
844 * FIXME: If ever we support RODCs, we must check that the PAC has not
845 * been issued by an RODC (other than ourselves) — otherwise the PAC
846 * cannot be trusted. Because the plugin interface does not give us the
847 * client entry, we cannot look up its groups in the database.
849 code
= kerberos_pac_to_user_info_dc(mem_ctx
,
853 AUTH_INCLUDE_RESOURCE_GROUPS
,
861 code
= samba_kdc_check_s4u2proxy_rbcd(ctx
->context
,
866 NULL
/* device_info_dc */,
867 (struct auth_claims
) {},
870 talloc_free(mem_ctx
);
874 static krb5_error_code
mit_samba_change_pwd_error(krb5_context context
,
876 enum samPwdChangeReason reject_reason
,
877 struct samr_DomInfo1
*dominfo
)
879 krb5_error_code code
= KADM5_PASS_Q_GENERIC
;
881 if (NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_USER
)) {
882 code
= KADM5_BAD_PRINCIPAL
;
883 krb5_set_error_message(context
,
885 "No such user when changing password");
887 if (NT_STATUS_EQUAL(result
, NT_STATUS_ACCESS_DENIED
)) {
888 code
= KADM5_PASS_Q_GENERIC
;
889 krb5_set_error_message(context
,
891 "Not permitted to change password");
893 if (NT_STATUS_EQUAL(result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
895 switch (reject_reason
) {
896 case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
:
897 code
= KADM5_PASS_Q_TOOSHORT
;
898 krb5_set_error_message(context
,
900 "Password too short, password "
901 "must be at least %d characters "
903 dominfo
->min_password_length
);
905 case SAM_PWD_CHANGE_NOT_COMPLEX
:
906 code
= KADM5_PASS_Q_DICT
;
907 krb5_set_error_message(context
,
909 "Password does not meet "
910 "complexity requirements");
912 case SAM_PWD_CHANGE_PWD_IN_HISTORY
:
913 code
= KADM5_PASS_TOOSOON
;
914 krb5_set_error_message(context
,
916 "Password is already in password "
917 "history. New password must not "
918 "match any of your %d previous "
920 dominfo
->password_history_length
);
923 code
= KADM5_PASS_Q_GENERIC
;
924 krb5_set_error_message(context
,
926 "Password change rejected, "
927 "password changes may not be "
928 "permitted on this account, or "
929 "the minimum password age may "
930 "not have elapsed.");
938 krb5_error_code
mit_samba_kpasswd_change_password(struct mit_samba_context
*ctx
,
940 krb5_db_entry
*db_entry
)
943 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
946 enum samPwdChangeReason reject_reason
;
947 struct samr_DomInfo1
*dominfo
;
948 const char *error_string
= NULL
;
949 const struct auth_user_info_dc
*user_info_dc
= NULL
;
950 struct samba_kdc_entry
*p
=
951 talloc_get_type_abort(db_entry
->e_data
, struct samba_kdc_entry
);
952 krb5_error_code code
= 0;
954 #ifdef DEBUG_PASSWORD
955 DBG_WARNING("mit_samba_kpasswd_change_password called with: %s\n", pwd
);
958 tmp_ctx
= talloc_named(ctx
, 0, "mit_samba_kpasswd_change_password");
959 if (tmp_ctx
== NULL
) {
963 code
= samba_kdc_get_user_info_from_db(tmp_ctx
,
969 const char *krb5err
= krb5_get_error_message(ctx
->context
, code
);
970 DBG_WARNING("samba_kdc_get_user_info_from_db failed: %s\n",
971 krb5err
!= NULL
? krb5err
: "<unknown>");
972 krb5_free_error_message(ctx
->context
, krb5err
);
977 status
= auth_generate_session_info(tmp_ctx
,
981 0, /* session_info_flags */
984 if (!NT_STATUS_IS_OK(status
)) {
985 DBG_WARNING("auth_generate_session_info failed: %s\n",
991 /* password is expected as UTF16 */
993 if (!convert_string_talloc(tmp_ctx
, CH_UTF8
, CH_UTF16
,
995 &password
.data
, &password
.length
)) {
996 DBG_WARNING("convert_string_talloc failed\n");
1001 status
= samdb_kpasswd_change_password(tmp_ctx
,
1002 ctx
->db_ctx
->lp_ctx
,
1003 ctx
->db_ctx
->ev_ctx
,
1010 if (!NT_STATUS_IS_OK(status
)) {
1011 DBG_WARNING("samdb_kpasswd_change_password failed: %s\n",
1013 code
= KADM5_PASS_Q_GENERIC
;
1014 krb5_set_error_message(ctx
->context
, code
, "%s", error_string
);
1018 if (!NT_STATUS_IS_OK(result
)) {
1019 code
= mit_samba_change_pwd_error(ctx
->context
,
1026 talloc_free(tmp_ctx
);
1031 void mit_samba_zero_bad_password_count(krb5_db_entry
*db_entry
)
1033 /* struct netr_SendToSamBase *send_to_sam = NULL; */
1034 struct samba_kdc_entry
*p
=
1035 talloc_get_type_abort(db_entry
->e_data
, struct samba_kdc_entry
);
1036 struct ldb_dn
*domain_dn
;
1038 domain_dn
= ldb_get_default_basedn(p
->kdc_db_ctx
->samdb
);
1040 authsam_logon_success_accounting(p
->kdc_db_ctx
->samdb
,
1045 /* TODO: RODC support */
1049 void mit_samba_update_bad_password_count(krb5_db_entry
*db_entry
)
1051 struct samba_kdc_entry
*p
=
1052 talloc_get_type_abort(db_entry
->e_data
, struct samba_kdc_entry
);
1054 authsam_update_bad_pwd_count(p
->kdc_db_ctx
->samdb
,
1056 ldb_get_default_basedn(p
->kdc_db_ctx
->samdb
));
1059 bool mit_samba_princ_needs_pac(krb5_db_entry
*db_entry
)
1061 struct samba_kdc_entry
*skdc_entry
=
1062 talloc_get_type_abort(db_entry
->e_data
, struct samba_kdc_entry
);
1064 return samba_princ_needs_pac(skdc_entry
);