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