2 Unix SMB/CIFS implementation.
4 Kerberos utility functions for GENSEC
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "system/kerberos.h"
26 #include "system/time.h"
27 #include "system/network.h"
28 #include "auth/kerberos/kerberos.h"
29 #include "auth/auth.h"
31 struct ccache_container {
32 krb5_context krb5_context;
37 static int free_ccache(void *ptr) {
38 struct ccache_container *ccc = ptr;
39 /* current heimdal - 0.6.3, which we need anyway, fixes segfaults here */
40 krb5_cc_close(ccc->krb5_context, ccc->ccache);
47 * Return a freshly allocated ccache (destroyed by destructor on child
48 * of parent_ctx), for a given set of client credentials
51 NTSTATUS kinit_to_ccache(TALLOC_CTX *parent_ctx,
52 struct cli_credentials *credentials,
55 const char **ccache_name)
61 struct ccache_container *mem_ctx = talloc(parent_ctx, struct ccache_container);
64 return NT_STATUS_NO_MEMORY;
67 password = cli_credentials_get_password(credentials);
69 /* this string should be unique */
70 ccache_string = talloc_asprintf(mem_ctx, "MEMORY:%s_%s",
71 cli_credentials_get_principal(credentials, mem_ctx),
72 generate_random_str(mem_ctx, 16));
74 ret = krb5_cc_resolve(context, ccache_string, ccache);
76 DEBUG(1,("failed to generate a new krb5 keytab (%s): %s\n",
80 return NT_STATUS_INTERNAL_ERROR;
83 mem_ctx->krb5_context = context;
84 mem_ctx->ccache = *ccache;
87 talloc_set_destructor(mem_ctx, free_ccache);
89 ret = kerberos_kinit_password_cc(context, *ccache,
90 cli_credentials_get_principal(credentials, mem_ctx),
91 password, NULL, &kdc_time);
93 /* cope with ticket being in the future due to clock skew */
94 if ((unsigned)kdc_time > time(NULL)) {
95 time_t t = time(NULL);
96 int time_offset =(unsigned)kdc_time-t;
97 DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset));
98 krb5_set_real_time(context, t + time_offset + 1, 0);
101 if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
102 DEBUG(1,("kinit for %s failed (%s)\n",
103 cli_credentials_get_principal(credentials, mem_ctx),
104 smb_get_krb5_error_message(context,
106 talloc_free(mem_ctx);
107 return NT_STATUS_TIME_DIFFERENCE_AT_DC;
110 DEBUG(1,("kinit for %s failed (%s)\n",
111 cli_credentials_get_principal(credentials, mem_ctx),
112 smb_get_krb5_error_message(context,
114 talloc_free(mem_ctx);
115 return NT_STATUS_WRONG_PASSWORD;
117 *ccache_name = ccache_string;