}
}
-krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
- void *data,
- krb5_krbhst_info *hi,
- time_t timeout,
- const krb5_data *send_buf,
- krb5_data *recv_buf)
+static krb5_error_code smb_krb5_send_and_recv_func_int(krb5_context context,
+ struct tevent_context *ev,
+ krb5_krbhst_info *hi,
+ struct addrinfo *ai,
+ krb5_send_to_kdc_func func,
+ void *data,
+ time_t timeout,
+ const krb5_data *send_buf,
+ krb5_data *recv_buf)
{
krb5_error_code ret;
NTSTATUS status;
const char *name;
- struct addrinfo *ai, *a;
+ struct addrinfo *a;
struct smb_krb5_socket *smb_krb5;
DATA_BLOB send_blob;
- struct tevent_context *ev;
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) {
return ENOMEM;
}
- if (!data) {
- /* If no event context was available, then create one for this loop */
- ev = samba_tevent_context_init(tmp_ctx);
- if (!ev) {
- talloc_free(tmp_ctx);
- return ENOMEM;
- }
- } else {
- ev = talloc_get_type_abort(data, struct tevent_context);
- }
-
send_blob = data_blob_const(send_buf->data, send_buf->length);
- ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
- if (ret) {
- talloc_free(tmp_ctx);
- return ret;
- }
-
for (a = ai; a; a = a->ai_next) {
struct socket_address *remote_addr;
smb_krb5 = talloc(tmp_ctx, struct smb_krb5_socket);
return EINVAL;
}
- /* After each and every event loop, reset the
- * send_to_kdc pointers to what they were when
- * we entered this loop. That way, if a
- * nested event has invalidated them, we put
- * it back before we return to the heimdal
- * code */
- ret = krb5_set_send_to_kdc_func(context,
- smb_krb5_send_and_recv_func,
- data);
- if (ret != 0) {
- talloc_free(tmp_ctx);
- return ret;
+ if (func) {
+ /* After each and every event loop, reset the
+ * send_to_kdc pointers to what they were when
+ * we entered this loop. That way, if a
+ * nested event has invalidated them, we put
+ * it back before we return to the heimdal
+ * code */
+ ret = krb5_set_send_to_kdc_func(context,
+ func,
+ data);
+ if (ret != 0) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
}
}
if (NT_STATUS_EQUAL(smb_krb5->status, NT_STATUS_IO_TIMEOUT)) {
}
return KRB5_KDC_UNREACH;
}
+
+krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
+ void *data,
+ krb5_krbhst_info *hi,
+ time_t timeout,
+ const krb5_data *send_buf,
+ krb5_data *recv_buf)
+{
+ krb5_error_code ret;
+ struct addrinfo *ai;
+
+ struct tevent_context *ev;
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ if (!data) {
+ /* If no event context was available, then create one for this loop */
+ ev = samba_tevent_context_init(tmp_ctx);
+ if (!ev) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+ } else {
+ ev = talloc_get_type_abort(data, struct tevent_context);
+ }
+
+ ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
+ if (ret) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ return smb_krb5_send_and_recv_func_int(context, ev, hi, ai, smb_krb5_send_and_recv_func, data, timeout, send_buf, recv_buf);
+}
+
+krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context,
+ void *data, /* struct addrinfo */
+ krb5_krbhst_info *hi,
+ time_t timeout,
+ const krb5_data *send_buf,
+ krb5_data *recv_buf)
+{
+ struct addrinfo *ai = data;
+
+ struct tevent_context *ev;
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ /* If no event context was available, then create one for this loop */
+ ev = samba_tevent_context_init(tmp_ctx);
+ if (!ev) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+
+ /* No need to pass in send_and_recv functions, we won't nest on this private event loop */
+ return smb_krb5_send_and_recv_func_int(context, ev, hi, ai, NULL, NULL,
+ timeout, send_buf, recv_buf);
+}
#endif
krb5_error_code
time_t timeout,
const krb5_data *send_buf,
krb5_data *recv_buf);
+krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context,
+ void *data, /* struct addrinfo */
+ krb5_krbhst_info *hi,
+ time_t timeout,
+ const krb5_data *send_buf,
+ krb5_data *recv_buf);
krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context,
struct tevent_context *ev,
struct tevent_context **previous_ev);
for env in ["dc", "s4member", "rodc", "promoted_dc", "plugin_s4_dc", "s3member"]:
plantestsuite("samba.blackbox.wbinfo(%s:local)" % env, "%s:local" % env, [os.path.join(samba4srcdir, "../nsswitch/tests/test_wbinfo.sh"), '$DOMAIN', '$DC_USERNAME', '$DC_PASSWORD', env])
+for env in ["dc", "rodc", "promoted_dc", "plugin_s4_dc"]:
+ plansmbtorture4testsuite('krb5.kdc', env, ['ncacn_np:$SERVER', "-k", "yes", '-U$USERNAME@$REALM%$PASSWORD', '--workgroup=$DOMAIN'])
+
+
# TODO: Verifying the databases really should be a part of the
# environment teardown.
# check the databases are all OK. PLEASE LEAVE THIS AS THE LAST TEST
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ Validate the krb5 pac generation routines
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2015
+
+ 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 "torture/smbtorture.h"
+#include "torture/winbind/proto.h"
+#include "auth/credentials/credentials.h"
+#include "lib/cmdline/popt_common.h"
+#include "source4/auth/kerberos/kerberos.h"
+#include "source4/auth/kerberos/kerberos_util.h"
+#include "lib/util/util_net.h"
+
+static bool torture_krb5_init_context(struct torture_context *tctx,
+ struct smb_krb5_context **smb_krb5_context)
+{
+ const char *host = torture_setting_string(tctx, "host", NULL);
+ krb5_error_code k5ret;
+ bool ok;
+ struct addrinfo *server;
+
+ k5ret = smb_krb5_init_context(tctx, tctx->lp_ctx, smb_krb5_context);
+ torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
+
+ ok = interpret_string_addr_internal(&server, host, AI_NUMERICHOST);
+ torture_assert(tctx, ok, "Failed to parse target server");
+
+ set_sockaddr_port(server->ai_addr, 88);
+
+ k5ret = krb5_set_send_to_kdc_func((*smb_krb5_context)->krb5_context,
+ smb_krb5_send_and_recv_func_forced,
+ server);
+ torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
+ return true;
+}
+
+static bool torture_krb5_as_req_1(struct torture_context *tctx)
+{
+ krb5_error_code k5ret;
+ bool ok;
+ krb5_creds my_creds;
+ krb5_principal principal;
+ struct smb_krb5_context *smb_krb5_context;
+ enum credentials_obtained obtained;
+ const char *error_string;
+ const char *password = cli_credentials_get_password(cmdline_credentials);
+
+ ok = torture_krb5_init_context(tctx, &smb_krb5_context);
+ torture_assert(tctx, ok, "torture_krb5_init_context failed");
+
+ k5ret = principal_from_credentials(tctx, cmdline_credentials, smb_krb5_context, &principal, &obtained, &error_string);
+ torture_assert_int_equal(tctx, k5ret, 0, error_string);
+
+ k5ret = krb5_get_init_creds_password(smb_krb5_context->krb5_context, &my_creds, principal,
+ password, NULL, NULL, 0,
+ NULL, NULL);
+ torture_assert_int_equal(tctx, k5ret, 0, "krb5_get_init_creds_password failed");
+
+ torture_assert_int_equal(tctx,
+ krb5_principal_get_type(smb_krb5_context->krb5_context,
+ my_creds.client), KRB5_NT_PRINCIPAL,
+ "smb_krb5_init_context gave incorrect client->name.name_type");
+
+ torture_assert(tctx, krb5_principal_compare(smb_krb5_context->krb5_context,
+ principal, my_creds.client),
+ "krb5_get_init_creds_password returned a different principal");
+
+ torture_assert_int_equal(tctx,
+ krb5_principal_get_type(smb_krb5_context->krb5_context,
+ my_creds.server), KRB5_NT_SRV_INST,
+ "smb_krb5_init_context gave incorrect client->name.name_type");
+
+ torture_assert_str_equal(tctx, krb5_principal_get_comp_string(smb_krb5_context->krb5_context,
+ my_creds.server, 0),
+ "krbtgt",
+ "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[0]");
+
+ k5ret = krb5_free_cred_contents(smb_krb5_context->krb5_context, &my_creds);
+ torture_assert_int_equal(tctx, k5ret, 0, "krb5_free_creds failed");
+
+ return true;
+}
+
+NTSTATUS torture_krb5_init(void);
+NTSTATUS torture_krb5_init(void)
+{
+ struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "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-1",
+ torture_krb5_as_req_1);
+
+ torture_suite_add_suite(suite, kdc_suite);
+
+ torture_register_suite(suite);
+ return NT_STATUS_OK;
+}
--- /dev/null
+#!/usr/bin/env python
+if bld.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
+ bld.SAMBA_MODULE('TORTURE_KRB5',
+ source='kdc.c',
+ autoproto='proto.h',
+ subsystem='smbtorture',
+ init_function='torture_krb5_init',
+ deps='authkrb5 popt POPT_CREDENTIALS torture KERBEROS_UTIL',
+ internal_module=True
+ )
+
)
bld.RECURSE('local')
+bld.RECURSE('krb5')
bld.SAMBA_MODULE('TORTURE_NBENCH',
source='nbench/nbio.c nbench/nbench.c',