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"
29 #include <kadm5/kadm_err.h>
31 #include "kdc/sdb_kdb.h"
32 #include "auth/kerberos/kerberos.h"
33 #include "auth/kerberos/pac_utils.h"
34 #include "kdc/samba_kdc.h"
35 #include "kdc/pac-glue.h"
36 #include "kdc/db-glue.h"
37 #include "auth/auth.h"
38 #include "kdc/kpasswd_glue.h"
39 #include "auth/auth_sam.h"
41 #include "mit_samba.h"
43 void mit_samba_context_free(struct mit_samba_context
*ctx
)
45 /* free heimdal's krb5_context */
47 krb5_free_context(ctx
->context
);
50 /* then free everything else */
54 int mit_samba_context_init(struct mit_samba_context
**_ctx
)
57 struct mit_samba_context
*ctx
;
58 const char *s4_conf_file
;
60 struct samba_kdc_base_context base_ctx
;
62 ctx
= talloc_zero(NULL
, struct mit_samba_context
);
68 base_ctx
.ev_ctx
= tevent_context_init(ctx
);
69 if (!base_ctx
.ev_ctx
) {
73 tevent_loop_allow_nesting(base_ctx
.ev_ctx
);
74 base_ctx
.lp_ctx
= loadparm_init_global(false);
75 if (!base_ctx
.lp_ctx
) {
80 setup_logging("mitkdc", DEBUG_DEFAULT_STDOUT
);
82 /* init s4 configuration */
83 s4_conf_file
= lpcfg_configfile(base_ctx
.lp_ctx
);
85 lpcfg_load(base_ctx
.lp_ctx
, s4_conf_file
);
87 lpcfg_load_default(base_ctx
.lp_ctx
);
90 status
= samba_kdc_setup_db_ctx(ctx
, &base_ctx
, &ctx
->db_ctx
);
91 if (!NT_STATUS_IS_OK(status
)) {
96 /* init heimdal's krb_context and log facilities */
97 ret
= smb_krb5_init_context_basic(ctx
,
108 mit_samba_context_free(ctx
);
115 static krb5_error_code
ks_is_tgs_principal(struct mit_samba_context
*ctx
,
116 krb5_const_principal principal
)
121 p
= smb_krb5_principal_get_comp_string(ctx
, ctx
->context
, principal
, 0);
123 eq
= krb5_princ_size(ctx
->context
, principal
) == 2 &&
124 (strcmp(p
, KRB5_TGS_NAME
) == 0);
131 int mit_samba_generate_salt(krb5_data
*salt
)
138 salt
->data
= malloc(salt
->length
);
139 if (salt
->data
== NULL
) {
143 generate_random_buffer((uint8_t *)salt
->data
, salt
->length
);
148 int mit_samba_generate_random_password(krb5_data
*pwd
)
158 tmp_ctx
= talloc_named(NULL
,
160 "mit_samba_create_principal_password context");
161 if (tmp_ctx
== NULL
) {
165 password
= generate_random_password(tmp_ctx
, pwd
->length
, pwd
->length
);
166 if (password
== NULL
) {
167 talloc_free(tmp_ctx
);
171 pwd
->data
= strdup(password
);
172 talloc_free(tmp_ctx
);
173 if (pwd
->data
== NULL
) {
180 int mit_samba_get_principal(struct mit_samba_context
*ctx
,
181 krb5_const_principal principal
,
183 krb5_db_entry
**_kentry
)
185 struct sdb_entry_ex sentry
= {
188 krb5_db_entry
*kentry
;
191 krb5_principal referral_principal
= NULL
;
193 kentry
= calloc(1, sizeof(krb5_db_entry
));
194 if (kentry
== NULL
) {
198 if (kflags
& KRB5_KDB_FLAG_CANONICALIZE
) {
199 sflags
|= SDB_F_CANON
;
201 if (kflags
& (KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY
|
202 KRB5_KDB_FLAG_INCLUDE_PAC
)) {
204 * KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is equal to
207 * We use ANY to also allow AS_REQ for service principal names
208 * This is supported by Windows.
210 sflags
|= SDB_F_GET_ANY
|SDB_F_FOR_AS_REQ
;
211 } else if (ks_is_tgs_principal(ctx
, principal
)) {
212 sflags
|= SDB_F_GET_KRBTGT
;
214 sflags
|= SDB_F_GET_SERVER
|SDB_F_FOR_TGS_REQ
;
217 /* always set this or the created_by data will not be populated by samba's
218 * backend and we will fail to parse the entry later */
219 sflags
|= SDB_F_ADMIN_DATA
;
222 fetch_referral_principal
:
223 ret
= samba_kdc_fetch(ctx
->context
, ctx
->db_ctx
,
224 principal
, sflags
, 0, &sentry
);
228 case SDB_ERR_NOENTRY
:
229 ret
= KRB5_KDB_NOENTRY
;
231 case SDB_ERR_WRONG_REALM
: {
232 char *dest_realm
= NULL
;
233 const char *our_realm
= lpcfg_realm(ctx
->db_ctx
->lp_ctx
);
235 if (sflags
& SDB_F_FOR_AS_REQ
) {
237 * If this is a request for a TGT, we are done. The KDC
238 * will return the correct error to the client.
244 if (referral_principal
!= NULL
) {
245 sdb_free_entry(&sentry
);
246 ret
= KRB5_KDB_NOENTRY
;
251 * We get a TGS request
253 * cifs/dc7.SAMBA2008R2.EXAMPLE.COM@ADDOM.SAMBA.EXAMPLE.COM
255 * to our DC for the realm
257 * ADDOM.SAMBA.EXAMPLE.COM
259 * We look up if we have and entry in the database and get an
260 * entry with the pricipal:
262 * cifs/dc7.SAMBA2008R2.EXAMPLE.COM@SAMBA2008R2.EXAMPLE.COM
264 * and the error: SDB_ERR_WRONG_REALM.
266 * In the case of a TGS-REQ we need to return a referral ticket
267 * fo the next trust hop to the client. This ticket will have
268 * the following principal:
270 * krbtgt/SAMBA2008R2.EXAMPLE.COM@ADDOM.SAMBA.EXAMPLE.COM
272 * We just redo the lookup in the database with the referral
273 * principal and return success.
275 dest_realm
= smb_krb5_principal_get_realm(
276 ctx
, ctx
->context
, sentry
.entry
.principal
);
277 sdb_free_entry(&sentry
);
278 if (dest_realm
== NULL
) {
279 ret
= KRB5_KDB_NOENTRY
;
283 ret
= smb_krb5_make_principal(ctx
->context
,
289 TALLOC_FREE(dest_realm
);
294 principal
= referral_principal
;
295 goto fetch_referral_principal
;
297 case SDB_ERR_NOT_FOUND_HERE
:
298 /* FIXME: RODC support */
303 ret
= sdb_entry_ex_to_kdb_entry_ex(ctx
->context
, &sentry
, kentry
);
305 sdb_free_entry(&sentry
);
308 krb5_free_principal(ctx
->context
, referral_principal
);
309 referral_principal
= NULL
;
319 int mit_samba_get_firstkey(struct mit_samba_context
*ctx
,
320 krb5_db_entry
**_kentry
)
322 struct sdb_entry_ex sentry
= {
325 krb5_db_entry
*kentry
;
328 kentry
= malloc(sizeof(krb5_db_entry
));
329 if (kentry
== NULL
) {
333 ret
= samba_kdc_firstkey(ctx
->context
, ctx
->db_ctx
, &sentry
);
337 case SDB_ERR_NOENTRY
:
339 return KRB5_KDB_NOENTRY
;
340 case SDB_ERR_NOT_FOUND_HERE
:
341 /* FIXME: RODC support */
347 ret
= sdb_entry_ex_to_kdb_entry_ex(ctx
->context
, &sentry
, kentry
);
349 sdb_free_entry(&sentry
);
359 int mit_samba_get_nextkey(struct mit_samba_context
*ctx
,
360 krb5_db_entry
**_kentry
)
362 struct sdb_entry_ex sentry
= {
365 krb5_db_entry
*kentry
;
368 kentry
= malloc(sizeof(krb5_db_entry
));
369 if (kentry
== NULL
) {
373 ret
= samba_kdc_nextkey(ctx
->context
, ctx
->db_ctx
, &sentry
);
377 case SDB_ERR_NOENTRY
:
379 return KRB5_KDB_NOENTRY
;
380 case SDB_ERR_NOT_FOUND_HERE
:
381 /* FIXME: RODC support */
387 ret
= sdb_entry_ex_to_kdb_entry_ex(ctx
->context
, &sentry
, kentry
);
389 sdb_free_entry(&sentry
);
399 int mit_samba_get_pac(struct mit_samba_context
*smb_ctx
,
400 krb5_context context
,
401 krb5_db_entry
*client
,
402 krb5_keyblock
*client_key
,
406 DATA_BLOB
*logon_info_blob
= NULL
;
407 DATA_BLOB
*upn_dns_info_blob
= NULL
;
408 DATA_BLOB
*cred_ndr
= NULL
;
409 DATA_BLOB
**cred_ndr_ptr
= NULL
;
410 DATA_BLOB cred_blob
= data_blob_null
;
411 DATA_BLOB
*pcred_blob
= NULL
;
413 krb5_error_code code
;
414 struct samba_kdc_entry
*skdc_entry
;
416 skdc_entry
= talloc_get_type_abort(client
->e_data
,
417 struct samba_kdc_entry
);
419 tmp_ctx
= talloc_named(smb_ctx
,
421 "mit_samba_get_pac_data_blobs context");
422 if (tmp_ctx
== NULL
) {
426 #if 0 /* TODO Find out if this is a pkinit_reply key */
427 /* Check if we have a PREAUTH key */
428 if (client_key
!= NULL
) {
429 cred_ndr_ptr
= &cred_ndr
;
433 nt_status
= samba_kdc_get_pac_blobs(tmp_ctx
,
438 if (!NT_STATUS_IS_OK(nt_status
)) {
439 talloc_free(tmp_ctx
);
443 if (cred_ndr
!= NULL
) {
444 code
= samba_kdc_encrypt_pac_credentials(context
,
450 talloc_free(tmp_ctx
);
453 pcred_blob
= &cred_blob
;
456 code
= samba_make_krb5_pac(context
,
463 talloc_free(tmp_ctx
);
467 krb5_error_code
mit_samba_reget_pac(struct mit_samba_context
*ctx
,
468 krb5_context context
,
470 krb5_const_principal client_principal
,
471 krb5_db_entry
*client
,
472 krb5_db_entry
*server
,
473 krb5_db_entry
*krbtgt
,
474 krb5_keyblock
*krbtgt_keyblock
,
478 krb5_error_code code
;
480 DATA_BLOB
*pac_blob
= NULL
;
481 DATA_BLOB
*upn_blob
= NULL
;
482 DATA_BLOB
*deleg_blob
= NULL
;
483 struct samba_kdc_entry
*client_skdc_entry
= NULL
;
484 struct samba_kdc_entry
*krbtgt_skdc_entry
= NULL
;
485 struct samba_kdc_entry
*server_skdc_entry
= NULL
;
486 bool is_in_db
= false;
487 bool is_untrusted
= false;
488 size_t num_types
= 0;
489 uint32_t *types
= NULL
;
490 uint32_t forced_next_type
= 0;
492 ssize_t logon_info_idx
= -1;
493 ssize_t delegation_idx
= -1;
494 ssize_t logon_name_idx
= -1;
495 ssize_t upn_dns_info_idx
= -1;
496 ssize_t srv_checksum_idx
= -1;
497 ssize_t kdc_checksum_idx
= -1;
498 krb5_pac new_pac
= NULL
;
501 if (client
!= NULL
) {
503 talloc_get_type_abort(client
->e_data
,
504 struct samba_kdc_entry
);
506 /* The user account may be set not to want the PAC */
507 ok
= samba_princ_needs_pac(client_skdc_entry
);
513 if (server
== NULL
) {
517 talloc_get_type_abort(server
->e_data
,
518 struct samba_kdc_entry
);
520 if (krbtgt
== NULL
) {
524 talloc_get_type_abort(krbtgt
->e_data
,
525 struct samba_kdc_entry
);
527 tmp_ctx
= talloc_named(ctx
, 0, "mit_samba_reget_pac context");
528 if (tmp_ctx
== NULL
) {
532 code
= samba_krbtgt_is_in_db(krbtgt_skdc_entry
,
540 if (client
== NULL
) {
541 code
= KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
;
545 nt_status
= samba_kdc_get_pac_blobs(tmp_ctx
,
550 if (!NT_STATUS_IS_OK(nt_status
)) {
555 struct PAC_SIGNATURE_DATA
*pac_srv_sig
;
556 struct PAC_SIGNATURE_DATA
*pac_kdc_sig
;
558 pac_blob
= talloc_zero(tmp_ctx
, DATA_BLOB
);
559 if (pac_blob
== NULL
) {
564 pac_srv_sig
= talloc_zero(tmp_ctx
, struct PAC_SIGNATURE_DATA
);
565 if (pac_srv_sig
== NULL
) {
570 pac_kdc_sig
= talloc_zero(tmp_ctx
, struct PAC_SIGNATURE_DATA
);
571 if (pac_kdc_sig
== NULL
) {
576 nt_status
= samba_kdc_update_pac_blob(tmp_ctx
,
584 if (!NT_STATUS_IS_OK(nt_status
)) {
585 DEBUG(0, ("Update PAC blob failed: %s\n",
586 nt_errstr(nt_status
)));
593 * Now check the KDC signature, fetching the correct
594 * key based on the enc type.
596 code
= check_pac_checksum(pac_srv_sig
->signature
,
601 DBG_INFO("PAC KDC signature failed to verify\n");
607 if (flags
& KRB5_KDB_FLAG_CONSTRAINED_DELEGATION
) {
608 deleg_blob
= talloc_zero(tmp_ctx
, DATA_BLOB
);
609 if (deleg_blob
== NULL
) {
614 nt_status
= samba_kdc_update_delegation_info_blob(tmp_ctx
,
618 discard_const(client_principal
),
620 if (!NT_STATUS_IS_OK(nt_status
)) {
621 DEBUG(0, ("Update delegation info failed: %s\n",
622 nt_errstr(nt_status
)));
628 /* Check the types of the given PAC */
629 code
= krb5_pac_get_types(context
, *pac
, &num_types
, &types
);
634 for (i
= 0; i
< num_types
; i
++) {
636 case PAC_TYPE_LOGON_INFO
:
637 if (logon_info_idx
!= -1) {
638 DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
648 case PAC_TYPE_CONSTRAINED_DELEGATION
:
649 if (delegation_idx
!= -1) {
650 DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
660 case PAC_TYPE_LOGON_NAME
:
661 if (logon_name_idx
!= -1) {
662 DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
672 case PAC_TYPE_UPN_DNS_INFO
:
673 if (upn_dns_info_idx
!= -1) {
674 DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
682 upn_dns_info_idx
= i
;
684 case PAC_TYPE_SRV_CHECKSUM
:
685 if (srv_checksum_idx
!= -1) {
686 DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
694 srv_checksum_idx
= i
;
696 case PAC_TYPE_KDC_CHECKSUM
:
697 if (kdc_checksum_idx
!= -1) {
698 DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
706 kdc_checksum_idx
= i
;
713 if (logon_info_idx
== -1) {
714 DEBUG(1, ("PAC_TYPE_LOGON_INFO missing\n"));
719 if (logon_name_idx
== -1) {
720 DEBUG(1, ("PAC_TYPE_LOGON_NAME missing\n"));
725 if (srv_checksum_idx
== -1) {
726 DEBUG(1, ("PAC_TYPE_SRV_CHECKSUM missing\n"));
731 if (kdc_checksum_idx
== -1) {
732 DEBUG(1, ("PAC_TYPE_KDC_CHECKSUM missing\n"));
738 /* Build an updated PAC */
739 code
= krb5_pac_init(context
, &new_pac
);
747 DATA_BLOB type_blob
= data_blob_null
;
750 if (forced_next_type
!= 0) {
752 * We need to inject possible missing types
754 type
= forced_next_type
;
755 forced_next_type
= 0;
756 } else if (i
< num_types
) {
764 case PAC_TYPE_LOGON_INFO
:
765 type_blob
= *pac_blob
;
767 if (delegation_idx
== -1 && deleg_blob
!= NULL
) {
768 /* inject CONSTRAINED_DELEGATION behind */
769 forced_next_type
= PAC_TYPE_CONSTRAINED_DELEGATION
;
772 case PAC_TYPE_CONSTRAINED_DELEGATION
:
773 if (deleg_blob
!= NULL
) {
774 type_blob
= *deleg_blob
;
777 case PAC_TYPE_CREDENTIAL_INFO
:
779 * Note that we copy the credential blob,
780 * as it's only usable with the PKINIT based
781 * AS-REP reply key, it's only available on the
782 * host which did the AS-REQ/AS-REP exchange.
784 * This matches Windows 2008R2...
787 case PAC_TYPE_LOGON_NAME
:
789 * This is generated in the main KDC code
792 case PAC_TYPE_UPN_DNS_INFO
:
794 * Replace in the RODC case, otherwise
795 * upn_blob is NULL and we just copy.
797 if (upn_blob
!= NULL
) {
798 type_blob
= *upn_blob
;
801 case PAC_TYPE_SRV_CHECKSUM
:
803 * This is generated in the main KDC code
806 case PAC_TYPE_KDC_CHECKSUM
:
808 * This is generated in the main KDC code
816 if (type_blob
.length
!= 0) {
817 code
= smb_krb5_copy_data_contents(&type_data
,
822 krb5_pac_free(context
, new_pac
);
826 code
= krb5_pac_get_buffer(context
,
832 krb5_pac_free(context
, new_pac
);
837 code
= krb5_pac_add_buffer(context
,
841 smb_krb5_free_data_contents(context
, &type_data
);
844 krb5_pac_free(context
, new_pac
);
851 /* We now replace the pac */
852 krb5_pac_free(context
, *pac
);
855 talloc_free(tmp_ctx
);
859 /* provide header, function is exported but there are no public headers */
861 krb5_error_code
encode_krb5_padata_sequence(krb5_pa_data
*const *rep
, krb5_data
**code
);
863 /* this function allocates 'data' using malloc.
864 * The caller is responsible for freeing it */
865 static void samba_kdc_build_edata_reply(NTSTATUS nt_status
, DATA_BLOB
*e_data
)
867 krb5_error_code ret
= 0;
868 krb5_pa_data pa
, *ppa
[2];
877 pa
.magic
= KV5M_PA_DATA
;
878 pa
.pa_type
= KRB5_PADATA_PW_SALT
;
880 pa
.contents
= malloc(pa
.length
);
885 SIVAL(pa
.contents
, 0, NT_STATUS_V(nt_status
));
886 SIVAL(pa
.contents
, 4, 0);
887 SIVAL(pa
.contents
, 8, 1);
892 ret
= encode_krb5_padata_sequence(ppa
, &d
);
898 e_data
->data
= (uint8_t *)d
->data
;
899 e_data
->length
= d
->length
;
901 /* free d, not d->data - gd */
907 int mit_samba_check_client_access(struct mit_samba_context
*ctx
,
908 krb5_db_entry
*client
,
909 const char *client_name
,
910 krb5_db_entry
*server
,
911 const char *server_name
,
912 const char *netbios_name
,
913 bool password_change
,
916 struct samba_kdc_entry
*skdc_entry
;
919 skdc_entry
= talloc_get_type(client
->e_data
, struct samba_kdc_entry
);
921 nt_status
= samba_kdc_check_client_access(skdc_entry
,
926 if (!NT_STATUS_IS_OK(nt_status
)) {
927 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_MEMORY
)) {
931 samba_kdc_build_edata_reply(nt_status
, e_data
);
933 return samba_kdc_map_policy_err(nt_status
);
939 int mit_samba_check_s4u2proxy(struct mit_samba_context
*ctx
,
940 krb5_db_entry
*kentry
,
941 const char *target_name
,
942 bool is_nt_enterprise_name
)
946 * This is disabled because mit_samba_update_pac_data() does not handle
947 * S4U_DELEGATION_INFO
950 return KRB5KDC_ERR_BADOPTION
;
952 krb5_principal target_principal
;
956 if (is_nt_enterprise_name
) {
957 flags
= KRB5_PRINCIPAL_PARSE_ENTERPRISE
;
960 ret
= krb5_parse_name_flags(ctx
->context
, target_name
,
961 flags
, &target_principal
);
966 ret
= samba_kdc_check_s4u2proxy(ctx
->context
,
971 krb5_free_principal(ctx
->context
, target_principal
);
977 static krb5_error_code
mit_samba_change_pwd_error(krb5_context context
,
979 enum samPwdChangeReason reject_reason
,
980 struct samr_DomInfo1
*dominfo
)
982 krb5_error_code code
= KADM5_PASS_Q_GENERIC
;
984 if (NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_USER
)) {
985 code
= KADM5_BAD_PRINCIPAL
;
986 krb5_set_error_message(context
,
988 "No such user when changing password");
990 if (NT_STATUS_EQUAL(result
, NT_STATUS_ACCESS_DENIED
)) {
991 code
= KADM5_PASS_Q_GENERIC
;
992 krb5_set_error_message(context
,
994 "Not permitted to change password");
996 if (NT_STATUS_EQUAL(result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
998 switch (reject_reason
) {
999 case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
:
1000 code
= KADM5_PASS_Q_TOOSHORT
;
1001 krb5_set_error_message(context
,
1003 "Password too short, password "
1004 "must be at least %d characters "
1006 dominfo
->min_password_length
);
1008 case SAM_PWD_CHANGE_NOT_COMPLEX
:
1009 code
= KADM5_PASS_Q_DICT
;
1010 krb5_set_error_message(context
,
1012 "Password does not meet "
1013 "complexity requirements");
1015 case SAM_PWD_CHANGE_PWD_IN_HISTORY
:
1016 code
= KADM5_PASS_TOOSOON
;
1017 krb5_set_error_message(context
,
1019 "Password is already in password "
1020 "history. New password must not "
1021 "match any of your %d previous "
1023 dominfo
->password_history_length
);
1026 code
= KADM5_PASS_Q_GENERIC
;
1027 krb5_set_error_message(context
,
1029 "Password change rejected, "
1030 "password changes may not be "
1031 "permitted on this account, or "
1032 "the minimum password age may "
1033 "not have elapsed.");
1041 int mit_samba_kpasswd_change_password(struct mit_samba_context
*ctx
,
1043 krb5_db_entry
*db_entry
)
1046 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1047 TALLOC_CTX
*tmp_ctx
;
1049 enum samPwdChangeReason reject_reason
;
1050 struct samr_DomInfo1
*dominfo
;
1051 const char *error_string
= NULL
;
1052 struct auth_user_info_dc
*user_info_dc
;
1053 struct samba_kdc_entry
*p
;
1054 krb5_error_code code
= 0;
1056 #ifdef DEBUG_PASSWORD
1057 DEBUG(1,("mit_samba_kpasswd_change_password called with: %s\n", pwd
));
1060 tmp_ctx
= talloc_named(ctx
, 0, "mit_samba_kpasswd_change_password");
1061 if (tmp_ctx
== NULL
) {
1065 p
= (struct samba_kdc_entry
*)db_entry
->e_data
;
1067 status
= authsam_make_user_info_dc(tmp_ctx
,
1069 lpcfg_netbios_name(ctx
->db_ctx
->lp_ctx
),
1070 lpcfg_sam_name(ctx
->db_ctx
->lp_ctx
),
1071 lpcfg_sam_dnsname(ctx
->db_ctx
->lp_ctx
),
1077 if (!NT_STATUS_IS_OK(status
)) {
1078 DEBUG(1,("authsam_make_user_info_dc failed: %s\n",
1079 nt_errstr(status
)));
1080 talloc_free(tmp_ctx
);
1084 status
= auth_generate_session_info(tmp_ctx
,
1085 ctx
->db_ctx
->lp_ctx
,
1088 0, /* session_info_flags */
1089 &ctx
->session_info
);
1091 if (!NT_STATUS_IS_OK(status
)) {
1092 DEBUG(1,("auth_generate_session_info failed: %s\n",
1093 nt_errstr(status
)));
1094 talloc_free(tmp_ctx
);
1098 /* password is expected as UTF16 */
1100 if (!convert_string_talloc(tmp_ctx
, CH_UTF8
, CH_UTF16
,
1102 &password
.data
, &password
.length
)) {
1103 DEBUG(1,("convert_string_talloc failed\n"));
1104 talloc_free(tmp_ctx
);
1108 status
= samdb_kpasswd_change_password(tmp_ctx
,
1109 ctx
->db_ctx
->lp_ctx
,
1110 ctx
->db_ctx
->ev_ctx
,
1118 if (!NT_STATUS_IS_OK(status
)) {
1119 DEBUG(1,("samdb_kpasswd_change_password failed: %s\n",
1120 nt_errstr(status
)));
1121 code
= KADM5_PASS_Q_GENERIC
;
1122 krb5_set_error_message(ctx
->context
, code
, "%s", error_string
);
1126 if (!NT_STATUS_IS_OK(result
)) {
1127 code
= mit_samba_change_pwd_error(ctx
->context
,
1134 talloc_free(tmp_ctx
);
1139 void mit_samba_zero_bad_password_count(krb5_db_entry
*db_entry
)
1141 struct netr_SendToSamBase
*send_to_sam
= NULL
;
1142 struct samba_kdc_entry
*p
;
1143 struct ldb_dn
*domain_dn
;
1145 p
= (struct samba_kdc_entry
*)db_entry
->e_data
;
1147 domain_dn
= ldb_get_default_basedn(p
->kdc_db_ctx
->samdb
);
1149 authsam_logon_success_accounting(p
->kdc_db_ctx
->samdb
,
1154 /* TODO: RODC support */
1158 void mit_samba_update_bad_password_count(krb5_db_entry
*db_entry
)
1160 struct samba_kdc_entry
*p
;
1162 p
= (struct samba_kdc_entry
*)db_entry
->e_data
;
1164 authsam_update_bad_pwd_count(p
->kdc_db_ctx
->samdb
,
1166 ldb_get_default_basedn(p
->kdc_db_ctx
->samdb
));