]>
Commit | Line | Data |
---|---|---|
ca02e0ec | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
ca02e0ec AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
b1218840 AJ |
9 | /* |
10 | * ---------------------------------------------------------------------------- | |
11 | * | |
12 | * Author: Markus Moeller (markus_moeller at compuserve.com) | |
13 | * | |
14 | * Copyright (C) 2007 Markus Moeller. All rights reserved. | |
15 | * | |
16 | * This program is free software; you can redistribute it and/or modify | |
17 | * it under the terms of the GNU General Public License as published by | |
18 | * the Free Software Foundation; either version 2 of the License, or | |
19 | * (at your option) any later version. | |
20 | * | |
21 | * This program is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License | |
27 | * along with this program; if not, write to the Free Software | |
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | |
29 | * | |
30 | * ----------------------------------------------------------------------------- | |
31 | */ | |
32 | ||
f7f3304a | 33 | #include "squid.h" |
b1218840 AJ |
34 | #include "util.h" |
35 | ||
1a22a39e | 36 | #if HAVE_LDAP && HAVE_KRB5 |
b1218840 AJ |
37 | |
38 | #include "support.h" | |
39 | ||
7451e5ad MM |
40 | #if HAVE_KRB5 |
41 | extern struct kstruct kparam; | |
42 | #endif | |
b1218840 AJ |
43 | |
44 | #define KT_PATH_MAX 256 | |
45 | ||
46 | void | |
47 | krb5_cleanup() | |
48 | { | |
7451e5ad MM |
49 | if (kparam.context) |
50 | for (int i=0; i<MAX_DOMAINS; i++) { | |
51 | if (kparam.cc[i]) | |
52 | krb5_cc_destroy(kparam.context, kparam.cc[i]); | |
53 | safe_free(kparam.mem_ccache[i]); | |
54 | } | |
55 | krb5_free_context(kparam.context); | |
b1218840 | 56 | } |
f95eb8d8 MM |
57 | |
58 | static void | |
59 | k5_error2(const char* msg, char* msg2, krb5_error_code code) | |
60 | { | |
61 | const char *errmsg; | |
62 | errmsg = krb5_get_error_message(kparam.context, code); | |
63 | error((char *) "%s| %s: ERROR: %s%s : %s\n", LogTime(), PROGRAM, msg, msg2, errmsg); | |
64 | #if HAVE_KRB5_FREE_ERROR_MESSAGE | |
65 | krb5_free_error_message(kparam.context, errmsg); | |
66 | #elif HAVE_KRB5_FREE_ERROR_STRING | |
67 | krb5_free_error_string(kparam.context, (char *)errmsg); | |
68 | #else | |
69 | xfree(errmsg); | |
70 | #endif | |
71 | } | |
72 | ||
40f1fd09 | 73 | static void |
74 | k5_debug(const char* msg, krb5_error_code code) | |
75 | { | |
76 | const char *errmsg; | |
77 | errmsg = krb5_get_error_message(kparam.context, code); | |
78 | debug((char *) "%s| %s: DEBUG: %s : %s\n", LogTime(), PROGRAM, msg, errmsg); | |
79 | #if HAVE_KRB5_FREE_ERROR_MESSAGE | |
80 | krb5_free_error_message(kparam.context, errmsg); | |
81 | #elif HAVE_KRB5_FREE_ERROR_STRING | |
82 | krb5_free_error_string(kparam.context, (char *)errmsg); | |
83 | #else | |
84 | xfree(errmsg); | |
85 | #endif | |
86 | } | |
87 | ||
f95eb8d8 MM |
88 | static void |
89 | k5_error(const char* msg, krb5_error_code code) | |
90 | { | |
91 | k5_error2(msg, (char *)"", code); | |
92 | } | |
93 | ||
b1218840 AJ |
94 | /* |
95 | * create Kerberos memory cache | |
96 | */ | |
97 | int | |
40f1fd09 | 98 | krb5_create_cache(char *domain, char *service_principal_name) |
b1218840 AJ |
99 | { |
100 | ||
7451e5ad | 101 | krb5_keytab keytab = NULL; |
b1218840 AJ |
102 | krb5_keytab_entry entry; |
103 | krb5_kt_cursor cursor; | |
7451e5ad | 104 | krb5_cc_cursor ccursor; |
b1218840 | 105 | krb5_creds *creds = NULL; |
b1218840 AJ |
106 | krb5_principal *principal_list = NULL; |
107 | krb5_principal principal = NULL; | |
108 | char *service; | |
109 | char *keytab_name = NULL, *principal_name = NULL, *mem_cache = NULL; | |
110 | char buf[KT_PATH_MAX], *p; | |
4ebcf1ce | 111 | size_t j,nprinc = 0; |
b1218840 | 112 | int retval = 0; |
b1218840 | 113 | krb5_error_code code = 0; |
7451e5ad | 114 | int ccindex=-1; |
b1218840 AJ |
115 | |
116 | if (!domain || !strcmp(domain, "")) | |
2e881a6f | 117 | return (1); |
b1218840 | 118 | |
b2bdde72 MM |
119 | /* |
120 | * prepare memory credential cache | |
121 | */ | |
122 | #if !HAVE_KRB5_MEMORY_CACHE || HAVE_SUN_LDAP_SDK | |
7451e5ad MM |
123 | mem_cache = (char *) xmalloc(strlen("FILE:/tmp/squid_ldap_") + strlen(domain) + 1 + 16); |
124 | snprintf(mem_cache, strlen("FILE:/tmp/squid_ldap_") + strlen(domain) + 1 + 16, "FILE:/tmp/squid_ldap_%s_%d", domain, (int) getpid()); | |
b2bdde72 | 125 | #else |
7451e5ad MM |
126 | mem_cache = (char *) xmalloc(strlen("MEMORY:squid_ldap_") + strlen(domain) + 1 + 16); |
127 | snprintf(mem_cache, strlen("MEMORY:squid_ldap_") + strlen(domain) + 1 + 16, "MEMORY:squid_ldap_%s_%d", domain, (int) getpid()); | |
b2bdde72 MM |
128 | #endif |
129 | ||
130 | setenv("KRB5CCNAME", mem_cache, 1); | |
131 | debug((char *) "%s| %s: DEBUG: Set credential cache to %s\n", LogTime(), PROGRAM, mem_cache); | |
7451e5ad MM |
132 | for (int i=0; i<MAX_DOMAINS; i++) { |
133 | if (kparam.mem_ccache[i] && !strcmp(mem_cache,kparam.mem_ccache[i])) { | |
134 | ccindex=i; | |
135 | break; | |
136 | } | |
137 | } | |
138 | if ( ccindex == -1 ) { | |
581d42c4 | 139 | kparam.mem_ccache[kparam.ncache]=xstrdup(mem_cache); |
7451e5ad MM |
140 | ccindex=kparam.ncache; |
141 | kparam.ncache++; | |
142 | if ( kparam.ncache == MAX_DOMAINS ) { | |
143 | error((char *) "%s| %s: ERROR: Too many domains to support: # domains %d\n", LogTime(), PROGRAM, kparam.ncache); | |
144 | retval = 1; | |
145 | goto cleanup; | |
146 | } | |
147 | code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc[ccindex]); | |
148 | if (code) { | |
40f1fd09 | 149 | k5_error("Error while resolving memory ccache", code); |
7451e5ad MM |
150 | retval = 1; |
151 | goto cleanup; | |
152 | } | |
b2bdde72 | 153 | } |
b1218840 | 154 | /* |
7451e5ad | 155 | * getting default principal from cache |
b1218840 AJ |
156 | */ |
157 | ||
7451e5ad | 158 | code = krb5_cc_get_principal(kparam.context, kparam.cc[ccindex], &principal); |
b1218840 | 159 | if (code) { |
7451e5ad MM |
160 | if (principal) |
161 | krb5_free_principal(kparam.context, principal); | |
162 | principal = NULL; | |
40f1fd09 | 163 | k5_debug("No default principal found in ccache", code); |
7451e5ad MM |
164 | } else { |
165 | /* | |
166 | * Look for krbtgt and check if it is expired (or soon to be expired) | |
167 | */ | |
168 | code = krb5_cc_start_seq_get(kparam.context, kparam.cc[ccindex], &ccursor); | |
169 | if (code) { | |
40f1fd09 | 170 | k5_error("Error while starting ccache scan", code); |
7451e5ad MM |
171 | code = krb5_cc_close (kparam.context, kparam.cc[ccindex]); |
172 | if (code) { | |
40f1fd09 | 173 | k5_error("Error while closing ccache", code); |
7451e5ad MM |
174 | } |
175 | if (kparam.cc[ccindex]) { | |
176 | code = krb5_cc_destroy(kparam.context, kparam.cc[ccindex]); | |
177 | if (code) { | |
40f1fd09 | 178 | k5_error("Error while destroying ccache", code); |
7451e5ad MM |
179 | } |
180 | } | |
181 | } else { | |
182 | krb5_error_code code2 = 0; | |
4dccc594 | 183 | creds = static_cast<krb5_creds *>(xcalloc(1,sizeof(*creds))); |
7451e5ad MM |
184 | while ((krb5_cc_next_cred(kparam.context, kparam.cc[ccindex], &ccursor, creds)) == 0) { |
185 | code2 = krb5_unparse_name(kparam.context, creds->server, &principal_name); | |
186 | if (code2) { | |
40f1fd09 | 187 | k5_error("Error while unparsing principal", code2); |
7451e5ad MM |
188 | code = krb5_cc_destroy(kparam.context, kparam.cc[ccindex]); |
189 | if (code) { | |
40f1fd09 | 190 | k5_error("Error while destroying ccache", code); |
7451e5ad | 191 | } |
4dccc594 AJ |
192 | assert(creds != NULL); |
193 | krb5_free_creds(kparam.context, creds); | |
581d42c4 | 194 | creds = NULL; |
7451e5ad MM |
195 | safe_free(principal_name); |
196 | debug((char *) "%s| %s: DEBUG: Reset credential cache to %s\n", LogTime(), PROGRAM, mem_cache); | |
197 | code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc[ccindex]); | |
198 | if (code) { | |
40f1fd09 | 199 | k5_error("Error while resolving memory ccache", code); |
7451e5ad MM |
200 | retval = 1; |
201 | goto cleanup; | |
202 | } | |
203 | code =1; | |
204 | break; | |
205 | } | |
206 | if (!strncmp(KRB5_TGS_NAME,principal_name,KRB5_TGS_NAME_SIZE)) { | |
207 | time_t now; | |
208 | static krb5_deltat skew=MAX_SKEW; | |
209 | ||
210 | debug((char *) "%s| %s: DEBUG: Found %s in cache : %s\n", LogTime(), PROGRAM,KRB5_TGS_NAME,principal_name); | |
211 | /* | |
212 | * Check time | |
213 | */ | |
214 | time(&now); | |
215 | debug((char *) "%s| %s: DEBUG: credential time diff %d\n", LogTime(), PROGRAM, (int)(creds->times.endtime - now)); | |
216 | if (creds->times.endtime - now < 2*skew) { | |
217 | debug((char *) "%s| %s: DEBUG: credential will soon expire %d\n", LogTime(), PROGRAM, (int)(creds->times.endtime - now)); | |
218 | if (principal) | |
219 | krb5_free_principal(kparam.context, principal); | |
220 | principal = NULL; | |
221 | code = krb5_cc_destroy(kparam.context, kparam.cc[ccindex]); | |
222 | if (code) { | |
40f1fd09 | 223 | k5_error("Error while destroying ccache", code); |
7451e5ad | 224 | } |
4dccc594 AJ |
225 | assert(creds != NULL); |
226 | krb5_free_creds(kparam.context, creds); | |
7451e5ad MM |
227 | creds = NULL; |
228 | safe_free(principal_name); | |
229 | debug((char *) "%s| %s: DEBUG: Reset credential cache to %s\n", LogTime(), PROGRAM, mem_cache); | |
230 | code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc[ccindex]); | |
231 | if (code) { | |
40f1fd09 | 232 | k5_error("Error while resolving ccache", code); |
7451e5ad MM |
233 | retval = 1; |
234 | goto cleanup; | |
235 | } | |
236 | code = 1; | |
237 | } else { | |
238 | safe_free(principal_name); | |
239 | } | |
240 | break; | |
241 | } | |
4dccc594 AJ |
242 | assert(creds != NULL); |
243 | krb5_free_creds(kparam.context, creds); | |
244 | creds = static_cast<krb5_creds *>(xcalloc(1, sizeof(*creds))); | |
7451e5ad MM |
245 | safe_free(principal_name); |
246 | } | |
247 | if (creds) | |
248 | krb5_free_creds(kparam.context, creds); | |
249 | creds = NULL; | |
250 | code2 = krb5_cc_end_seq_get(kparam.context, kparam.cc[ccindex], &ccursor); | |
251 | if (code2) { | |
40f1fd09 | 252 | k5_error("Error while ending ccache scan", code2); |
7451e5ad MM |
253 | retval = 1; |
254 | goto cleanup; | |
255 | } | |
256 | } | |
b1218840 | 257 | } |
b1218840 | 258 | if (code) { |
7451e5ad MM |
259 | /* |
260 | * getting default keytab name | |
261 | */ | |
b1218840 | 262 | |
7451e5ad MM |
263 | debug((char *) "%s| %s: DEBUG: Get default keytab file name\n", LogTime(), PROGRAM); |
264 | krb5_kt_default_name(kparam.context, buf, KT_PATH_MAX); | |
f53969cc | 265 | p = strchr(buf, ':'); /* Find the end if "FILE:" */ |
7451e5ad | 266 | if (p) |
f53969cc | 267 | ++p; /* step past : */ |
7451e5ad MM |
268 | keytab_name = xstrdup(p ? p : buf); |
269 | debug((char *) "%s| %s: DEBUG: Got default keytab file name %s\n", LogTime(), PROGRAM, keytab_name); | |
b1218840 | 270 | |
7451e5ad MM |
271 | code = krb5_kt_resolve(kparam.context, keytab_name, &keytab); |
272 | if (code) { | |
40f1fd09 | 273 | k5_error2("Error while resolving keytab ", keytab_name,code); |
7451e5ad MM |
274 | retval = 1; |
275 | goto cleanup; | |
276 | } | |
277 | code = krb5_kt_start_seq_get(kparam.context, keytab, &cursor); | |
278 | if (code) { | |
40f1fd09 | 279 | k5_error("Error while starting keytab scan", code); |
7451e5ad MM |
280 | retval = 1; |
281 | goto cleanup; | |
282 | } | |
283 | debug((char *) "%s| %s: DEBUG: Get principal name from keytab %s\n", LogTime(), PROGRAM, keytab_name); | |
284 | ||
285 | nprinc = 0; | |
286 | while ((code = krb5_kt_next_entry(kparam.context, keytab, &entry, &cursor)) == 0) { | |
287 | int found = 0; | |
288 | ||
289 | principal_list = (krb5_principal *) xrealloc(principal_list, sizeof(krb5_principal) * (nprinc + 1)); | |
290 | krb5_copy_principal(kparam.context, entry.principal, &principal_list[nprinc++]); | |
1a22a39e | 291 | #if USE_HEIMDAL_KRB5 |
7451e5ad | 292 | debug((char *) "%s| %s: DEBUG: Keytab entry has realm name: %s\n", LogTime(), PROGRAM, entry.principal->realm); |
b1218840 | 293 | #else |
7451e5ad | 294 | debug((char *) "%s| %s: DEBUG: Keytab entry has realm name: %s\n", LogTime(), PROGRAM, krb5_princ_realm(kparam.context, entry.principal)->data); |
b1218840 | 295 | #endif |
1a22a39e | 296 | #if USE_HEIMDAL_KRB5 |
7451e5ad | 297 | if (!strcasecmp(domain, entry.principal->realm)) |
b1218840 | 298 | #else |
7451e5ad | 299 | if (!strcasecmp(domain, krb5_princ_realm(kparam.context, entry.principal)->data)) |
b1218840 | 300 | #endif |
7451e5ad MM |
301 | { |
302 | code = krb5_unparse_name(kparam.context, entry.principal, &principal_name); | |
303 | if (code) { | |
40f1fd09 | 304 | k5_error("Error while unparsing principal name", code); |
7451e5ad MM |
305 | } else { |
306 | debug((char *) "%s| %s: DEBUG: Found principal name: %s\n", LogTime(), PROGRAM, principal_name); | |
307 | found = 1; | |
40f1fd09 | 308 | if (service_principal_name && strcasecmp(principal_name,service_principal_name) != 0 ) { |
309 | debug((char *) "%s| %s: DEBUG: principal name does not match parameter: %s\n", LogTime(), PROGRAM, service_principal_name); | |
310 | safe_free(principal_name); | |
311 | found = 0; | |
312 | } | |
7451e5ad | 313 | } |
2e881a6f | 314 | } |
1a22a39e | 315 | #if USE_HEIMDAL_KRB5 || ( HAVE_KRB5_KT_FREE_ENTRY && HAVE_DECL_KRB5_KT_FREE_ENTRY ) |
7451e5ad | 316 | code = krb5_kt_free_entry(kparam.context, &entry); |
b1218840 | 317 | #else |
7451e5ad | 318 | code = krb5_free_keytab_entry_contents(kparam.context, &entry); |
b1218840 | 319 | #endif |
b2bdde72 | 320 | if (code) { |
40f1fd09 | 321 | k5_error("Error while freeing keytab entry", code); |
7451e5ad MM |
322 | retval = 1; |
323 | break; | |
b2bdde72 | 324 | } |
7451e5ad MM |
325 | if (found) { |
326 | debug((char *) "%s| %s: DEBUG: Got principal name %s\n", LogTime(), PROGRAM, principal_name); | |
327 | /* | |
328 | * build principal | |
329 | */ | |
330 | code = krb5_parse_name(kparam.context, principal_name, &principal); | |
331 | if (code) { | |
f95eb8d8 | 332 | k5_error2("Error while parsing name ", principal_name,code); |
7451e5ad MM |
333 | safe_free(principal_name); |
334 | if (principal) | |
335 | krb5_free_principal(kparam.context, principal); | |
336 | found = 0; | |
337 | continue; | |
338 | } | |
339 | creds = (krb5_creds *) xcalloc(1,sizeof(*creds)); | |
b2bdde72 | 340 | |
7451e5ad MM |
341 | /* |
342 | * get credentials | |
343 | */ | |
b2bdde72 | 344 | #if HAVE_GET_INIT_CREDS_KEYTAB |
7451e5ad | 345 | code = krb5_get_init_creds_keytab(kparam.context, creds, principal, keytab, 0, NULL, NULL); |
b2bdde72 | 346 | #else |
7451e5ad MM |
347 | service = (char *) xmalloc(strlen("krbtgt") + 2 * strlen(domain) + 3); |
348 | snprintf(service, strlen("krbtgt") + 2 * strlen(domain) + 3, "krbtgt/%s@%s", domain, domain); | |
349 | creds->client = principal; | |
350 | code = krb5_parse_name(kparam.context, service, &creds->server); | |
351 | xfree(service); | |
352 | code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); | |
b2bdde72 MM |
353 | #endif |
354 | ||
7451e5ad | 355 | if (code) { |
40f1fd09 | 356 | k5_error("Error while initialising credentials from keytab", code); |
7451e5ad MM |
357 | safe_free(principal_name); |
358 | if (principal) | |
359 | krb5_free_principal(kparam.context, principal); | |
360 | if (creds) | |
361 | krb5_free_creds(kparam.context, creds); | |
362 | creds = NULL; | |
363 | found = 0; | |
364 | continue; | |
365 | } | |
366 | code = krb5_cc_initialize(kparam.context, kparam.cc[ccindex], principal); | |
367 | if (code) { | |
40f1fd09 | 368 | k5_error("Error while initialising cache", code); |
7451e5ad MM |
369 | safe_free(principal_name); |
370 | if (principal) | |
371 | krb5_free_principal(kparam.context, principal); | |
372 | if (creds) | |
373 | krb5_free_creds(kparam.context, creds); | |
374 | creds = NULL; | |
375 | found = 0; | |
376 | continue; | |
377 | } | |
378 | code = krb5_cc_store_cred(kparam.context, kparam.cc[ccindex], creds); | |
379 | if (code) { | |
40f1fd09 | 380 | k5_error("Error while storing credentials", code); |
7451e5ad MM |
381 | if (principal) |
382 | krb5_free_principal(kparam.context, principal); | |
383 | safe_free(principal_name); | |
384 | if (creds) | |
385 | krb5_free_creds(kparam.context, creds); | |
386 | creds = NULL; | |
387 | found = 0; | |
388 | continue; | |
389 | } | |
390 | debug((char *) "%s| %s: DEBUG: Stored credentials\n", LogTime(), PROGRAM); | |
391 | break; | |
b2bdde72 | 392 | } |
b2bdde72 | 393 | } |
b1218840 | 394 | |
7451e5ad | 395 | if (code && code != KRB5_KT_END) { |
40f1fd09 | 396 | k5_error("Error while scanning keytab", code); |
7451e5ad MM |
397 | retval = 1; |
398 | goto cleanup; | |
399 | } | |
400 | code = krb5_kt_end_seq_get(kparam.context, keytab, &cursor); | |
401 | if (code) { | |
40f1fd09 | 402 | k5_error("Error while ending keytab scan", code); |
7451e5ad MM |
403 | retval = 1; |
404 | goto cleanup; | |
405 | } | |
b1218840 | 406 | |
7451e5ad MM |
407 | /* |
408 | * if no principal name found in keytab for domain use the prinipal name which can get a TGT | |
409 | */ | |
40f1fd09 | 410 | if (!principal_name && !service_principal_name) { |
7451e5ad MM |
411 | size_t i; |
412 | debug((char *) "%s| %s: DEBUG: Did not find a principal in keytab for domain %s.\n", LogTime(), PROGRAM, domain); | |
413 | debug((char *) "%s| %s: DEBUG: Try to get principal of trusted domain.\n", LogTime(), PROGRAM); | |
b1218840 | 414 | |
7451e5ad MM |
415 | for (i = 0; i < nprinc; ++i) { |
416 | krb5_creds *tgt_creds = NULL; | |
417 | creds = (krb5_creds *) xmalloc(sizeof(*creds)); | |
418 | memset(creds, 0, sizeof(*creds)); | |
419 | /* | |
420 | * get credentials | |
421 | */ | |
422 | code = krb5_unparse_name(kparam.context, principal_list[i], &principal_name); | |
423 | if (code) { | |
40f1fd09 | 424 | k5_error("Error while unparsing principal name", code); |
7451e5ad MM |
425 | goto loop_end; |
426 | } | |
427 | debug((char *) "%s| %s: DEBUG: Keytab entry has principal: %s\n", LogTime(), PROGRAM, principal_name); | |
b1218840 AJ |
428 | |
429 | #if HAVE_GET_INIT_CREDS_KEYTAB | |
7451e5ad | 430 | code = krb5_get_init_creds_keytab(kparam.context, creds, principal_list[i], keytab, 0, NULL, NULL); |
b1218840 | 431 | #else |
7451e5ad MM |
432 | service = (char *) xmalloc(strlen("krbtgt") + 2 * strlen(domain) + 3); |
433 | snprintf(service, strlen("krbtgt") + 2 * strlen(domain) + 3, "krbtgt/%s@%s", domain, domain); | |
434 | creds->client = principal_list[i]; | |
435 | code = krb5_parse_name(kparam.context, service, &creds->server); | |
436 | xfree(service); | |
437 | code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); | |
b1218840 | 438 | #endif |
7451e5ad | 439 | if (code) { |
40f1fd09 | 440 | k5_error("Error while initialising credentials from keytab", code); |
7451e5ad MM |
441 | goto loop_end; |
442 | } | |
443 | code = krb5_cc_initialize(kparam.context, kparam.cc[ccindex], principal_list[i]); | |
444 | if (code) { | |
40f1fd09 | 445 | k5_error("Error while initialising memory caches", code); |
7451e5ad MM |
446 | goto loop_end; |
447 | } | |
448 | code = krb5_cc_store_cred(kparam.context, kparam.cc[ccindex], creds); | |
449 | if (code) { | |
40f1fd09 | 450 | k5_error("Error while storing credentials", code); |
7451e5ad MM |
451 | goto loop_end; |
452 | } | |
453 | if (creds->server) | |
454 | krb5_free_principal(kparam.context, creds->server); | |
1a22a39e | 455 | #if USE_HEIMDAL_KRB5 |
7451e5ad MM |
456 | service = (char *) xmalloc(strlen("krbtgt") + strlen(domain) + strlen(principal_list[i]->realm) + 3); |
457 | snprintf(service, strlen("krbtgt") + strlen(domain) + strlen(principal_list[i]->realm) + 3, "krbtgt/%s@%s", domain, principal_list[i]->realm); | |
b1218840 | 458 | #else |
7451e5ad MM |
459 | service = (char *) xmalloc(strlen("krbtgt") + strlen(domain) + strlen(krb5_princ_realm(kparam.context, principal_list[i])->data) + 3); |
460 | snprintf(service, strlen("krbtgt") + strlen(domain) + strlen(krb5_princ_realm(kparam.context, principal_list[i])->data) + 3, "krbtgt/%s@%s", domain, krb5_princ_realm(kparam.context, principal_list[i])->data); | |
b1218840 | 461 | #endif |
7451e5ad MM |
462 | code = krb5_parse_name(kparam.context, service, &creds->server); |
463 | xfree(service); | |
464 | if (code) { | |
40f1fd09 | 465 | k5_error("Error while initialising TGT credentials", code); |
7451e5ad MM |
466 | goto loop_end; |
467 | } | |
b4548e78 | 468 | |
469 | // overwrite limitation of enctypes | |
bcc5a637 | 470 | #if USE_HEIMDAL_KRB5 |
471 | creds->session.keytype = 0; | |
472 | if (creds->session.keyvalue.length > 0) | |
473 | krb5_free_keyblock_contents(kparam.context, &creds->session); | |
474 | #else | |
b4548e78 | 475 | creds->keyblock.enctype = 0; |
476 | if (creds->keyblock.contents) | |
477 | krb5_free_keyblock_contents(kparam.context, &creds->keyblock); | |
bcc5a637 | 478 | #endif |
7451e5ad MM |
479 | code = krb5_get_credentials(kparam.context, 0, kparam.cc[ccindex], creds, &tgt_creds); |
480 | if (code) { | |
40f1fd09 | 481 | k5_error("Error while getting tgt", code); |
7451e5ad MM |
482 | goto loop_end; |
483 | } else { | |
484 | debug((char *) "%s| %s: DEBUG: Found trusted principal name: %s\n", LogTime(), PROGRAM, principal_name); | |
485 | if (tgt_creds) | |
486 | krb5_free_creds(kparam.context, tgt_creds); | |
487 | tgt_creds = NULL; | |
488 | break; | |
489 | } | |
490 | ||
491 | loop_end: | |
492 | safe_free(principal_name); | |
b2bdde72 MM |
493 | if (tgt_creds) |
494 | krb5_free_creds(kparam.context, tgt_creds); | |
495 | tgt_creds = NULL; | |
7451e5ad MM |
496 | if (creds) |
497 | krb5_free_creds(kparam.context, creds); | |
498 | creds = NULL; | |
499 | ||
2e881a6f | 500 | } |
b1218840 | 501 | |
4ebcf1ce MM |
502 | if (creds) |
503 | krb5_free_creds(kparam.context, creds); | |
504 | creds = NULL; | |
2e881a6f | 505 | } |
7451e5ad MM |
506 | } else { |
507 | debug((char *) "%s| %s: DEBUG: Got principal from ccache\n", LogTime(), PROGRAM); | |
508 | /* | |
509 | * get credentials | |
510 | */ | |
511 | code = krb5_unparse_name(kparam.context, principal, &principal_name); | |
512 | if (code) { | |
40f1fd09 | 513 | k5_error("Error while unparsing principal name", code); |
7451e5ad MM |
514 | retval = 1; |
515 | goto cleanup; | |
516 | } | |
517 | debug((char *) "%s| %s: DEBUG: ccache has principal: %s\n", LogTime(), PROGRAM, principal_name); | |
b1218840 | 518 | } |
7451e5ad | 519 | |
b2bdde72 | 520 | if (!principal_name) { |
2e881a6f A |
521 | debug((char *) "%s| %s: DEBUG: Got no principal name\n", LogTime(), PROGRAM); |
522 | retval = 1; | |
b1218840 | 523 | } |
2e881a6f | 524 | cleanup: |
b1218840 | 525 | if (keytab) |
2e881a6f | 526 | krb5_kt_close(kparam.context, keytab); |
4ebcf1ce MM |
527 | xfree(keytab_name); |
528 | xfree(principal_name); | |
529 | xfree(mem_cache); | |
b1218840 | 530 | if (principal) |
2e881a6f | 531 | krb5_free_principal(kparam.context, principal); |
4ebcf1ce MM |
532 | for (j = 0; j < nprinc; ++j) { |
533 | if (principal_list[j]) | |
534 | krb5_free_principal(kparam.context, principal_list[j]); | |
b1218840 | 535 | } |
4ebcf1ce | 536 | xfree(principal_list); |
b1218840 | 537 | if (creds) |
2e881a6f | 538 | krb5_free_creds(kparam.context, creds); |
b1218840 AJ |
539 | return (retval); |
540 | } | |
541 | #endif | |
f53969cc | 542 |