summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/kdc/kpasswd-heimdal.c59
-rw-r--r--source4/kdc/kpasswd-helper.c74
-rw-r--r--source4/kdc/kpasswd-helper.h30
-rwxr-xr-xsource4/kdc/wscript_build2
4 files changed, 122 insertions, 43 deletions
diff --git a/source4/kdc/kpasswd-heimdal.c b/source4/kdc/kpasswd-heimdal.c
index 85d173008c0..af8187b4765 100644
--- a/source4/kdc/kpasswd-heimdal.c
+++ b/source4/kdc/kpasswd-heimdal.c
@@ -33,31 +33,7 @@
#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,
- TALLOC_CTX *mem_ctx,
- uint16_t result_code,
- const char *error_string,
- DATA_BLOB *error_blob)
-{
- char *error_string_utf8;
- size_t len;
-
- DEBUG(result_code ? 3 : 10, ("kpasswdd: %s\n", error_string));
-
- if (!push_utf8_talloc(mem_ctx, &error_string_utf8, error_string, &len)) {
- return false;
- }
-
- *error_blob = data_blob_talloc(mem_ctx, NULL, 2 + len + 1);
- if (!error_blob->data) {
- return false;
- }
- RSSVAL(error_blob->data, 0, result_code);
- memcpy(error_blob->data + 2, error_string_utf8, len + 1);
- return true;
-}
+#include "kdc/kpasswd-helper.h"
/* Return true if there is a valid error packet formed in the error_blob */
static bool kpasswdd_make_unauth_error_reply(struct kdc_server *kdc,
@@ -70,7 +46,7 @@ static bool kpasswdd_make_unauth_error_reply(struct kdc_server *kdc,
int kret;
DATA_BLOB error_bytes;
krb5_data k5_error_bytes, k5_error_blob;
- ret = kpasswdd_make_error_reply(kdc, mem_ctx, result_code, error_string,
+ ret = kpasswd_make_error_reply(mem_ctx, result_code, error_string,
&error_bytes);
if (!ret) {
return false;
@@ -104,13 +80,13 @@ static bool kpasswd_make_pwchange_reply(struct kdc_server *kdc,
DATA_BLOB *error_blob)
{
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_ACCESSDENIED,
"No such user when changing password",
error_blob);
}
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_ACCESSDENIED,
"Not permitted to change password",
error_blob);
@@ -133,19 +109,19 @@ static bool kpasswd_make_pwchange_reply(struct kdc_server *kdc,
reject_string = "Password change rejected, password changes may not be permitted on this account, or the minimum password age may not have elapsed.";
break;
}
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_SOFTERROR,
reject_string,
error_blob);
}
if (!NT_STATUS_IS_OK(status)) {
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_HARDERROR,
talloc_asprintf(mem_ctx, "failed to set password: %s", nt_errstr(status)),
error_blob);
}
- return kpasswdd_make_error_reply(kdc, mem_ctx, KRB5_KPASSWD_SUCCESS,
+ return kpasswd_make_error_reply(mem_ctx, KRB5_KPASSWD_SUCCESS,
"Password changed",
error_blob);
}
@@ -179,8 +155,7 @@ static bool kpasswdd_change_password(struct kdc_server *kdc,
&error_string,
&result);
if (!NT_STATUS_IS_OK(status)) {
- return kpasswdd_make_error_reply(kdc,
- mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_ACCESSDENIED,
error_string,
reply);
@@ -207,7 +182,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
if (!NT_STATUS_IS_OK(gensec_session_info(gensec_security,
mem_ctx,
&session_info))) {
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_HARDERROR,
"gensec_session_info failed!",
reply);
@@ -251,7 +226,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
ret = decode_ChangePasswdDataMS(input->data, input->length,
&chpw, &len);
if (ret) {
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_MALFORMED,
"failed to decode password change structure",
reply);
@@ -271,7 +246,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
if ((chpw.targname && !chpw.targrealm)
|| (!chpw.targname && chpw.targrealm)) {
free_ChangePasswdDataMS(&chpw);
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_MALFORMED,
"Realm and principal must be both present, or neither present",
reply);
@@ -283,7 +258,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
*chpw.targrealm, 0);
if (ret) {
free_ChangePasswdDataMS(&chpw);
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_MALFORMED,
"failed to get principal",
reply);
@@ -291,7 +266,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
if (copy_PrincipalName(chpw.targname, &principal->name)) {
free_ChangePasswdDataMS(&chpw);
krb5_free_principal(context, principal);
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_MALFORMED,
"failed to extract principal to set",
reply);
@@ -312,7 +287,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
if (krb5_unparse_name_short(context, principal, &set_password_on_princ) != 0) {
krb5_free_principal(context, principal);
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_MALFORMED,
"krb5_unparse_name failed!",
reply);
@@ -320,7 +295,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
} else {
if (krb5_unparse_name(context, principal, &set_password_on_princ) != 0) {
krb5_free_principal(context, principal);
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_MALFORMED,
"krb5_unparse_name failed!",
reply);
@@ -331,7 +306,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
samdb = samdb_connect(mem_ctx, kdc->task->event_ctx, kdc->task->lp_ctx, session_info, 0);
if (!samdb) {
free(set_password_on_princ);
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_HARDERROR,
"Unable to open database!",
reply);
@@ -399,7 +374,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
reply);
}
default:
- return kpasswdd_make_error_reply(kdc, mem_ctx,
+ return kpasswd_make_error_reply(mem_ctx,
KRB5_KPASSWD_BAD_VERSION,
talloc_asprintf(mem_ctx,
"Protocol version %u not supported",
diff --git a/source4/kdc/kpasswd-helper.c b/source4/kdc/kpasswd-helper.c
new file mode 100644
index 00000000000..31195d907d5
--- /dev/null
+++ b/source4/kdc/kpasswd-helper.c
@@ -0,0 +1,74 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Samba kpasswd implementation
+
+ Copyright (c) 2005 Andrew Bartlett <abartlet@samba.org>
+ Copyright (c) 2016 Andreas Schneider <asn@samba.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/kerberos.h"
+#include "kdc/kpasswd-helper.h"
+
+bool kpasswd_make_error_reply(TALLOC_CTX *mem_ctx,
+ krb5_error_code error_code,
+ const char *error_string,
+ DATA_BLOB *error_data)
+{
+ bool ok;
+ char *s;
+ size_t slen;
+
+ if (error_code == 0) {
+ DBG_DEBUG("kpasswd reply - %s\n", error_string);
+ } else {
+ DBG_INFO("kpasswd reply - %s\n", error_string);
+ }
+
+ ok = push_utf8_talloc(mem_ctx, &s, error_string, &slen);
+ if (!ok) {
+ return false;
+ }
+
+ /*
+ * The string 's' has two terminating nul-bytes which are also
+ * reflected by 'slen'. Normally Kerberos doesn't expect that strings
+ * are nul-terminated, but Heimdal does!
+ */
+#ifndef SAMBA4_USES_HEIMDAL
+ if (slen < 2) {
+ return false;
+ }
+ slen -= 2;
+#endif
+ if (2 + slen < slen) {
+ return false;
+ }
+ error_data->length = 2 + slen;
+ error_data->data = talloc_size(mem_ctx, error_data->length);
+ if (error_data->data == NULL) {
+ talloc_free(s);
+ return false;
+ }
+
+ RSSVAL(error_data->data, 0, error_code);
+ memcpy(error_data->data + 2, s, slen);
+
+ talloc_free(s);
+
+ return true;
+}
diff --git a/source4/kdc/kpasswd-helper.h b/source4/kdc/kpasswd-helper.h
new file mode 100644
index 00000000000..74a508ca70f
--- /dev/null
+++ b/source4/kdc/kpasswd-helper.h
@@ -0,0 +1,30 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Samba kpasswd implementation
+
+ Copyright (c) 2016 Andreas Schneider <asn@samba.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _KPASSWD_HELPER_H
+#define _KPASSWD_HELPER_H
+
+bool kpasswd_make_error_reply(TALLOC_CTX *mem_ctx,
+ krb5_error_code error_code,
+ const char *error_string,
+ DATA_BLOB *error_data);
+
+#endif /* _KPASSWD_HELPER_H */
diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
index 230118cdd60..170cc349927 100755
--- a/source4/kdc/wscript_build
+++ b/source4/kdc/wscript_build
@@ -7,7 +7,7 @@ else:
kdc_include = getattr(bld.env, "CPPPATH_KDC")
bld.SAMBA_MODULE('service_kdc',
- source='kdc-heimdal.c kpasswd-heimdal.c',
+ source='kdc-heimdal.c kpasswd-helper.c kpasswd-heimdal.c',
subsystem='service',
init_function='server_service_kdc_init',
deps='''