diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
commit | 5209a846a9157e649fcdcb561f7eaf19c8c0e465 (patch) | |
tree | b0a7e52b5646c8eec182dbc391e7934b6804488c /source4/kdc | |
parent | 625359b2e266105022309df8985720108ecd6f67 (diff) | |
parent | 2ee8d29d22bcb1c350ab59d71b0aee548489bc9c (diff) | |
download | samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.gz samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.bz2 samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba into regsrv
Conflicts:
source4/lib/registry/ldb.c
source4/rpc_server/winreg/rpc_winreg.c
Diffstat (limited to 'source4/kdc')
-rw-r--r-- | source4/kdc/config.mk | 10 | ||||
-rw-r--r-- | source4/kdc/hdb-samba4.c (renamed from source4/kdc/hdb-ldb.c) | 93 | ||||
-rw-r--r-- | source4/kdc/kdc.c | 25 | ||||
-rw-r--r-- | source4/kdc/kpasswdd.c | 39 |
4 files changed, 102 insertions, 65 deletions
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk index 2c96e22cb3..dfd2879bd6 100644 --- a/source4/kdc/config.mk +++ b/source4/kdc/config.mk @@ -4,9 +4,9 @@ # Start SUBSYSTEM KDC [MODULE::KDC] INIT_FUNCTION = server_service_kdc_init -SUBSYSTEM = smbd +SUBSYSTEM = samba PRIVATE_DEPENDENCIES = \ - HEIMDAL_KDC HDB_LDB + HEIMDAL_KDC HDB_SAMBA4 # End SUBSYSTEM KDC ####################### @@ -14,7 +14,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o) ####################### # Start SUBSYSTEM KDC -[SUBSYSTEM::HDB_LDB] +[SUBSYSTEM::HDB_SAMBA4] CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb PRIVATE_DEPENDENCIES = \ LIBLDB auth_sam auth_sam_reply CREDENTIALS \ @@ -22,5 +22,5 @@ PRIVATE_DEPENDENCIES = \ # End SUBSYSTEM KDC ####################### -HDB_LDB_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-ldb.o pac-glue.o) -$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_LDB_OBJ_FILES:.o=.c))) +HDB_SAMBA4_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-samba4.o pac-glue.o) +$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_SAMBA4_OBJ_FILES:.o=.c))) diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-samba4.c index ef3a0bcb8a..b6a48e79d0 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-samba4.c @@ -41,7 +41,7 @@ #include "auth/auth.h" #include "auth/credentials/credentials.h" #include "auth/auth_sam.h" -#include "util/util_ldb.h" +#include "../lib/util/util_ldb.h" #include "dsdb/samdb/samdb.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_drsblobs.h" @@ -50,11 +50,11 @@ #include "param/param.h" #include "events/events.h" #include "kdc/kdc.h" -#include "lib/crypto/md4.h" +#include "../lib/crypto/md4.h" enum hdb_ldb_ent_type -{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, - HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY }; +{ HDB_SAMBA4_ENT_TYPE_CLIENT, HDB_SAMBA4_ENT_TYPE_SERVER, + HDB_SAMBA4_ENT_TYPE_KRBTGT, HDB_SAMBA4_ENT_TYPE_TRUST, HDB_SAMBA4_ENT_TYPE_ANY }; enum trust_direction { UNKNOWN = 0, @@ -115,26 +115,26 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h /* Account types - clear the invalid bit if it turns out to be valid */ if (userAccountControl & UF_NORMAL_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { flags.client = 1; } flags.invalid = 0; } if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { flags.client = 1; } flags.invalid = 0; } if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { flags.client = 1; } flags.invalid = 0; } if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { flags.client = 1; } flags.invalid = 0; @@ -186,7 +186,7 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h return flags; } -static int hdb_ldb_destrutor(struct hdb_ldb_private *private) +static int hdb_ldb_destructor(struct hdb_ldb_private *private) { hdb_entry_ex *entry_ex = private->entry_ex; free_hdb_entry(&entry_ex->entry); @@ -277,12 +277,11 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context, if (scpk) { DATA_BLOB blob; - blob = strhex_to_data_blob(scpk->data); + blob = strhex_to_data_blob(mem_ctx, scpk->data); if (!blob.data) { ret = ENOMEM; goto out; } - talloc_steal(mem_ctx, blob.data); /* we cannot use ndr_pull_struct_blob_all() here, as w2k and w2k3 add padding bytes */ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb, @@ -542,7 +541,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, private->iconv_convenience = lp_iconv_convenience(lp_ctx); private->netbios_name = lp_netbios_name(lp_ctx); - talloc_set_destructor(private, hdb_ldb_destrutor); + talloc_set_destructor(private, hdb_ldb_destructor); entry_ex->ctx = private; entry_ex->free_entry = hdb_ldb_free_entry; @@ -551,7 +550,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal))); - if (ent_type == HDB_LDB_ENT_TYPE_ANY && principal == NULL) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) { const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); if (!samAccountName) { krb5_set_error_string(context, "LDB_message2entry: no samAccountName present"); @@ -587,7 +586,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type); - if (ent_type == HDB_LDB_ENT_TYPE_KRBTGT) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) { entry_ex->entry.flags.invalid = 0; entry_ex->entry.flags.server = 1; entry_ex->entry.flags.forwardable = 1; @@ -631,7 +630,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry); } - if (ent_type != HDB_LDB_ENT_TYPE_KRBTGT) { + if (ent_type != HDB_SAMBA4_ENT_TYPE_KRBTGT) { NTTIME must_change_time = samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx, domain_dn, msg); @@ -728,7 +727,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, private->iconv_convenience = lp_iconv_convenience(lp_ctx); private->netbios_name = lp_netbios_name(lp_ctx); - talloc_set_destructor(private, hdb_ldb_destrutor); + talloc_set_destructor(private, hdb_ldb_destructor); entry_ex->ctx = private; entry_ex->free_entry = hdb_ldb_free_entry; @@ -757,13 +756,20 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, goto out; } - ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, + ndr_err = ndr_pull_struct_blob(password_val, mem_ctx, private->iconv_convenience, &password_blob, (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ret = EINVAL; goto out; } + entry_ex->entry.kvno = -1; + for (i=0; i < password_blob.count; i++) { + if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_VERSION) { + entry_ex->entry.kvno = password_blob.current->array[i].AuthInfo.version.version; + } + } + for (i=0; i < password_blob.count; i++) { if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, @@ -806,6 +812,8 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, entry_ex->entry.keys.len++; } + entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal))); + ret = copy_Principal(principal, entry_ex->entry.principal); if (ret) { krb5_clear_error_string(context); @@ -909,16 +917,16 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con } switch (ent_type) { - case HDB_LDB_ENT_TYPE_CLIENT: - case HDB_LDB_ENT_TYPE_TRUST: - case HDB_LDB_ENT_TYPE_ANY: + case HDB_SAMBA4_ENT_TYPE_CLIENT: + case HDB_SAMBA4_ENT_TYPE_TRUST: + case HDB_SAMBA4_ENT_TYPE_ANY: /* Can't happen */ return EINVAL; - case HDB_LDB_ENT_TYPE_KRBTGT: + case HDB_SAMBA4_ENT_TYPE_KRBTGT: filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", KRB5_TGS_NAME); break; - case HDB_LDB_ENT_TYPE_SERVER: + case HDB_SAMBA4_ENT_TYPE_SERVER: filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", short_princ_talloc); break; @@ -929,8 +937,8 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con return ENOMEM; } - lret = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, filter, princ_attrs, &res); - + lret = ldb_search(ldb_ctx, mem_ctx, &res, realm_dn, + LDB_SCOPE_SUBTREE, princ_attrs, "%s", filter); if (lret != LDB_SUCCESS) { DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); return HDB_ERR_NOENTRY; @@ -963,8 +971,9 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context return ENOMEM; } - lret = ldb_search(ldb_ctx, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, filter, attrs, &res); - + lret = ldb_search(ldb_ctx, mem_ctx, &res, + ldb_get_default_basedn(ldb_ctx), + LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (lret != LDB_SUCCESS) { DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); return HDB_ERR_NOENTRY; @@ -988,7 +997,7 @@ static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context struct ldb_result *cross_ref_res; struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx); - ret = ldb_search_exp_fmt(ldb_ctx, mem_ctx, &cross_ref_res, + ret = ldb_search(ldb_ctx, mem_ctx, &cross_ref_res, partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs, "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))", realm, realm); @@ -1074,7 +1083,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, } ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_CLIENT, + principal, HDB_SAMBA4_ENT_TYPE_CLIENT, msg[0], realm_ref_msg[0], entry_ex); return ret; } @@ -1135,7 +1144,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg); + principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, &msg); if (ret != 0) { krb5_warnx(context, "LDB_fetch: could not find principal in DB"); @@ -1144,10 +1153,10 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, } ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, + principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, msg[0], realm_ref_msg_1[0], entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed"); } return ret; @@ -1185,7 +1194,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, principal, direction, msg[0], entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "LDB_fetch: trust_message2entry failed"); } return ret; @@ -1264,7 +1273,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_SERVER, realm_dn, &msg); + principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, &msg); if (ret != 0) { return ret; @@ -1272,7 +1281,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, } ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_SERVER, + principal, HDB_SAMBA4_ENT_TYPE_SERVER, msg[0], realm_ref_msg[0], entry_ex); if (ret != 0) { krb5_warnx(context, "LDB_fetch: message2entry failed"); @@ -1357,7 +1366,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd if (priv->index < priv->count) { ret = LDB_message2entry(context, db, mem_ctx, - NULL, HDB_LDB_ENT_TYPE_ANY, + NULL, HDB_SAMBA4_ENT_TYPE_ANY, priv->msgs[priv->index++], priv->realm_ref_msgs[0], entry); } else { @@ -1432,9 +1441,9 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs); - lret = ldb_search(ldb_ctx, realm_dn, - LDB_SCOPE_SUBTREE, "(objectClass=user)", - user_attrs, &res); + lret = ldb_search(ldb_ctx, priv, &res, + realm_dn, LDB_SCOPE_SUBTREE, user_attrs, + "(objectClass=user)"); if (lret != LDB_SUCCESS) { talloc_free(priv); @@ -1475,7 +1484,7 @@ static krb5_error_code LDB_destroy(krb5_context context, HDB *db) * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb * code */ -NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx, +NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, struct event_context *ev_ctx, struct loadparm_context *lp_ctx, krb5_context context, struct HDB **db, const char *arg) @@ -1535,12 +1544,12 @@ NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg) +krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg) { NTSTATUS nt_status; /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */ - nt_status = kdc_hdb_ldb_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, - context, db, arg); + nt_status = kdc_hdb_samba4_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, + context, db, arg); if (NT_STATUS_IS_OK(nt_status)) { return 0; diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index b7009b030f..45fa803d04 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -29,7 +29,7 @@ #include "lib/events/events.h" #include "lib/socket/socket.h" #include "system/network.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "lib/messaging/irpc.h" #include "lib/stream/packet.h" #include "librpc/gen_ndr/samr.h" @@ -484,7 +484,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address, /* within the kdc task we want to be a single process, so ask for the single process model ops and pass these to the stream_setup_socket() call. */ - model_ops = process_model_byname("single"); + model_ops = process_model_startup(kdc->task->event_ctx, "single"); if (!model_ops) { DEBUG(0,("Can't find 'single' process model_ops\n")); talloc_free(kdc_socket); @@ -584,13 +584,11 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg, return NT_STATUS_INVALID_PARAMETER; } -#if 0 - /* Windows does not check this */ if (pac_validate.MessageType != 3) { /* We don't implement any other message types - such as certificate validation - yet */ return NT_STATUS_INVALID_PARAMETER; } -#endif + if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength) || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) { @@ -659,6 +657,11 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg, } +static struct hdb_method hdb_samba4 = { + .interface_version = HDB_INTERFACE_VERSION, + .prefix = "samba4:", + .create = hdb_samba4_create +}; /* startup the kdc task @@ -726,7 +729,7 @@ static void kdc_task_init(struct task_server *task) } kdc->config->num_db = 1; - status = kdc_hdb_ldb_create(kdc, task->event_ctx, task->lp_ctx, + status = kdc_hdb_samba4_create(kdc, task->event_ctx, task->lp_ctx, kdc->smb_krb5_context->krb5_context, &kdc->config->db[0], NULL); if (!NT_STATUS_IS_OK(status)) { @@ -734,6 +737,16 @@ static void kdc_task_init(struct task_server *task) return; } + + /* Register hdb-samba4 hooks */ + ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, + PLUGIN_TYPE_DATA, "hdb", + &hdb_samba4); + if(ret) { + task_server_terminate(task, "kdc: failed to register hdb keytab"); + return; + } + ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops); if(ret) { task_server_terminate(task, "kdc: failed to register hdb keytab"); diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c index 603332e69e..1336b0157e 100644 --- a/source4/kdc/kpasswdd.c +++ b/source4/kdc/kpasswdd.c @@ -25,7 +25,7 @@ #include "lib/events/events.h" #include "lib/socket/socket.h" #include "system/network.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "lib/ldb/include/ldb.h" #include "auth/gensec/gensec.h" #include "auth/credentials/credentials.h" @@ -175,7 +175,7 @@ static bool kpasswd_make_pwchange_reply(struct kdc_server *kdc, static bool kpasswdd_change_password(struct kdc_server *kdc, TALLOC_CTX *mem_ctx, struct auth_session_info *session_info, - const char *password, + const DATA_BLOB *password, DATA_BLOB *reply) { NTSTATUS status; @@ -219,6 +219,8 @@ static bool kpasswd_process_request(struct kdc_server *kdc, DATA_BLOB *reply) { struct auth_session_info *session_info; + ssize_t pw_len; + if (!NT_STATUS_IS_OK(gensec_session_info(gensec_security, &session_info))) { return kpasswdd_make_error_reply(kdc, mem_ctx, @@ -230,12 +232,20 @@ static bool kpasswd_process_request(struct kdc_server *kdc, switch (version) { case KRB5_KPASSWD_VERS_CHANGEPW: { - char *password = talloc_strndup(mem_ctx, (const char *)input->data, input->length); - if (!password) { + DATA_BLOB password; + pw_len = convert_string_talloc(mem_ctx, lp_iconv_convenience(kdc->task->lp_ctx), + CH_UTF8, CH_UTF16, + (const char *)input->data, + input->length, + (void **)&password.data); + + if (pw_len == -1) { return false; } + password.length = pw_len; + return kpasswdd_change_password(kdc, mem_ctx, session_info, - password, reply); + &password, reply); break; } case KRB5_KPASSWD_VERS_SETPW: @@ -248,7 +258,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc, krb5_context context = kdc->smb_krb5_context->krb5_context; ChangePasswdDataMS chpw; - char *password; + DATA_BLOB password; krb5_principal principal; char *set_password_on_princ; @@ -271,13 +281,18 @@ static bool kpasswd_process_request(struct kdc_server *kdc, reply); } - password = talloc_strndup(mem_ctx, - (const char *)chpw.newpasswd.data, - chpw.newpasswd.length); - if (!password) { + pw_len = convert_string_talloc(mem_ctx, lp_iconv_convenience(kdc->task->lp_ctx), + CH_UTF8, CH_UTF16, + (const char *)chpw.newpasswd.data, + chpw.newpasswd.length, + (void **)&password.data); + if (pw_len == -1) { free_ChangePasswdDataMS(&chpw); return false; } + + password.length = pw_len; + if ((chpw.targname && !chpw.targrealm) || (!chpw.targname && chpw.targrealm)) { return kpasswdd_make_error_reply(kdc, mem_ctx, @@ -306,7 +321,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc, } else { free_ChangePasswdDataMS(&chpw); return kpasswdd_change_password(kdc, mem_ctx, session_info, - password, reply); + &password, reply); } free_ChangePasswdDataMS(&chpw); @@ -371,7 +386,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc, /* Admin password set */ status = samdb_set_password(samdb, mem_ctx, set_password_on_dn, NULL, - msg, password, NULL, NULL, + msg, &password, NULL, NULL, false, /* this is not a user password change */ &reject_reason, &dominfo); } |