summaryrefslogtreecommitdiffstats
path: root/source4/torture/krb5/kdc-mit.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /source4/torture/krb5/kdc-mit.c
parentInitial commit. (diff)
downloadsamba-upstream.tar.xz
samba-upstream.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source4/torture/krb5/kdc-mit.c')
-rw-r--r--source4/torture/krb5/kdc-mit.c795
1 files changed, 795 insertions, 0 deletions
diff --git a/source4/torture/krb5/kdc-mit.c b/source4/torture/krb5/kdc-mit.c
new file mode 100644
index 0000000..5085966
--- /dev/null
+++ b/source4/torture/krb5/kdc-mit.c
@@ -0,0 +1,795 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Validate the krb5 pac generation routines
+
+ 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 "system/time.h"
+#include "torture/smbtorture.h"
+#include "torture/winbind/proto.h"
+#include "torture/krb5/proto.h"
+#include "auth/credentials/credentials.h"
+#include "lib/cmdline/cmdline.h"
+#include "source4/auth/kerberos/kerberos.h"
+#include "source4/auth/kerberos/kerberos_util.h"
+#include "lib/util/util_net.h"
+
+#define krb5_is_app_tag(dat,tag) \
+ ((dat != NULL) && (dat)->length && \
+ ((((dat)->data[0] & ~0x20) == ((tag) | 0x40))))
+
+#define krb5_is_as_req(dat) krb5_is_app_tag(dat, 10)
+#define krb5_is_as_rep(dat) krb5_is_app_tag(dat, 11)
+#define krb5_is_krb_error(dat) krb5_is_app_tag(dat, 30)
+
+enum torture_krb5_test {
+ TORTURE_KRB5_TEST_PLAIN,
+ TORTURE_KRB5_TEST_PAC_REQUEST,
+ TORTURE_KRB5_TEST_BREAK_PW,
+ TORTURE_KRB5_TEST_CLOCK_SKEW,
+ TORTURE_KRB5_TEST_AES,
+ TORTURE_KRB5_TEST_RC4,
+ TORTURE_KRB5_TEST_AES_RC4,
+};
+
+struct torture_krb5_context {
+ struct torture_context *tctx;
+ krb5_context krb5_context;
+ enum torture_krb5_test test;
+ int recv_packet_count;
+ krb5_kdc_req *as_req;
+ krb5_kdc_rep *as_rep;
+};
+
+krb5_error_code decode_krb5_error(const krb5_data *output, krb5_error **rep);
+
+krb5_error_code decode_krb5_as_req(const krb5_data *output, krb5_kdc_req **req);
+krb5_error_code decode_krb5_as_rep(const krb5_data *output, krb5_kdc_rep **rep);
+
+krb5_error_code decode_krb5_padata_sequence(const krb5_data *output, krb5_pa_data ***rep);
+
+void krb5_free_kdc_req(krb5_context ctx, krb5_kdc_req *req);
+void krb5_free_kdc_rep(krb5_context ctx, krb5_kdc_rep *rep);
+void krb5_free_pa_data(krb5_context ctx, krb5_pa_data **data);
+
+static bool torture_check_krb5_as_req(struct torture_krb5_context *test_context,
+ krb5_context context,
+ const krb5_data *message)
+{
+ krb5_error_code code;
+ int nktypes;
+
+ code = decode_krb5_as_req(message, &test_context->as_req);
+ torture_assert_int_equal(test_context->tctx,
+ code, 0,
+ "decode_as_req failed");
+ torture_assert_int_equal(test_context->tctx,
+ test_context->as_req->msg_type,
+ KRB5_AS_REQ,
+ "Not a AS REQ");
+
+ nktypes = test_context->as_req->nktypes;
+ torture_assert_int_not_equal(test_context->tctx,
+ nktypes, 0,
+ "No keytypes");
+
+ return true;
+}
+
+static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
+ void *data,
+ const krb5_data *realm,
+ const krb5_data *message,
+ krb5_data **new_message_out,
+ krb5_data **new_reply_out)
+{
+ bool ok;
+ struct torture_krb5_context *test_context =
+ (struct torture_krb5_context *)data;
+
+ switch (test_context->test)
+ {
+ case TORTURE_KRB5_TEST_PLAIN:
+ case TORTURE_KRB5_TEST_PAC_REQUEST:
+ case TORTURE_KRB5_TEST_BREAK_PW:
+ case TORTURE_KRB5_TEST_CLOCK_SKEW:
+ case TORTURE_KRB5_TEST_AES:
+ case TORTURE_KRB5_TEST_RC4:
+ case TORTURE_KRB5_TEST_AES_RC4:
+ ok = torture_check_krb5_as_req(test_context,
+ context,
+ message);
+ if (!ok) {
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * We need these function to validate packets because our torture macros
+ * do a 'return false' on error.
+ */
+static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
+ krb5_context context,
+ const krb5_data *reply,
+ krb5_error_code error_code,
+ bool check_pa_data)
+
+{
+ krb5_error *krb_error;
+ krb5_error_code code;
+
+ code = decode_krb5_error(reply, &krb_error);
+ torture_assert_int_equal(test_context->tctx,
+ code,
+ 0,
+ "decode_krb5_error failed");
+
+ torture_assert_int_equal(test_context->tctx,
+ krb_error->error,
+ error_code - KRB5KDC_ERR_NONE,
+ "Got wrong error code");
+
+ if (check_pa_data) {
+ krb5_pa_data **d, **pa_data = NULL;
+ bool timestamp_found = false;
+
+ torture_assert_int_not_equal(test_context->tctx,
+ krb_error->e_data.length, 0,
+ "No e-data returned");
+
+ code = decode_krb5_padata_sequence(&krb_error->e_data,
+ &pa_data);
+ torture_assert_int_equal(test_context->tctx,
+ code,
+ 0,
+ "decode_krb5_padata_sequence failed");
+
+ for (d = pa_data; d != NULL; d++) {
+ if ((*d)->pa_type == KRB5_PADATA_ENC_TIMESTAMP) {
+ timestamp_found = true;
+ break;
+ }
+ }
+ torture_assert(test_context->tctx,
+ timestamp_found,
+ "Encrypted timestamp not found");
+
+ krb5_free_pa_data(context, pa_data);
+ }
+
+ krb5_free_error(context, krb_error);
+
+ return true;
+}
+
+static bool torture_check_krb5_as_rep(struct torture_krb5_context *test_context,
+ krb5_context context,
+ const krb5_data *reply)
+{
+ krb5_error_code code;
+ bool ok;
+
+ code = decode_krb5_as_rep(reply, &test_context->as_rep);
+ torture_assert_int_equal(test_context->tctx,
+ code,
+ 0,
+ "decode_krb5_as_rep failed");
+
+ torture_assert(test_context->tctx,
+ test_context->as_rep->ticket->enc_part.kvno,
+ "No KVNO set");
+
+ ok = torture_setting_bool(test_context->tctx,
+ "expect_cached_at_rodc",
+ false);
+ if (ok) {
+ torture_assert_int_not_equal(test_context->tctx,
+ test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
+ 0,
+ "Did not get a RODC number in the KVNO");
+ } else {
+ torture_assert_int_equal(test_context->tctx,
+ test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
+ 0,
+ "Unexpecedly got a RODC number in the KVNO");
+ }
+
+ return true;
+}
+
+static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context,
+ krb5_context context,
+ const krb5_data *reply,
+ krb5_enctype expected_enctype)
+{
+ krb5_enctype reply_enctype;
+ bool ok;
+
+ ok = torture_check_krb5_as_rep(test_context,
+ context,
+ reply);
+ if (!ok) {
+ return false;
+ }
+
+ reply_enctype = test_context->as_rep->enc_part.enctype;
+
+ torture_assert_int_equal(test_context->tctx,
+ reply_enctype, expected_enctype,
+ "Ticket encrypted with invalid algorithm");
+
+ return true;
+}
+
+static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
+ void *data,
+ krb5_error_code kdc_code,
+ const krb5_data *realm,
+ const krb5_data *message,
+ const krb5_data *reply,
+ krb5_data **new_reply_out)
+{
+ struct torture_krb5_context *test_context =
+ (struct torture_krb5_context *)data;
+ krb5_error_code code;
+ bool ok = true;
+
+ torture_comment(test_context->tctx,
+ "PACKET COUNT = %d\n",
+ test_context->recv_packet_count);
+
+ torture_comment(test_context->tctx,
+ "KRB5_AS_REP = %d\n",
+ krb5_is_as_req(reply));
+
+ torture_comment(test_context->tctx,
+ "KRB5_ERROR = %d\n",
+ krb5_is_krb_error(reply));
+
+ torture_comment(test_context->tctx,
+ "KDC ERROR CODE = %d\n",
+ kdc_code);
+
+ switch (test_context->test)
+ {
+ case TORTURE_KRB5_TEST_PLAIN:
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ } else {
+ ok = torture_check_krb5_as_rep(test_context,
+ context,
+ reply);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_as_rep failed");
+ }
+
+ torture_assert_goto(test_context->tctx,
+ test_context->recv_packet_count < 2,
+ ok,
+ out,
+ "Too many packets");
+
+ break;
+ case TORTURE_KRB5_TEST_PAC_REQUEST:
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KRB_ERR_RESPONSE_TOO_BIG,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ } else if (test_context->recv_packet_count == 1) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ } else if (krb5_is_krb_error(reply)) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KRB_ERR_RESPONSE_TOO_BIG,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ } else {
+ ok = torture_check_krb5_as_rep(test_context,
+ context,
+ reply);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_as_rep failed");
+ }
+
+ torture_assert_goto(test_context->tctx,
+ test_context->recv_packet_count < 3,
+ ok,
+ out,
+ "Too many packets");
+ break;
+ case TORTURE_KRB5_TEST_BREAK_PW:
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ if (!ok) {
+ goto out;
+ }
+ } else if (test_context->recv_packet_count == 1) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_FAILED,
+ true);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ }
+
+ torture_assert_goto(test_context->tctx,
+ test_context->recv_packet_count < 2,
+ ok,
+ out,
+ "Too many packets");
+ break;
+ case TORTURE_KRB5_TEST_CLOCK_SKEW:
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ if (!ok) {
+ goto out;
+ }
+ } else if (test_context->recv_packet_count == 1) {
+ /*
+ * This only works if kdc_timesync 0 is set in krb5.conf
+ *
+ * See commit 5f39a4438eafd693a3eb8366bbc3901efe62e538
+ * in the MIT Kerberos source tree.
+ */
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KRB_AP_ERR_SKEW,
+ false);
+ torture_assert_goto(test_context->tctx,
+ ok,
+ ok,
+ out,
+ "torture_check_krb5_error failed");
+ }
+
+ torture_assert_goto(test_context->tctx,
+ test_context->recv_packet_count < 2,
+ ok,
+ out,
+ "Too many packets");
+ break;
+ case TORTURE_KRB5_TEST_AES:
+ torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES\n");
+
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ if (!ok) {
+ goto out;
+ }
+ } else {
+ ok = torture_check_krb5_as_rep_enctype(test_context,
+ context,
+ reply,
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96);
+ if (!ok) {
+ goto out;
+ }
+ }
+ break;
+ case TORTURE_KRB5_TEST_RC4:
+ torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_RC4\n");
+
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ if (!ok) {
+ goto out;
+ }
+ } else {
+ ok = torture_check_krb5_as_rep_enctype(test_context,
+ context,
+ reply,
+ ENCTYPE_ARCFOUR_HMAC);
+ if (!ok) {
+ goto out;
+ }
+ }
+ break;
+ case TORTURE_KRB5_TEST_AES_RC4:
+ torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES_RC4\n");
+
+ if (test_context->recv_packet_count == 0) {
+ ok = torture_check_krb5_error(test_context,
+ context,
+ reply,
+ KRB5KDC_ERR_PREAUTH_REQUIRED,
+ false);
+ if (!ok) {
+ goto out;
+ }
+ } else {
+ ok = torture_check_krb5_as_rep_enctype(test_context,
+ context,
+ reply,
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96);
+ if (!ok) {
+ goto out;
+ }
+ }
+ break;
+ }
+
+ code = kdc_code;
+out:
+ if (!ok) {
+ code = EINVAL;
+ }
+
+ /* Cleanup */
+ krb5_free_kdc_req(test_context->krb5_context, test_context->as_req);
+ krb5_free_kdc_rep(test_context->krb5_context, test_context->as_rep);
+
+ test_context->recv_packet_count++;
+
+ return code;
+}
+
+static bool torture_krb5_init_context(struct torture_context *tctx,
+ enum torture_krb5_test test,
+ struct smb_krb5_context **smb_krb5_context)
+{
+ krb5_error_code code;
+
+ struct torture_krb5_context *test_context = talloc_zero(tctx,
+ struct torture_krb5_context);
+ torture_assert(tctx, test_context != NULL, "Failed to allocate");
+
+ test_context->test = test;
+ test_context->tctx = tctx;
+
+ code = smb_krb5_init_context(tctx, tctx->lp_ctx, smb_krb5_context);
+ torture_assert_int_equal(tctx, code, 0, "smb_krb5_init_context failed");
+
+ test_context->krb5_context = (*smb_krb5_context)->krb5_context;
+
+ krb5_set_kdc_send_hook((*smb_krb5_context)->krb5_context,
+ torture_krb5_pre_send_test,
+ test_context);
+
+ krb5_set_kdc_recv_hook((*smb_krb5_context)->krb5_context,
+ torture_krb5_post_recv_test,
+ test_context);
+
+ return true;
+}
+static bool torture_krb5_as_req_creds(struct torture_context *tctx,
+ struct cli_credentials *credentials,
+ enum torture_krb5_test test)
+{
+ krb5_get_init_creds_opt *krb_options = NULL;
+ struct smb_krb5_context *smb_krb5_context;
+ enum credentials_obtained obtained;
+ const char *error_string;
+ const char *password;
+ krb5_principal principal;
+ krb5_error_code code;
+ krb5_creds my_creds;
+ bool ok;
+
+ ok = torture_krb5_init_context(tctx, test, &smb_krb5_context);
+ torture_assert(tctx, ok, "torture_krb5_init_context failed");
+
+ code = principal_from_credentials(tctx,
+ credentials,
+ smb_krb5_context,
+ &principal,
+ &obtained,
+ &error_string);
+ torture_assert_int_equal(tctx, code, 0, error_string);
+
+ password = cli_credentials_get_password(credentials);
+
+ switch (test)
+ {
+ case TORTURE_KRB5_TEST_PLAIN:
+ break;
+ case TORTURE_KRB5_TEST_PAC_REQUEST:
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
+ code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
+ &krb_options);
+ torture_assert_int_equal(tctx,
+ code, 0,
+ "krb5_get_init_creds_opt_alloc failed");
+
+ code = krb5_get_init_creds_opt_set_pac_request(smb_krb5_context->krb5_context,
+ krb_options,
+ 1);
+ torture_assert_int_equal(tctx,
+ code, 0,
+ "krb5_get_init_creds_opt_set_pac_request failed");
+#endif
+ break;
+ case TORTURE_KRB5_TEST_BREAK_PW:
+ password = "NOT the password";
+ break;
+ case TORTURE_KRB5_TEST_CLOCK_SKEW:
+ code = krb5_set_real_time(smb_krb5_context->krb5_context,
+ time(NULL) + 3600,
+ 0);
+ torture_assert_int_equal(tctx,
+ code, 0,
+ "krb5_set_real_time failed");
+ break;
+ case TORTURE_KRB5_TEST_AES: {
+ krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96 };
+
+ code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
+ &krb_options);
+ torture_assert_int_equal(tctx,
+ code, 0,
+ "krb5_get_init_creds_opt_alloc failed");
+
+ krb5_get_init_creds_opt_set_etype_list(krb_options,
+ etype,
+ 1);
+ break;
+ }
+ case TORTURE_KRB5_TEST_RC4: {
+ krb5_enctype etype[] = { ENCTYPE_ARCFOUR_HMAC };
+
+ code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
+ &krb_options);
+ torture_assert_int_equal(tctx,
+ code, 0,
+ "krb5_get_init_creds_opt_alloc failed");
+
+ krb5_get_init_creds_opt_set_etype_list(krb_options,
+ etype,
+ 1);
+ break;
+ }
+ case TORTURE_KRB5_TEST_AES_RC4: {
+ krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_ARCFOUR_HMAC };
+
+ code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
+ &krb_options);
+ torture_assert_int_equal(tctx,
+ code, 0,
+ "krb5_get_init_creds_opt_alloc failed");
+
+
+ krb5_get_init_creds_opt_set_etype_list(krb_options,
+ etype,
+ 2);
+ break;
+ }
+ }
+
+ code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
+ &my_creds,
+ principal,
+ password,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ krb_options);
+ krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context,
+ krb_options);
+
+ switch (test)
+ {
+ case TORTURE_KRB5_TEST_PLAIN:
+ case TORTURE_KRB5_TEST_PAC_REQUEST:
+ case TORTURE_KRB5_TEST_AES:
+ case TORTURE_KRB5_TEST_RC4:
+ case TORTURE_KRB5_TEST_AES_RC4:
+ torture_assert_int_equal(tctx,
+ code,
+ 0,
+ "krb5_get_init_creds_password failed");
+ break;
+ case TORTURE_KRB5_TEST_BREAK_PW:
+ torture_assert_int_equal(tctx,
+ code,
+ KRB5KDC_ERR_PREAUTH_FAILED,
+ "krb5_get_init_creds_password should "
+ "have failed");
+ return true;
+ case TORTURE_KRB5_TEST_CLOCK_SKEW:
+ torture_assert_int_equal(tctx,
+ code,
+ KRB5KRB_AP_ERR_SKEW,
+ "krb5_get_init_creds_password should "
+ "have failed");
+ return true;
+ }
+
+ krb5_free_cred_contents(smb_krb5_context->krb5_context,
+ &my_creds);
+
+ return true;
+}
+
+static bool torture_krb5_as_req_cmdline(struct torture_context *tctx)
+{
+ return torture_krb5_as_req_creds(tctx,
+ samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_PLAIN);
+}
+
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
+static bool torture_krb5_as_req_pac_request(struct torture_context *tctx)
+{
+ bool ok;
+
+ ok = torture_setting_bool(tctx, "expect_rodc", false);
+ if (ok) {
+ torture_skip(tctx,
+ "This test needs further investigation in the "
+ "RODC case against a Windows DC, in particular "
+ "with non-cached users");
+ }
+ return torture_krb5_as_req_creds(tctx, samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_PAC_REQUEST);
+}
+#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST */
+
+static bool torture_krb5_as_req_break_pw(struct torture_context *tctx)
+{
+ return torture_krb5_as_req_creds(tctx,
+ samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_BREAK_PW);
+}
+
+static bool torture_krb5_as_req_clock_skew(struct torture_context *tctx)
+{
+ return torture_krb5_as_req_creds(tctx,
+ samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_CLOCK_SKEW);
+}
+
+static bool torture_krb5_as_req_aes(struct torture_context *tctx)
+{
+ return torture_krb5_as_req_creds(tctx,
+ samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_AES);
+}
+
+static bool torture_krb5_as_req_rc4(struct torture_context *tctx)
+{
+ return torture_krb5_as_req_creds(tctx,
+ samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_RC4);
+}
+
+static bool torture_krb5_as_req_aes_rc4(struct torture_context *tctx)
+{
+ return torture_krb5_as_req_creds(tctx,
+ samba_cmdline_get_creds(),
+ TORTURE_KRB5_TEST_AES_RC4);
+}
+
+NTSTATUS torture_krb5_init(TALLOC_CTX *ctx)
+{
+ struct torture_suite *suite =
+ torture_suite_create(ctx, "krb5");
+ struct torture_suite *kdc_suite = torture_suite_create(suite, "kdc");
+ suite->description = talloc_strdup(suite, "Kerberos tests");
+ kdc_suite->description = talloc_strdup(kdc_suite, "Kerberos KDC tests");
+
+ torture_suite_add_simple_test(kdc_suite,
+ "as-req-cmdline",
+ torture_krb5_as_req_cmdline);
+
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
+ /* Only available with MIT Kerveros 1.15 and newer */
+ torture_suite_add_simple_test(kdc_suite, "as-req-pac-request",
+ torture_krb5_as_req_pac_request);
+#endif
+
+ torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
+ torture_krb5_as_req_break_pw);
+
+ /* This only works if kdc_timesync 0 is set in krb5.conf */
+ torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
+ torture_krb5_as_req_clock_skew);
+
+#if 0
+ torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
+#endif
+ torture_suite_add_simple_test(kdc_suite,
+ "as-req-aes",
+ torture_krb5_as_req_aes);
+
+ torture_suite_add_simple_test(kdc_suite,
+ "as-req-rc4",
+ torture_krb5_as_req_rc4);
+
+ torture_suite_add_simple_test(kdc_suite,
+ "as-req-aes-rc4",
+ torture_krb5_as_req_aes_rc4);
+
+ torture_suite_add_suite(suite, kdc_suite);
+
+ torture_register_suite(ctx, suite);
+
+ return NT_STATUS_OK;
+}