1 /* $KAME: gssapi.c,v 1.19 2001/04/03 15:51:55 thorpej Exp $ */
4 * Copyright 2000 Wasabi Systems, Inc.
7 * This software was written by Frank van der Linden of Wasabi Systems
8 * for Zembu Labs, Inc. http://www.zembu.com/
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of Wasabi Systems, Inc. may not be used to endorse
19 * or promote products derived from this software without specific prior
22 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/types.h>
40 #include <sys/queue.h>
41 #include <sys/socket.h>
57 #include "localconf.h"
58 #include "remoteconf.h"
59 #include "isakmp_var.h"
63 #include "ipsec_doi.h"
64 #include "crypto_openssl.h"
66 #include "isakmp_ident.h"
67 #include "isakmp_inf.h"
74 gssapi_error(OM_uint32 status_code
, const char *where
,
77 OM_uint32 message_context
, maj_stat
, min_stat
;
78 gss_buffer_desc status_string
;
82 plogv(LLV_ERROR
, where
, NULL
, fmt
, &ap
);
88 maj_stat
= gss_display_status(&min_stat
, status_code
,
89 GSS_C_MECH_CODE
, GSS_C_NO_OID
, &message_context
,
91 if (GSS_ERROR(maj_stat
))
92 plog(LLV_ERROR
, LOCATION
, NULL
,
93 "UNABLE TO GET GSSAPI ERROR CODE\n");
95 plog(LLV_ERROR
, where
, NULL
,
96 "%s\n", (char *)status_string
.value
);
97 gss_release_buffer(&min_stat
, &status_string
);
99 } while (message_context
!= 0);
103 * vmbufs and gss_buffer_descs are really just the same on NetBSD, but
104 * this is to be portable.
107 gssapi_vm2gssbuf(vchar_t
*vmbuf
, gss_buffer_t gsstoken
)
110 gsstoken
->value
= racoon_malloc(vmbuf
->l
);
111 if (gsstoken
->value
== NULL
)
113 memcpy(gsstoken
->value
, vmbuf
->v
, vmbuf
->l
);
114 gsstoken
->length
= vmbuf
->l
;
120 gssapi_gss2vmbuf(gss_buffer_t gsstoken
, vchar_t
**vmbuf
)
123 *vmbuf
= vmalloc(gsstoken
->length
);
126 memcpy((*vmbuf
)->v
, gsstoken
->value
, gsstoken
->length
);
127 (*vmbuf
)->l
= gsstoken
->length
;
133 gssapi_get_default_gss_id(void)
135 char name
[NI_MAXHOST
];
138 if (gethostname(name
, sizeof(name
)) != 0) {
139 plog(LLV_ERROR
, LOCATION
, NULL
, "gethostname failed: %s\n",
143 name
[sizeof(name
) - 1] = '\0';
145 gssid
= racoon_malloc(sizeof(*gssid
));
146 gssid
->l
= asprintf(&gssid
->v
, "%s/%s", GSSAPI_DEF_NAME
, name
);
152 gssapi_get_default_name(struct ph1handle
*iph1
, int remote
, gss_name_t
*service
)
154 char name
[NI_MAXHOST
];
157 gss_buffer_desc name_token
;
158 OM_uint32 min_stat
, maj_stat
;
160 sa
= remote
? iph1
->remote
: iph1
->local
;
162 if (getnameinfo(sa
, sysdep_sa_len(sa
), name
, NI_MAXHOST
, NULL
, 0, 0) != 0)
165 name_token
.length
= asprintf(&buf
, "%s@%s", GSSAPI_DEF_NAME
, name
);
166 name_token
.value
= buf
;
168 maj_stat
= gss_import_name(&min_stat
, &name_token
,
169 GSS_C_NT_HOSTBASED_SERVICE
, service
);
170 if (GSS_ERROR(maj_stat
)) {
171 gssapi_error(min_stat
, LOCATION
, "import name\n");
172 maj_stat
= gss_release_buffer(&min_stat
, &name_token
);
173 if (GSS_ERROR(maj_stat
))
174 gssapi_error(min_stat
, LOCATION
, "release name_token");
177 maj_stat
= gss_release_buffer(&min_stat
, &name_token
);
178 if (GSS_ERROR(maj_stat
))
179 gssapi_error(min_stat
, LOCATION
, "release name_token");
185 gssapi_init(struct ph1handle
*iph1
)
187 struct gssapi_ph1_state
*gps
;
188 gss_buffer_desc id_token
, cred_token
;
189 gss_buffer_t cred
= &cred_token
;
190 gss_name_t princ
, canon_princ
;
191 OM_uint32 maj_stat
, min_stat
;
193 gps
= racoon_calloc(1, sizeof (struct gssapi_ph1_state
));
195 plog(LLV_ERROR
, LOCATION
, NULL
, "racoon_calloc failed\n");
198 gps
->gss_context
= GSS_C_NO_CONTEXT
;
199 gps
->gss_cred
= GSS_C_NO_CREDENTIAL
;
201 gssapi_set_state(iph1
, gps
);
203 if (iph1
->rmconf
->proposal
->gssid
!= NULL
) {
204 id_token
.length
= iph1
->rmconf
->proposal
->gssid
->l
;
205 id_token
.value
= iph1
->rmconf
->proposal
->gssid
->v
;
206 maj_stat
= gss_import_name(&min_stat
, &id_token
, GSS_C_NO_OID
,
208 if (GSS_ERROR(maj_stat
)) {
209 gssapi_error(min_stat
, LOCATION
, "import name\n");
210 gssapi_free_state(iph1
);
214 gssapi_get_default_name(iph1
, 0, &princ
);
216 maj_stat
= gss_canonicalize_name(&min_stat
, princ
, GSS_C_NO_OID
,
218 if (GSS_ERROR(maj_stat
)) {
219 gssapi_error(min_stat
, LOCATION
, "canonicalize name\n");
220 maj_stat
= gss_release_name(&min_stat
, &princ
);
221 if (GSS_ERROR(maj_stat
))
222 gssapi_error(min_stat
, LOCATION
, "release princ\n");
223 gssapi_free_state(iph1
);
226 maj_stat
= gss_release_name(&min_stat
, &princ
);
227 if (GSS_ERROR(maj_stat
))
228 gssapi_error(min_stat
, LOCATION
, "release princ\n");
230 maj_stat
= gss_export_name(&min_stat
, canon_princ
, cred
);
231 if (GSS_ERROR(maj_stat
)) {
232 gssapi_error(min_stat
, LOCATION
, "export name\n");
233 maj_stat
= gss_release_name(&min_stat
, &canon_princ
);
234 if (GSS_ERROR(maj_stat
))
235 gssapi_error(min_stat
, LOCATION
,
236 "release canon_princ\n");
237 gssapi_free_state(iph1
);
243 * XXXJRT Did this debug message ever work? This is a GSS name
244 * blob at this point.
246 plog(LLV_DEBUG
, LOCATION
, NULL
, "will try to acquire '%.*s' creds\n",
247 cred
->length
, cred
->value
);
250 maj_stat
= gss_release_buffer(&min_stat
, cred
);
251 if (GSS_ERROR(maj_stat
))
252 gssapi_error(min_stat
, LOCATION
, "release cred buffer\n");
254 maj_stat
= gss_acquire_cred(&min_stat
, canon_princ
, GSS_C_INDEFINITE
,
255 GSS_C_NO_OID_SET
, GSS_C_BOTH
, &gps
->gss_cred
, NULL
, NULL
);
256 if (GSS_ERROR(maj_stat
)) {
257 gssapi_error(min_stat
, LOCATION
, "acquire cred\n");
258 maj_stat
= gss_release_name(&min_stat
, &canon_princ
);
259 if (GSS_ERROR(maj_stat
))
260 gssapi_error(min_stat
, LOCATION
,
261 "release canon_princ\n");
262 gssapi_free_state(iph1
);
265 maj_stat
= gss_release_name(&min_stat
, &canon_princ
);
266 if (GSS_ERROR(maj_stat
))
267 gssapi_error(min_stat
, LOCATION
, "release canon_princ\n");
273 gssapi_get_itoken(struct ph1handle
*iph1
, int *lenp
)
275 struct gssapi_ph1_state
*gps
;
276 gss_buffer_desc empty
, name_token
;
277 gss_buffer_t itoken
, rtoken
, dummy
;
278 OM_uint32 maj_stat
, min_stat
;
281 if (gssapi_get_state(iph1
) == NULL
&& gssapi_init(iph1
) < 0)
284 gps
= gssapi_get_state(iph1
);
290 if (iph1
->approval
!= NULL
&& iph1
->approval
->gssid
!= NULL
) {
291 plog(LLV_DEBUG
, LOCATION
, NULL
,
292 "using provided service '%.*s'\n",
293 (int)iph1
->approval
->gssid
->l
, iph1
->approval
->gssid
->v
);
294 name_token
.length
= iph1
->approval
->gssid
->l
;
295 name_token
.value
= iph1
->approval
->gssid
->v
;
296 maj_stat
= gss_import_name(&min_stat
, &name_token
,
297 GSS_C_NO_OID
, &partner
);
298 if (GSS_ERROR(maj_stat
)) {
299 gssapi_error(min_stat
, LOCATION
, "import of %.*s\n",
300 name_token
.length
, name_token
.value
);
304 if (gssapi_get_default_name(iph1
, 1, &partner
) < 0)
307 rtoken
= gps
->gsscnt_p
== 0 ? dummy
: &gps
->gss_p
[gps
->gsscnt_p
- 1];
308 itoken
= &gps
->gss
[gps
->gsscnt
];
310 gps
->gss_status
= gss_init_sec_context(&min_stat
, gps
->gss_cred
,
311 &gps
->gss_context
, partner
, GSS_C_NO_OID
,
312 GSS_C_MUTUAL_FLAG
| GSS_C_SEQUENCE_FLAG
|
313 GSS_C_CONF_FLAG
| GSS_C_INTEG_FLAG
,
314 0, GSS_C_NO_CHANNEL_BINDINGS
, rtoken
, NULL
,
317 if (GSS_ERROR(gps
->gss_status
)) {
318 gssapi_error(min_stat
, LOCATION
, "init_sec_context\n");
319 maj_stat
= gss_release_name(&min_stat
, &partner
);
320 if (GSS_ERROR(maj_stat
))
321 gssapi_error(min_stat
, LOCATION
, "release name\n");
324 maj_stat
= gss_release_name(&min_stat
, &partner
);
325 if (GSS_ERROR(maj_stat
))
326 gssapi_error(min_stat
, LOCATION
, "release name\n");
328 plog(LLV_DEBUG
, LOCATION
, NULL
, "gss_init_sec_context status %x\n",
332 *lenp
= itoken
->length
;
334 if (itoken
->length
!= 0)
341 * Call gss_accept_context, with token just read from the wire.
344 gssapi_get_rtoken(struct ph1handle
*iph1
, int *lenp
)
346 struct gssapi_ph1_state
*gps
;
347 gss_buffer_desc name_token
;
348 gss_buffer_t itoken
, rtoken
;
349 OM_uint32 min_stat
, maj_stat
;
350 gss_name_t client_name
;
352 if (gssapi_get_state(iph1
) == NULL
&& gssapi_init(iph1
) < 0)
355 gps
= gssapi_get_state(iph1
);
357 rtoken
= &gps
->gss_p
[gps
->gsscnt_p
- 1];
358 itoken
= &gps
->gss
[gps
->gsscnt
];
360 gps
->gss_status
= gss_accept_sec_context(&min_stat
, &gps
->gss_context
,
361 gps
->gss_cred
, rtoken
, GSS_C_NO_CHANNEL_BINDINGS
, &client_name
,
362 NULL
, itoken
, NULL
, NULL
, NULL
);
364 if (GSS_ERROR(gps
->gss_status
)) {
365 gssapi_error(min_stat
, LOCATION
, "accept_sec_context\n");
369 maj_stat
= gss_display_name(&min_stat
, client_name
, &name_token
, NULL
);
370 if (GSS_ERROR(maj_stat
)) {
371 gssapi_error(min_stat
, LOCATION
, "gss_display_name\n");
372 maj_stat
= gss_release_name(&min_stat
, &client_name
);
373 if (GSS_ERROR(maj_stat
))
374 gssapi_error(min_stat
, LOCATION
,
375 "release client_name\n");
378 maj_stat
= gss_release_name(&min_stat
, &client_name
);
379 if (GSS_ERROR(maj_stat
))
380 gssapi_error(min_stat
, LOCATION
, "release client_name\n");
382 plog(LLV_DEBUG
, LOCATION
, NULL
,
383 "gss_accept_sec_context: other side is %s\n",
384 (char *)name_token
.value
);
385 maj_stat
= gss_release_buffer(&min_stat
, &name_token
);
386 if (GSS_ERROR(maj_stat
))
387 gssapi_error(min_stat
, LOCATION
, "release name buffer\n");
389 if (itoken
->length
!= 0)
393 *lenp
= itoken
->length
;
399 gssapi_save_received_token(struct ph1handle
*iph1
, vchar_t
*token
)
401 struct gssapi_ph1_state
*gps
;
402 gss_buffer_t gsstoken
;
405 if (gssapi_get_state(iph1
) == NULL
&& gssapi_init(iph1
) < 0)
408 gps
= gssapi_get_state(iph1
);
410 gsstoken
= &gps
->gss_p
[gps
->gsscnt_p
];
412 ret
= gssapi_vm2gssbuf(token
, gsstoken
);
421 gssapi_get_token_to_send(struct ph1handle
*iph1
, vchar_t
**token
)
423 struct gssapi_ph1_state
*gps
;
424 gss_buffer_t gsstoken
;
427 gps
= gssapi_get_state(iph1
);
429 plog(LLV_ERROR
, LOCATION
, NULL
,
430 "gssapi not yet initialized?\n");
433 gsstoken
= &gps
->gss
[gps
->gsscnt
- 1];
434 ret
= gssapi_gss2vmbuf(gsstoken
, token
);
442 gssapi_get_itokens(struct ph1handle
*iph1
, vchar_t
**tokens
)
444 struct gssapi_ph1_state
*gps
;
449 gps
= gssapi_get_state(iph1
);
451 plog(LLV_ERROR
, LOCATION
, NULL
,
452 "gssapi not yet initialized?\n");
456 for (i
= len
= 0; i
< gps
->gsscnt
; i
++)
457 len
+= gps
->gss
[i
].length
;
463 for (i
= 0; i
< gps
->gsscnt
; i
++) {
464 memcpy(p
, gps
->gss
[i
].value
, gps
->gss
[i
].length
);
465 p
+= gps
->gss
[i
].length
;
470 plog(LLV_DEBUG
, LOCATION
, NULL
,
471 "%d itokens of length %zu\n", gps
->gsscnt
, (*tokens
)->l
);
477 gssapi_get_rtokens(struct ph1handle
*iph1
, vchar_t
**tokens
)
479 struct gssapi_ph1_state
*gps
;
484 gps
= gssapi_get_state(iph1
);
486 plog(LLV_ERROR
, LOCATION
, NULL
,
487 "gssapi not yet initialized?\n");
491 if (gssapi_more_tokens(iph1
)) {
492 plog(LLV_ERROR
, LOCATION
, NULL
,
493 "gssapi roundtrips not complete\n");
497 for (i
= len
= 0; i
< gps
->gsscnt_p
; i
++)
498 len
+= gps
->gss_p
[i
].length
;
504 for (i
= 0; i
< gps
->gsscnt_p
; i
++) {
505 memcpy(p
, gps
->gss_p
[i
].value
, gps
->gss_p
[i
].length
);
506 p
+= gps
->gss_p
[i
].length
;
515 gssapi_wraphash(struct ph1handle
*iph1
)
517 struct gssapi_ph1_state
*gps
;
518 OM_uint32 maj_stat
, min_stat
;
519 gss_buffer_desc hash_in_buf
, hash_out_buf
;
520 gss_buffer_t hash_in
= &hash_in_buf
, hash_out
= &hash_out_buf
;
523 gps
= gssapi_get_state(iph1
);
525 plog(LLV_ERROR
, LOCATION
, NULL
,
526 "gssapi not yet initialized?\n");
530 if (gssapi_more_tokens(iph1
)) {
531 plog(LLV_ERROR
, LOCATION
, NULL
,
532 "gssapi roundtrips not complete\n");
536 if (gssapi_vm2gssbuf(iph1
->hash
, hash_in
) < 0) {
537 plog(LLV_ERROR
, LOCATION
, NULL
, "vm2gssbuf failed\n");
541 maj_stat
= gss_wrap(&min_stat
, gps
->gss_context
, 1, GSS_C_QOP_DEFAULT
,
542 hash_in
, NULL
, hash_out
);
543 if (GSS_ERROR(maj_stat
)) {
544 gssapi_error(min_stat
, LOCATION
, "wrapping hash value\n");
545 maj_stat
= gss_release_buffer(&min_stat
, hash_in
);
546 if (GSS_ERROR(maj_stat
))
547 gssapi_error(min_stat
, LOCATION
,
548 "release hash_in buffer\n");
552 plog(LLV_DEBUG
, LOCATION
, NULL
, "wrapped HASH, ilen %zu olen %zu\n",
553 hash_in
->length
, hash_out
->length
);
555 maj_stat
= gss_release_buffer(&min_stat
, hash_in
);
556 if (GSS_ERROR(maj_stat
))
557 gssapi_error(min_stat
, LOCATION
, "release hash_in buffer\n");
559 if (gssapi_gss2vmbuf(hash_out
, &outbuf
) < 0) {
560 plog(LLV_ERROR
, LOCATION
, NULL
, "gss2vmbuf failed\n");
561 maj_stat
= gss_release_buffer(&min_stat
, hash_out
);
562 if (GSS_ERROR(maj_stat
))
563 gssapi_error(min_stat
, LOCATION
,
564 "release hash_out buffer\n");
567 maj_stat
= gss_release_buffer(&min_stat
, hash_out
);
568 if (GSS_ERROR(maj_stat
))
569 gssapi_error(min_stat
, LOCATION
, "release hash_out buffer\n");
575 gssapi_unwraphash(struct ph1handle
*iph1
)
577 struct gssapi_ph1_state
*gps
;
578 OM_uint32 maj_stat
, min_stat
;
579 gss_buffer_desc hashbuf
, hash_outbuf
;
580 gss_buffer_t hash_in
= &hashbuf
, hash_out
= &hash_outbuf
;
583 gps
= gssapi_get_state(iph1
);
585 plog(LLV_ERROR
, LOCATION
, NULL
,
586 "gssapi not yet initialized?\n");
591 hashbuf
.length
= ntohs(iph1
->pl_hash
->h
.len
) - sizeof(*iph1
->pl_hash
);
592 hashbuf
.value
= (char *)(iph1
->pl_hash
+ 1);
594 plog(LLV_DEBUG
, LOCATION
, NULL
, "unwrapping HASH of len %zu\n",
597 maj_stat
= gss_unwrap(&min_stat
, gps
->gss_context
, hash_in
, hash_out
,
599 if (GSS_ERROR(maj_stat
)) {
600 gssapi_error(min_stat
, LOCATION
, "unwrapping hash value\n");
604 if (gssapi_gss2vmbuf(hash_out
, &outbuf
) < 0) {
605 plog(LLV_ERROR
, LOCATION
, NULL
, "gss2vmbuf failed\n");
606 maj_stat
= gss_release_buffer(&min_stat
, hash_out
);
607 if (GSS_ERROR(maj_stat
))
608 gssapi_error(min_stat
, LOCATION
,
609 "release hash_out buffer\n");
612 maj_stat
= gss_release_buffer(&min_stat
, hash_out
);
613 if (GSS_ERROR(maj_stat
))
614 gssapi_error(min_stat
, LOCATION
, "release hash_out buffer\n");
620 gssapi_set_id_sent(struct ph1handle
*iph1
)
622 struct gssapi_ph1_state
*gps
;
624 gps
= gssapi_get_state(iph1
);
626 gps
->gss_flags
|= GSSFLAG_ID_SENT
;
630 gssapi_id_sent(struct ph1handle
*iph1
)
632 struct gssapi_ph1_state
*gps
;
634 gps
= gssapi_get_state(iph1
);
636 return (gps
->gss_flags
& GSSFLAG_ID_SENT
) != 0;
640 gssapi_set_id_rcvd(struct ph1handle
*iph1
)
642 struct gssapi_ph1_state
*gps
;
644 gps
= gssapi_get_state(iph1
);
646 gps
->gss_flags
|= GSSFLAG_ID_RCVD
;
650 gssapi_id_rcvd(struct ph1handle
*iph1
)
652 struct gssapi_ph1_state
*gps
;
654 gps
= gssapi_get_state(iph1
);
656 return (gps
->gss_flags
& GSSFLAG_ID_RCVD
) != 0;
660 gssapi_free_state(struct ph1handle
*iph1
)
662 struct gssapi_ph1_state
*gps
;
663 OM_uint32 maj_stat
, min_stat
;
665 gps
= gssapi_get_state(iph1
);
670 gssapi_set_state(iph1
, NULL
);
672 if (gps
->gss_cred
!= GSS_C_NO_CREDENTIAL
) {
673 maj_stat
= gss_release_cred(&min_stat
, &gps
->gss_cred
);
674 if (GSS_ERROR(maj_stat
))
675 gssapi_error(min_stat
, LOCATION
,
676 "releasing credentials\n");
682 gssapi_get_id(struct ph1handle
*iph1
)
684 gss_buffer_desc id_buffer
;
685 gss_buffer_t id
= &id_buffer
;
686 gss_name_t defname
, canon_name
;
687 OM_uint32 min_stat
, maj_stat
;
690 if (iph1
->rmconf
->proposal
->gssid
!= NULL
)
691 return (vdup(iph1
->rmconf
->proposal
->gssid
));
693 if (gssapi_get_default_name(iph1
, 0, &defname
) < 0)
696 maj_stat
= gss_canonicalize_name(&min_stat
, defname
, GSS_C_NO_OID
,
698 if (GSS_ERROR(maj_stat
)) {
699 gssapi_error(min_stat
, LOCATION
, "canonicalize name\n");
700 maj_stat
= gss_release_name(&min_stat
, &defname
);
701 if (GSS_ERROR(maj_stat
))
702 gssapi_error(min_stat
, LOCATION
,
703 "release default name\n");
706 maj_stat
= gss_release_name(&min_stat
, &defname
);
707 if (GSS_ERROR(maj_stat
))
708 gssapi_error(min_stat
, LOCATION
, "release default name\n");
710 maj_stat
= gss_export_name(&min_stat
, canon_name
, id
);
711 if (GSS_ERROR(maj_stat
)) {
712 gssapi_error(min_stat
, LOCATION
, "export name\n");
713 maj_stat
= gss_release_name(&min_stat
, &canon_name
);
714 if (GSS_ERROR(maj_stat
))
715 gssapi_error(min_stat
, LOCATION
,
716 "release canonical name\n");
719 maj_stat
= gss_release_name(&min_stat
, &canon_name
);
720 if (GSS_ERROR(maj_stat
))
721 gssapi_error(min_stat
, LOCATION
, "release canonical name\n");
725 * XXXJRT Did this debug message ever work? This is a GSS name
726 * blob at this point.
728 plog(LLV_DEBUG
, LOCATION
, NULL
, "will try to acquire '%.*s' creds\n",
729 id
->length
, id
->value
);
732 if (gssapi_gss2vmbuf(id
, &vmbuf
) < 0) {
733 plog(LLV_ERROR
, LOCATION
, NULL
, "gss2vmbuf failed\n");
734 maj_stat
= gss_release_buffer(&min_stat
, id
);
735 if (GSS_ERROR(maj_stat
))
736 gssapi_error(min_stat
, LOCATION
, "release id buffer\n");
739 maj_stat
= gss_release_buffer(&min_stat
, id
);
740 if (GSS_ERROR(maj_stat
))
741 gssapi_error(min_stat
, LOCATION
, "release id buffer\n");