]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/external/kerberos_ldap_group/support_krb5.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / acl / external / kerberos_ldap_group / support_krb5.cc
CommitLineData
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
41extern struct kstruct kparam;
42#endif
b1218840
AJ
43
44#define KT_PATH_MAX 256
45
46void
47krb5_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
58static void
59k5_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 73static void
74k5_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
88static void
89k5_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 */
97int
40f1fd09 98krb5_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
491loop_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 524cleanup:
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