[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Sun Sep 11 04:46:03 UTC 2016


The branch, master has been updated
       via  dd8553b s4-kdc: Move kpasswd_make_pwchange_reply() to a helper file
       via  f9de99c s4-kdc: Move kpasswd_make_error_reply() to a helper file
       via  2f36e6d krb5_wrap: Fix smb_krb5_mk_error() with MIT Kerberos
       via  5ae447e testprogs: Test only what the Heimdal kpasswd test should test
       via  e528919 testprogs: Make test_passwords.sh a Heimdal kpasswd test
       via  13fdeb0 testprogs: Add a new test_password_settings.sh script
       via  4899ece testprogs: Add a common test_smbclient_expect_failure() function
       via  b3e324a heimdal: Fix reauthentication after password change
      from  c855a37 winbindd: Remove unused enum ent_type

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit dd8553b54b7e6fad207ec09cffe039b844493755
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Sep 7 14:57:59 2016 +0200

    s4-kdc: Move kpasswd_make_pwchange_reply() to a helper file
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Sun Sep 11 06:45:00 CEST 2016 on sn-devel-144

commit f9de99ce9b59d9052d9ebe22332f76f66857476f
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Sep 7 14:47:31 2016 +0200

    s4-kdc: Move kpasswd_make_error_reply() to a helper file
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2f36e6d3ec1907b32275a769667cc7b791efd7de
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Sep 2 11:54:48 2016 +0200

    krb5_wrap: Fix smb_krb5_mk_error() with MIT Kerberos
    
    The server principal is required, so if not set create an obscure one.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5ae447e102d5c29688f759ce19bca1689c5924f0
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Sep 6 09:31:41 2016 +0200

    testprogs: Test only what the Heimdal kpasswd test should test
    
    The test_password_settings.sh test does test using different password
    settings and is not specific to the kpasswd implementation. This
    test tests the kpasswd service.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e5289191a994af4ad2def422ec57521eb2da2f90
Author: Andreas Schneider <asn at samba.org>
Date:   Mon Sep 5 15:18:07 2016 +0200

    testprogs: Make test_passwords.sh a Heimdal kpasswd test
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 13fdeb0a98c3e0d00fe227d6fa17d4770bc7468c
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Sep 6 08:55:43 2016 +0200

    testprogs: Add a new test_password_settings.sh script
    
    This test is not Kerberos implementation specific.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 4899ece472847a6e207098e4472d0e2515081fe0
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Sep 6 08:56:47 2016 +0200

    testprogs: Add a common test_smbclient_expect_failure() function
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b3e324aad53a6b4adf0ece58c1b8bd9eed2cd48c
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Sep 7 17:17:08 2016 +0200

    heimdal: Fix reauthentication after password change
    
    If the KDC requires a password change kinit will ask after the initial
    authentication for a new password. After the password has been changed
    it does reauthentication and for that it needs to use the new password
    we just set.
    
    It is needed for the a new kpasswd service test.
    
    This is already fixed upstream with:
        911c99375741281adae305f6ec3a3317023eba3e
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/krb5_wrap/krb5_samba.c                         |  52 +++-
 lib/krb5_wrap/krb5_samba.h                         |   2 +
 selftest/knownfail                                 |   1 -
 source4/heimdal/lib/krb5/init_creds_pw.c           |   7 +-
 source4/kdc/kdc-server.c                           |   2 +
 source4/kdc/kpasswd-heimdal.c                      | 114 ++-------
 source4/kdc/kpasswd-helper.c                       | 158 ++++++++++++
 .../kdc/kpasswd-helper.h                           |  23 +-
 source4/kdc/wscript_build                          |   2 +-
 source4/selftest/tests.py                          |   3 +-
 testprogs/blackbox/common_test_fns.inc             |  18 ++
 testprogs/blackbox/test_kpasswd_heimdal.sh         | 217 +++++++++++++++++
 testprogs/blackbox/test_password_settings.sh       | 211 ++++++++++++++++
 testprogs/blackbox/test_passwords.sh               | 265 ---------------------
 14 files changed, 690 insertions(+), 385 deletions(-)
 create mode 100644 source4/kdc/kpasswd-helper.c
 copy libcli/auth/schannel_proto.h => source4/kdc/kpasswd-helper.h (57%)
 create mode 100755 testprogs/blackbox/test_kpasswd_heimdal.sh
 create mode 100755 testprogs/blackbox/test_password_settings.sh
 delete mode 100755 testprogs/blackbox/test_passwords.sh


Changeset truncated at 500 lines:

diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index dcd6185..28884d9 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -206,6 +206,8 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
 				  krb5_error_code error_code,
 				  const char *e_text,
 				  krb5_data *e_data,
+				  const krb5_principal client,
+				  const krb5_principal server,
 				  krb5_data *enc_err)
 {
 	krb5_error_code code = EINVAL;
@@ -214,27 +216,59 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
 			     error_code,
 			     e_text,
 			     e_data,
-			     NULL, /* client */
-			     NULL, /* server */
+			     client,
+			     server,
 			     NULL, /* client_time */
 			     NULL, /* client_usec */
 			     enc_err);
 #else
-	krb5_error dec_err = {
-		.error = error_code,
-	};
+	krb5_principal unspec_server = NULL;
+	krb5_error errpkt;
 
+	errpkt.ctime = 0;
+	errpkt.cusec = 0;
+
+	code = krb5_us_timeofday(context,
+				 &errpkt.stime,
+				 &errpkt.susec);
+	if (code != 0) {
+		return code;
+	}
+
+	errpkt.error = error_code;
+
+	errpkt.text.length = 0;
 	if (e_text != NULL) {
-		dec_err.text.length = strlen(e_text);
-		dec_err.text.data = discard_const_p(char, e_text);
+		errpkt.text.length = strlen(e_text);
+		errpkt.text.data = discard_const_p(char, e_text);
 	}
+
+	errpkt.e_data.magic = KV5M_DATA;
+	errpkt.e_data.length = 0;
+	errpkt.e_data.data = NULL;
 	if (e_data != NULL) {
-		dec_err.e_data = *e_data;
+		errpkt.e_data = *e_data;
+	}
+
+	errpkt.client = client;
+
+	if (server != NULL) {
+		errpkt.server = server;
+	} else {
+		code = smb_krb5_make_principal(context,
+					       &unspec_server,
+					       "<unspecified realm>",
+					       NULL);
+		if (code != 0) {
+			return code;
+		}
+		errpkt.server = unspec_server;
 	}
 
 	code = krb5_mk_error(context,
-			     &dec_err,
+			     &errpkt,
 			     enc_err);
+	krb5_free_principal(context, unspec_server);
 #endif
 	return code;
 }
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 64a04b3..71e81ea 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -169,6 +169,8 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
 				  krb5_error_code error_code,
 				  const char *e_text,
 				  krb5_data *e_data,
+				  const krb5_principal client,
+				  const krb5_principal server,
 				  krb5_data *enc_err);
 
 krb5_error_code smb_krb5_get_allowed_etypes(krb5_context context,
diff --git a/selftest/knownfail b/selftest/knownfail
index 2f6a66b..1051518 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -142,7 +142,6 @@
 ^samba4.smb2.getinfo.qsec_buffercheck # S4 does not do the BUFFER_TOO_SMALL thingy
 ^samba4.ntvfs.cifs.krb5.base.createx_access.createx_access\(.*\)$
 ^samba4.rpc.lsa.forest.trust #Not fully provided by Samba4
-^samba4.blackbox.kinit\(.*\).kinit with user password for expired password\(.*\) # We need to work out why this fails only during the pw change
 ^samba4.blackbox.upgradeprovision.alpha13.ldapcmp_sd\(none\) # Due to something rewriting the NT ACL on DNS objects
 ^samba4.blackbox.upgradeprovision.alpha13.ldapcmp_full_sd\(none\) # Due to something rewriting the NT ACL on DNS objects
 ^samba4.blackbox.upgradeprovision.release-4-0-0.ldapcmp_sd\(none\) # Due to something rewriting the NT ACL on DNS objects
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index b6c0a64..a66ad35 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -1990,6 +1990,7 @@ krb5_get_init_creds_password(krb5_context context,
 {
     krb5_init_creds_context ctx;
     char buf[BUFSIZ];
+    char buf2[BUFSIZ];
     krb5_error_code ret;
     int chpw = 0;
 
@@ -2041,8 +2042,6 @@ krb5_get_init_creds_password(krb5_context context,
 
 
     if (ret == KRB5KDC_ERR_KEY_EXPIRED && chpw == 0) {
-	char buf2[1024];
-
 	/* try to avoid recursion */
 	if (in_tkt_service != NULL && strcmp(in_tkt_service, "kadmin/changepw") == 0)
 	   goto out;
@@ -2055,13 +2054,14 @@ krb5_get_init_creds_password(krb5_context context,
 			       client,
 			       ctx->password,
 			       buf2,
-			       sizeof(buf),
+			       sizeof(buf2),
 			       prompter,
 			       data,
 			       options);
 	if (ret)
 	    goto out;
 	chpw = 1;
+	password = buf2;
 	krb5_init_creds_free(context, ctx);
 	goto again;
     }
@@ -2074,6 +2074,7 @@ krb5_get_init_creds_password(krb5_context context,
 	krb5_init_creds_free(context, ctx);
 
     memset(buf, 0, sizeof(buf));
+    memset(buf2, 0, sizeof(buf2));
     return ret;
 }
 
diff --git a/source4/kdc/kdc-server.c b/source4/kdc/kdc-server.c
index 7854f49..13e338d 100644
--- a/source4/kdc/kdc-server.c
+++ b/source4/kdc/kdc-server.c
@@ -83,6 +83,8 @@ static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server *kdc,
 				 KRB5KDC_ERR_SVC_UNAVAILABLE,
 				 NULL,
 				 NULL,
+				 NULL,
+				 NULL,
 				 &enc_error);
 	if (code != 0) {
 		DBG_WARNING("Unable to form krb5 error reply\n");
diff --git a/source4/kdc/kpasswd-heimdal.c b/source4/kdc/kpasswd-heimdal.c
index ff2f6af..49fc755 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;
@@ -81,6 +57,8 @@ static bool kpasswdd_make_unauth_error_reply(struct kdc_server *kdc,
 				 result_code,
 				 NULL,
 				 &k5_error_bytes,
+				 NULL,
+				 NULL,
 				 &k5_error_blob);
 	if (kret) {
 		return false;
@@ -94,60 +72,6 @@ static bool kpasswdd_make_unauth_error_reply(struct kdc_server *kdc,
 	return true;
 }
 
-static bool kpasswd_make_pwchange_reply(struct kdc_server *kdc,
-					TALLOC_CTX *mem_ctx,
-					NTSTATUS status,
-					enum samPwdChangeReason reject_reason,
-					struct samr_DomInfo1 *dominfo,
-					DATA_BLOB *error_blob)
-{
-	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
-		return kpasswdd_make_error_reply(kdc, 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,
-						KRB5_KPASSWD_ACCESSDENIED,
-						"Not permitted to change password",
-						error_blob);
-	}
-	if (dominfo && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
-		const char *reject_string;
-		switch (reject_reason) {
-		case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
-			reject_string = talloc_asprintf(mem_ctx, "Password too short, password must be at least %d characters long.",
-							dominfo->min_password_length);
-			break;
-		case SAM_PWD_CHANGE_NOT_COMPLEX:
-			reject_string = "Password does not meet complexity requirements";
-			break;
-		case SAM_PWD_CHANGE_PWD_IN_HISTORY:
-			reject_string = talloc_asprintf(mem_ctx, "Password is already in password history.  New password must not match any of your %d previous passwords.",
-							dominfo->password_history_length);
-			break;
-		default:
-			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,
-						KRB5_KPASSWD_SOFTERROR,
-						reject_string,
-						error_blob);
-	}
-	if (!NT_STATUS_IS_OK(status)) {
-		return kpasswdd_make_error_reply(kdc, 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,
-					"Password changed",
-					error_blob);
-}
-
 /*
    A user password change
 
@@ -177,15 +101,13 @@ 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);
 	}
 
-	return kpasswd_make_pwchange_reply(kdc,
-					   mem_ctx,
+	return kpasswd_make_pwchange_reply(mem_ctx,
 					   result,
 					   reject_reason,
 					   dominfo,
@@ -205,7 +127,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);
@@ -249,7 +171,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);
@@ -269,7 +191,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);
@@ -281,7 +203,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);
@@ -289,7 +211,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);
@@ -310,7 +232,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);
@@ -318,7 +240,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);
@@ -329,7 +251,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);
@@ -344,7 +266,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
 		if (ret != LDB_SUCCESS) {
 			free(set_password_on_princ);
 			status = NT_STATUS_TRANSACTION_ABORTED;
-			return kpasswd_make_pwchange_reply(kdc, mem_ctx,
+			return kpasswd_make_pwchange_reply(mem_ctx,
 							   status,
 							   SAM_PWD_CHANGE_NO_ERROR,
 							   NULL,
@@ -363,7 +285,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
 		free(set_password_on_princ);
 		if (!NT_STATUS_IS_OK(status)) {
 			ldb_transaction_cancel(samdb);
-			return kpasswd_make_pwchange_reply(kdc, mem_ctx,
+			return kpasswd_make_pwchange_reply(mem_ctx,
 							   status,
 							   SAM_PWD_CHANGE_NO_ERROR,
 							   NULL,
@@ -390,14 +312,14 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
 		} else {
 			ldb_transaction_cancel(samdb);
 		}
-		return kpasswd_make_pwchange_reply(kdc, mem_ctx,
+		return kpasswd_make_pwchange_reply(mem_ctx,
 						   status,
 						   reject_reason,
 						   dominfo,
 						   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 0000000..5ecb6e9
--- /dev/null
+++ b/source4/kdc/kpasswd-helper.c
@@ -0,0 +1,158 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Samba kpasswd implementation
+
+   Copyright (c) 2005      Andrew Bartlett <abartlet at samba.org>
+   Copyright (c) 2016      Andreas Schneider <asn at 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 "librpc/gen_ndr/samr.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;
+}
+
+bool kpasswd_make_pwchange_reply(TALLOC_CTX *mem_ctx,
+				 NTSTATUS status,
+				 enum samPwdChangeReason reject_reason,
+				 struct samr_DomInfo1 *dominfo,
+				 DATA_BLOB *error_blob)
+{
+	const char *reject_string = NULL;
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+		return kpasswd_make_error_reply(mem_ctx,
+						KRB5_KPASSWD_ACCESSDENIED,
+						"No such user when changing password",


-- 
Samba Shared Repository



More information about the samba-cvs mailing list