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