diff --git a/source4/kdc/kpasswd_glue.c b/source4/kdc/kpasswd_glue.c new file mode 100644 index 00000000000..b12a2093314 --- /dev/null +++ b/source4/kdc/kpasswd_glue.c @@ -0,0 +1,112 @@ +/* + Unix SMB/CIFS implementation. + + kpasswd Server implementation + + Copyright (C) Andrew Bartlett 2005 + Copyright (C) Andrew Tridgell 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "dsdb/samdb/samdb.h" +#include "../lib/util/util_ldb.h" +#include "libcli/security/security.h" +#include "dsdb/common/util.h" +#include "auth/auth.h" +#include "kdc/kpasswd_glue.h" + +/* + A user password change + + Return true if there is a valid error packet (or success) formed in + the error_blob +*/ +NTSTATUS samdb_kpasswd_change_password(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct tevent_context *event_ctx, + struct ldb_context *samdb, + struct auth_session_info *session_info, + const DATA_BLOB *password, + enum samPwdChangeReason *reject_reason, + struct samr_DomInfo1 **dominfo, + const char **error_string, + NTSTATUS *result) +{ + struct samr_Password *oldLmHash, *oldNtHash; + const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL }; + struct ldb_message *msg; + NTSTATUS status; + int ret; + + /* Fetch the old hashes to get the old password in order to perform + * the password change operation. Naturally it would be much better to + * have a password hash from an authentication around but this doesn't + * seem to be the case here. */ + ret = dsdb_search_one(samdb, mem_ctx, &msg, ldb_get_default_basedn(samdb), + LDB_SCOPE_SUBTREE, + attrs, + DSDB_SEARCH_NO_GLOBAL_CATALOG, + "(&(objectClass=user)(sAMAccountName=%s))", + session_info->info->account_name); + if (ret != LDB_SUCCESS) { + *error_string = "No such user when changing password"; + return NT_STATUS_NO_SUCH_USER; + } + + /* + * No need to check for password lockout here, the KDC will + * have done that when issuing the ticket, which is not based + * on the user's password + */ + status = samdb_result_passwords_no_lockout(mem_ctx, lp_ctx, msg, + &oldLmHash, &oldNtHash); + if (!NT_STATUS_IS_OK(status)) { + *error_string = "Not permitted to change password"; + return NT_STATUS_ACCESS_DENIED; + } + + /* Start a SAM with user privileges for the password change */ + samdb = samdb_connect(mem_ctx, event_ctx, lp_ctx, + session_info, 0); + if (!samdb) { + *error_string = "Failed to open samdb"; + return NT_STATUS_ACCESS_DENIED; + } + + DEBUG(3, ("Changing password of %s\\%s (%s)\n", + session_info->info->domain_name, + session_info->info->account_name, + dom_sid_string(mem_ctx, &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]))); + + /* Performs the password change */ + status = samdb_set_password_sid(samdb, + mem_ctx, + &session_info->security_token->sids[PRIMARY_USER_SID_INDEX], + NULL, + password, + NULL, + NULL, + oldLmHash, + oldNtHash, /* this is a user password change */ + reject_reason, + dominfo); + if (!NT_STATUS_IS_OK(status)) { + *error_string = nt_errstr(status); + } + *result = status; + + return NT_STATUS_OK; +} diff --git a/source4/kdc/kpasswd_glue.h b/source4/kdc/kpasswd_glue.h new file mode 100644 index 00000000000..4d5c6c4d895 --- /dev/null +++ b/source4/kdc/kpasswd_glue.h @@ -0,0 +1,32 @@ +/* + Unix SMB/CIFS implementation. + + kpasswd Server implementation + + Copyright (C) Andrew Bartlett 2005 + Copyright (C) Andrew Tridgell 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +NTSTATUS samdb_kpasswd_change_password(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct tevent_context *event_ctx, + struct ldb_context *samdb, + struct auth_session_info *session_info, + const DATA_BLOB *password, + enum samPwdChangeReason *reject_reason, + struct samr_DomInfo1 **dominfo, + const char **error_string, + NTSTATUS *result); diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c index e42e346681b..b686e2be3b8 100644 --- a/source4/kdc/kpasswdd.c +++ b/source4/kdc/kpasswdd.c @@ -31,6 +31,7 @@ #include "param/param.h" #include "kdc/kdc-glue.h" #include "dsdb/common/util.h" +#include "kdc/kpasswd_glue.h" /* Return true if there is a valid error packet formed in the error_blob */ static bool kpasswdd_make_error_reply(struct kdc_server *kdc, @@ -156,73 +157,35 @@ static bool kpasswdd_change_password(struct kdc_server *kdc, DATA_BLOB *reply) { NTSTATUS status; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; enum samPwdChangeReason reject_reason; struct samr_DomInfo1 *dominfo; - struct samr_Password *oldLmHash, *oldNtHash; - struct ldb_context *samdb; - const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL }; - struct ldb_message *msg; - int ret; + const char *error_string; - /* Fetch the old hashes to get the old password in order to perform - * the password change operation. Naturally it would be much better to - * have a password hash from an authentication around but this doesn't - * seem to be the case here. */ - ret = dsdb_search_one(kdc->samdb, mem_ctx, &msg, ldb_get_default_basedn(kdc->samdb), - LDB_SCOPE_SUBTREE, - attrs, - DSDB_SEARCH_NO_GLOBAL_CATALOG, - "(&(objectClass=user)(sAMAccountName=%s))", - session_info->info->account_name); - if (ret != LDB_SUCCESS) { - return kpasswdd_make_error_reply(kdc, mem_ctx, - KRB5_KPASSWD_ACCESSDENIED, - "No such user when changing password", - reply); - } - - /* - * No need to check for password lockout here, the KDC will - * have done that when issuing the ticket, which is not based - * on the user's password - */ - status = samdb_result_passwords_no_lockout(mem_ctx, kdc->task->lp_ctx, msg, - &oldLmHash, &oldNtHash); + status = samdb_kpasswd_change_password(mem_ctx, + kdc->task->lp_ctx, + kdc->task->event_ctx, + kdc->samdb, + session_info, + password, + &reject_reason, + &dominfo, + &error_string, + &result); if (!NT_STATUS_IS_OK(status)) { - return kpasswdd_make_error_reply(kdc, mem_ctx, - KRB5_KPASSWD_ACCESSDENIED, - "Not permitted to change password", - reply); + return kpasswdd_make_error_reply(kdc, + mem_ctx, + KRB5_KPASSWD_ACCESSDENIED, + error_string, + reply); } - /* Start a SAM with user privileges for the password change */ - samdb = samdb_connect(mem_ctx, kdc->task->event_ctx, kdc->task->lp_ctx, - session_info, 0); - if (!samdb) { - return kpasswdd_make_error_reply(kdc, mem_ctx, - KRB5_KPASSWD_HARDERROR, - "Failed to open samdb", - reply); - } - - DEBUG(3, ("Changing password of %s\\%s (%s)\n", - session_info->info->domain_name, - session_info->info->account_name, - dom_sid_string(mem_ctx, &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]))); - - /* Performs the password change */ - status = samdb_set_password_sid(samdb, mem_ctx, - &session_info->security_token->sids[PRIMARY_USER_SID_INDEX], - NULL, password, NULL, NULL, - oldLmHash, oldNtHash, /* this is a user password change */ - &reject_reason, - &dominfo); - return kpasswd_make_pwchange_reply(kdc, mem_ctx, - status, + return kpasswd_make_pwchange_reply(kdc, + mem_ctx, + result, reject_reason, dominfo, reply); - } static bool kpasswd_process_request(struct kdc_server *kdc, diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build index 8f1ba82ef7c..0871404d030 100755 --- a/source4/kdc/wscript_build +++ b/source4/kdc/wscript_build @@ -21,10 +21,10 @@ bld.SAMBA_MODULE('service_kdc', samba_server_gensec PAC_GLUE KDC-GLUE + KPASSWD_GLUE ''', internal_module=False) - bld.SAMBA_LIBRARY('HDB_SAMBA4', source='hdb-samba4.c hdb-samba4-plugin.c', deps='ldb auth4_sam auth_sam_reply samba-credentials hdb db-glue samba-hostconfig com_err', @@ -79,6 +79,11 @@ bld.SAMBA_LIBRARY('db-glue', includes=kdc_include, ) +bld.SAMBA_SUBSYSTEM('KPASSWD_GLUE', + source='kpasswd_glue.c', + includes=kdc_include, + deps='ldb com_err') + bld.SAMBA_SUBSYSTEM('MIT_SAMBA', source='mit_samba.c', deps='''