No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / krb5 / kcm.c
blobfacc1fa0e70cb2a3269c1ba9a82b6aa4b0229fea
1 /*
2 * Copyright (c) 2005, PADL Software Pty Ltd.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of PADL Software nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #include "krb5_locl.h"
35 #ifdef HAVE_KCM
37 * Client library for Kerberos Credentials Manager (KCM) daemon
40 #ifdef HAVE_SYS_UN_H
41 #include <sys/un.h>
42 #endif
44 #include "kcm.h"
46 __RCSID("$Heimdal: kcm.c 22108 2007-12-03 17:23:53Z lha $"
47 "$NetBSD$");
49 typedef struct krb5_kcmcache {
50 char *name;
51 struct sockaddr_un path;
52 char *door_path;
53 } krb5_kcmcache;
55 #define KCMCACHE(X) ((krb5_kcmcache *)(X)->data.data)
56 #define CACHENAME(X) (KCMCACHE(X)->name)
57 #define KCMCURSOR(C) (*(uint32_t *)(C))
59 static krb5_error_code
60 try_door(krb5_context context, const krb5_kcmcache *k,
61 krb5_data *request_data,
62 krb5_data *response_data)
64 #ifdef HAVE_DOOR_CREATE
65 door_arg_t arg;
66 int fd;
67 int ret;
69 memset(&arg, 0, sizeof(arg));
71 fd = open(k->door_path, O_RDWR);
72 if (fd < 0)
73 return KRB5_CC_IO;
75 arg.data_ptr = request_data->data;
76 arg.data_size = request_data->length;
77 arg.desc_ptr = NULL;
78 arg.desc_num = 0;
79 arg.rbuf = NULL;
80 arg.rsize = 0;
82 ret = door_call(fd, &arg);
83 close(fd);
84 if (ret != 0)
85 return KRB5_CC_IO;
87 ret = krb5_data_copy(response_data, arg.rbuf, arg.rsize);
88 munmap(arg.rbuf, arg.rsize);
89 if (ret)
90 return ret;
92 return 0;
93 #else
94 return KRB5_CC_IO;
95 #endif
98 static krb5_error_code
99 try_unix_socket(krb5_context context, const krb5_kcmcache *k,
100 krb5_data *request_data,
101 krb5_data *response_data)
103 krb5_error_code ret;
104 int fd;
106 fd = socket(AF_UNIX, SOCK_STREAM, 0);
107 if (fd < 0)
108 return KRB5_CC_IO;
110 if (connect(fd, rk_UNCONST(&k->path), sizeof(k->path)) != 0) {
111 close(fd);
112 return KRB5_CC_IO;
115 ret = _krb5_send_and_recv_tcp(fd, context->kdc_timeout,
116 request_data, response_data);
117 close(fd);
118 return ret;
121 static krb5_error_code
122 kcm_send_request(krb5_context context,
123 krb5_kcmcache *k,
124 krb5_storage *request,
125 krb5_data *response_data)
127 krb5_error_code ret;
128 krb5_data request_data;
129 int i;
131 response_data->data = NULL;
132 response_data->length = 0;
134 ret = krb5_storage_to_data(request, &request_data);
135 if (ret) {
136 krb5_clear_error_string(context);
137 return KRB5_CC_NOMEM;
140 ret = KRB5_CC_IO;
142 for (i = 0; i < context->max_retries; i++) {
143 ret = try_door(context, k, &request_data, response_data);
144 if (ret == 0 && response_data->length != 0)
145 break;
146 ret = try_unix_socket(context, k, &request_data, response_data);
147 if (ret == 0 && response_data->length != 0)
148 break;
151 krb5_data_free(&request_data);
153 if (ret) {
154 krb5_clear_error_string(context);
155 ret = KRB5_CC_IO;
158 return ret;
161 static krb5_error_code
162 kcm_storage_request(krb5_context context,
163 kcm_operation opcode,
164 krb5_storage **storage_p)
166 krb5_storage *sp;
167 krb5_error_code ret;
169 *storage_p = NULL;
171 sp = krb5_storage_emem();
172 if (sp == NULL) {
173 krb5_set_error_string(context, "malloc: out of memory");
174 return KRB5_CC_NOMEM;
177 /* Send MAJOR | VERSION | OPCODE */
178 ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR);
179 if (ret)
180 goto fail;
181 ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR);
182 if (ret)
183 goto fail;
184 ret = krb5_store_int16(sp, opcode);
185 if (ret)
186 goto fail;
188 *storage_p = sp;
189 fail:
190 if (ret) {
191 krb5_set_error_string(context, "Failed to encode request");
192 krb5_storage_free(sp);
195 return ret;
198 static krb5_error_code
199 kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
201 krb5_kcmcache *k;
202 const char *path;
204 k = malloc(sizeof(*k));
205 if (k == NULL) {
206 krb5_set_error_string(context, "malloc: out of memory");
207 return KRB5_CC_NOMEM;
210 if (name != NULL) {
211 k->name = strdup(name);
212 if (k->name == NULL) {
213 free(k);
214 krb5_set_error_string(context, "malloc: out of memory");
215 return KRB5_CC_NOMEM;
217 } else
218 k->name = NULL;
220 path = krb5_config_get_string_default(context, NULL,
221 _PATH_KCM_SOCKET,
222 "libdefaults",
223 "kcm_socket",
224 NULL);
226 k->path.sun_family = AF_UNIX;
227 strlcpy(k->path.sun_path, path, sizeof(k->path.sun_path));
229 path = krb5_config_get_string_default(context, NULL,
230 _PATH_KCM_DOOR,
231 "libdefaults",
232 "kcm_door",
233 NULL);
234 k->door_path = strdup(path);
236 (*id)->data.data = k;
237 (*id)->data.length = sizeof(*k);
239 return 0;
242 static krb5_error_code
243 kcm_call(krb5_context context,
244 krb5_kcmcache *k,
245 krb5_storage *request,
246 krb5_storage **response_p,
247 krb5_data *response_data_p)
249 krb5_data response_data;
250 krb5_error_code ret;
251 int32_t status;
252 krb5_storage *response;
254 if (response_p != NULL)
255 *response_p = NULL;
257 ret = kcm_send_request(context, k, request, &response_data);
258 if (ret) {
259 return ret;
262 response = krb5_storage_from_data(&response_data);
263 if (response == NULL) {
264 krb5_data_free(&response_data);
265 return KRB5_CC_IO;
268 ret = krb5_ret_int32(response, &status);
269 if (ret) {
270 krb5_storage_free(response);
271 krb5_data_free(&response_data);
272 return KRB5_CC_FORMAT;
275 if (status) {
276 krb5_storage_free(response);
277 krb5_data_free(&response_data);
278 return status;
281 if (response_p != NULL) {
282 *response_data_p = response_data;
283 *response_p = response;
285 return 0;
288 krb5_storage_free(response);
289 krb5_data_free(&response_data);
291 return 0;
294 static void
295 kcm_free(krb5_context context, krb5_ccache *id)
297 krb5_kcmcache *k = KCMCACHE(*id);
299 if (k != NULL) {
300 if (k->name != NULL)
301 free(k->name);
302 if (k->door_path)
303 free(k->door_path);
304 memset(k, 0, sizeof(*k));
305 krb5_data_free(&(*id)->data);
308 *id = NULL;
311 static const char *
312 kcm_get_name(krb5_context context,
313 krb5_ccache id)
315 return CACHENAME(id);
318 static krb5_error_code
319 kcm_resolve(krb5_context context, krb5_ccache *id, const char *res)
321 return kcm_alloc(context, res, id);
325 * Request:
327 * Response:
328 * NameZ
330 static krb5_error_code
331 kcm_gen_new(krb5_context context, krb5_ccache *id)
333 krb5_kcmcache *k;
334 krb5_error_code ret;
335 krb5_storage *request, *response;
336 krb5_data response_data;
338 ret = kcm_alloc(context, NULL, id);
339 if (ret)
340 return ret;
342 k = KCMCACHE(*id);
344 ret = kcm_storage_request(context, KCM_OP_GEN_NEW, &request);
345 if (ret) {
346 kcm_free(context, id);
347 return ret;
350 ret = kcm_call(context, k, request, &response, &response_data);
351 if (ret) {
352 krb5_storage_free(request);
353 kcm_free(context, id);
354 return ret;
357 ret = krb5_ret_stringz(response, &k->name);
358 if (ret)
359 ret = KRB5_CC_IO;
361 krb5_storage_free(request);
362 krb5_storage_free(response);
363 krb5_data_free(&response_data);
365 if (ret)
366 kcm_free(context, id);
368 return ret;
372 * Request:
373 * NameZ
374 * Principal
376 * Response:
379 static krb5_error_code
380 kcm_initialize(krb5_context context,
381 krb5_ccache id,
382 krb5_principal primary_principal)
384 krb5_error_code ret;
385 krb5_kcmcache *k = KCMCACHE(id);
386 krb5_storage *request;
388 ret = kcm_storage_request(context, KCM_OP_INITIALIZE, &request);
389 if (ret)
390 return ret;
392 ret = krb5_store_stringz(request, k->name);
393 if (ret) {
394 krb5_storage_free(request);
395 return ret;
398 ret = krb5_store_principal(request, primary_principal);
399 if (ret) {
400 krb5_storage_free(request);
401 return ret;
404 ret = kcm_call(context, k, request, NULL, NULL);
406 krb5_storage_free(request);
407 return ret;
410 static krb5_error_code
411 kcm_close(krb5_context context,
412 krb5_ccache id)
414 kcm_free(context, &id);
415 return 0;
419 * Request:
420 * NameZ
422 * Response:
425 static krb5_error_code
426 kcm_destroy(krb5_context context,
427 krb5_ccache id)
429 krb5_error_code ret;
430 krb5_kcmcache *k = KCMCACHE(id);
431 krb5_storage *request;
433 ret = kcm_storage_request(context, KCM_OP_DESTROY, &request);
434 if (ret)
435 return ret;
437 ret = krb5_store_stringz(request, k->name);
438 if (ret) {
439 krb5_storage_free(request);
440 return ret;
443 ret = kcm_call(context, k, request, NULL, NULL);
445 krb5_storage_free(request);
446 return ret;
450 * Request:
451 * NameZ
452 * Creds
454 * Response:
457 static krb5_error_code
458 kcm_store_cred(krb5_context context,
459 krb5_ccache id,
460 krb5_creds *creds)
462 krb5_error_code ret;
463 krb5_kcmcache *k = KCMCACHE(id);
464 krb5_storage *request;
466 ret = kcm_storage_request(context, KCM_OP_STORE, &request);
467 if (ret)
468 return ret;
470 ret = krb5_store_stringz(request, k->name);
471 if (ret) {
472 krb5_storage_free(request);
473 return ret;
476 ret = krb5_store_creds(request, creds);
477 if (ret) {
478 krb5_storage_free(request);
479 return ret;
482 ret = kcm_call(context, k, request, NULL, NULL);
484 krb5_storage_free(request);
485 return ret;
489 * Request:
490 * NameZ
491 * WhichFields
492 * MatchCreds
494 * Response:
495 * Creds
498 static krb5_error_code
499 kcm_retrieve(krb5_context context,
500 krb5_ccache id,
501 krb5_flags which,
502 const krb5_creds *mcred,
503 krb5_creds *creds)
505 krb5_error_code ret;
506 krb5_kcmcache *k = KCMCACHE(id);
507 krb5_storage *request, *response;
508 krb5_data response_data;
510 ret = kcm_storage_request(context, KCM_OP_RETRIEVE, &request);
511 if (ret)
512 return ret;
514 ret = krb5_store_stringz(request, k->name);
515 if (ret) {
516 krb5_storage_free(request);
517 return ret;
520 ret = krb5_store_int32(request, which);
521 if (ret) {
522 krb5_storage_free(request);
523 return ret;
526 ret = krb5_store_creds_tag(request, rk_UNCONST(mcred));
527 if (ret) {
528 krb5_storage_free(request);
529 return ret;
532 ret = kcm_call(context, k, request, &response, &response_data);
533 if (ret) {
534 krb5_storage_free(request);
535 return ret;
538 ret = krb5_ret_creds(response, creds);
539 if (ret)
540 ret = KRB5_CC_IO;
542 krb5_storage_free(request);
543 krb5_storage_free(response);
544 krb5_data_free(&response_data);
546 return ret;
550 * Request:
551 * NameZ
553 * Response:
554 * Principal
556 static krb5_error_code
557 kcm_get_principal(krb5_context context,
558 krb5_ccache id,
559 krb5_principal *principal)
561 krb5_error_code ret;
562 krb5_kcmcache *k = KCMCACHE(id);
563 krb5_storage *request, *response;
564 krb5_data response_data;
566 ret = kcm_storage_request(context, KCM_OP_GET_PRINCIPAL, &request);
567 if (ret)
568 return ret;
570 ret = krb5_store_stringz(request, k->name);
571 if (ret) {
572 krb5_storage_free(request);
573 return ret;
576 ret = kcm_call(context, k, request, &response, &response_data);
577 if (ret) {
578 krb5_storage_free(request);
579 return ret;
582 ret = krb5_ret_principal(response, principal);
583 if (ret)
584 ret = KRB5_CC_IO;
586 krb5_storage_free(request);
587 krb5_storage_free(response);
588 krb5_data_free(&response_data);
590 return ret;
594 * Request:
595 * NameZ
597 * Response:
598 * Cursor
601 static krb5_error_code
602 kcm_get_first (krb5_context context,
603 krb5_ccache id,
604 krb5_cc_cursor *cursor)
606 krb5_error_code ret;
607 krb5_kcmcache *k = KCMCACHE(id);
608 krb5_storage *request, *response;
609 krb5_data response_data;
610 int32_t tmp;
612 ret = kcm_storage_request(context, KCM_OP_GET_FIRST, &request);
613 if (ret)
614 return ret;
616 ret = krb5_store_stringz(request, k->name);
617 if (ret) {
618 krb5_storage_free(request);
619 return ret;
622 ret = kcm_call(context, k, request, &response, &response_data);
623 if (ret) {
624 krb5_storage_free(request);
625 return ret;
628 ret = krb5_ret_int32(response, &tmp);
629 if (ret || tmp < 0)
630 ret = KRB5_CC_IO;
632 krb5_storage_free(request);
633 krb5_storage_free(response);
634 krb5_data_free(&response_data);
636 if (ret)
637 return ret;
639 *cursor = malloc(sizeof(tmp));
640 if (*cursor == NULL)
641 return KRB5_CC_NOMEM;
643 KCMCURSOR(*cursor) = tmp;
645 return 0;
649 * Request:
650 * NameZ
651 * Cursor
653 * Response:
654 * Creds
656 static krb5_error_code
657 kcm_get_next (krb5_context context,
658 krb5_ccache id,
659 krb5_cc_cursor *cursor,
660 krb5_creds *creds)
662 krb5_error_code ret;
663 krb5_kcmcache *k = KCMCACHE(id);
664 krb5_storage *request, *response;
665 krb5_data response_data;
667 ret = kcm_storage_request(context, KCM_OP_GET_NEXT, &request);
668 if (ret)
669 return ret;
671 ret = krb5_store_stringz(request, k->name);
672 if (ret) {
673 krb5_storage_free(request);
674 return ret;
677 ret = krb5_store_int32(request, KCMCURSOR(*cursor));
678 if (ret) {
679 krb5_storage_free(request);
680 return ret;
683 ret = kcm_call(context, k, request, &response, &response_data);
684 if (ret) {
685 krb5_storage_free(request);
686 return ret;
689 ret = krb5_ret_creds(response, creds);
690 if (ret)
691 ret = KRB5_CC_IO;
693 krb5_storage_free(request);
694 krb5_storage_free(response);
695 krb5_data_free(&response_data);
697 return ret;
701 * Request:
702 * NameZ
703 * Cursor
705 * Response:
708 static krb5_error_code
709 kcm_end_get (krb5_context context,
710 krb5_ccache id,
711 krb5_cc_cursor *cursor)
713 krb5_error_code ret;
714 krb5_kcmcache *k = KCMCACHE(id);
715 krb5_storage *request;
717 ret = kcm_storage_request(context, KCM_OP_END_GET, &request);
718 if (ret)
719 return ret;
721 ret = krb5_store_stringz(request, k->name);
722 if (ret) {
723 krb5_storage_free(request);
724 return ret;
727 ret = krb5_store_int32(request, KCMCURSOR(*cursor));
728 if (ret) {
729 krb5_storage_free(request);
730 return ret;
733 ret = kcm_call(context, k, request, NULL, NULL);
734 if (ret) {
735 krb5_storage_free(request);
736 return ret;
739 krb5_storage_free(request);
741 KCMCURSOR(*cursor) = 0;
742 free(*cursor);
743 *cursor = NULL;
745 return ret;
749 * Request:
750 * NameZ
751 * WhichFields
752 * MatchCreds
754 * Response:
757 static krb5_error_code
758 kcm_remove_cred(krb5_context context,
759 krb5_ccache id,
760 krb5_flags which,
761 krb5_creds *cred)
763 krb5_error_code ret;
764 krb5_kcmcache *k = KCMCACHE(id);
765 krb5_storage *request;
767 ret = kcm_storage_request(context, KCM_OP_REMOVE_CRED, &request);
768 if (ret)
769 return ret;
771 ret = krb5_store_stringz(request, k->name);
772 if (ret) {
773 krb5_storage_free(request);
774 return ret;
777 ret = krb5_store_int32(request, which);
778 if (ret) {
779 krb5_storage_free(request);
780 return ret;
783 ret = krb5_store_creds_tag(request, cred);
784 if (ret) {
785 krb5_storage_free(request);
786 return ret;
789 ret = kcm_call(context, k, request, NULL, NULL);
791 krb5_storage_free(request);
792 return ret;
795 static krb5_error_code
796 kcm_set_flags(krb5_context context,
797 krb5_ccache id,
798 krb5_flags flags)
800 krb5_error_code ret;
801 krb5_kcmcache *k = KCMCACHE(id);
802 krb5_storage *request;
804 ret = kcm_storage_request(context, KCM_OP_SET_FLAGS, &request);
805 if (ret)
806 return ret;
808 ret = krb5_store_stringz(request, k->name);
809 if (ret) {
810 krb5_storage_free(request);
811 return ret;
814 ret = krb5_store_int32(request, flags);
815 if (ret) {
816 krb5_storage_free(request);
817 return ret;
820 ret = kcm_call(context, k, request, NULL, NULL);
822 krb5_storage_free(request);
823 return ret;
826 static krb5_error_code
827 kcm_get_version(krb5_context context,
828 krb5_ccache id)
830 return 0;
833 static krb5_error_code
834 kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
836 krb5_set_error_string(context, "kcm_move not implemented");
837 return EINVAL;
840 static krb5_error_code
841 kcm_default_name(krb5_context context, char **str)
843 return _krb5_expand_default_cc_name(context,
844 KRB5_DEFAULT_CCNAME_KCM,
845 str);
849 * Variable containing the KCM based credential cache implemention.
851 * @ingroup krb5_ccache
854 const krb5_cc_ops krb5_kcm_ops = {
855 "KCM",
856 kcm_get_name,
857 kcm_resolve,
858 kcm_gen_new,
859 kcm_initialize,
860 kcm_destroy,
861 kcm_close,
862 kcm_store_cred,
863 kcm_retrieve,
864 kcm_get_principal,
865 kcm_get_first,
866 kcm_get_next,
867 kcm_end_get,
868 kcm_remove_cred,
869 kcm_set_flags,
870 kcm_get_version,
871 NULL,
872 NULL,
873 NULL,
874 kcm_move,
875 kcm_default_name
878 krb5_boolean
879 _krb5_kcm_is_running(krb5_context context)
881 krb5_error_code ret;
882 krb5_ccache_data ccdata;
883 krb5_ccache id = &ccdata;
884 krb5_boolean running;
886 ret = kcm_alloc(context, NULL, &id);
887 if (ret)
888 return 0;
890 running = (_krb5_kcm_noop(context, id) == 0);
892 kcm_free(context, &id);
894 return running;
898 * Request:
900 * Response:
903 krb5_error_code
904 _krb5_kcm_noop(krb5_context context,
905 krb5_ccache id)
907 krb5_error_code ret;
908 krb5_kcmcache *k = KCMCACHE(id);
909 krb5_storage *request;
911 ret = kcm_storage_request(context, KCM_OP_NOOP, &request);
912 if (ret)
913 return ret;
915 ret = kcm_call(context, k, request, NULL, NULL);
917 krb5_storage_free(request);
918 return ret;
923 * Request:
924 * NameZ
925 * Mode
927 * Response:
930 krb5_error_code
931 _krb5_kcm_chmod(krb5_context context,
932 krb5_ccache id,
933 uint16_t mode)
935 krb5_error_code ret;
936 krb5_kcmcache *k = KCMCACHE(id);
937 krb5_storage *request;
939 ret = kcm_storage_request(context, KCM_OP_CHMOD, &request);
940 if (ret)
941 return ret;
943 ret = krb5_store_stringz(request, k->name);
944 if (ret) {
945 krb5_storage_free(request);
946 return ret;
949 ret = krb5_store_int16(request, mode);
950 if (ret) {
951 krb5_storage_free(request);
952 return ret;
955 ret = kcm_call(context, k, request, NULL, NULL);
957 krb5_storage_free(request);
958 return ret;
963 * Request:
964 * NameZ
965 * UID
966 * GID
968 * Response:
971 krb5_error_code
972 _krb5_kcm_chown(krb5_context context,
973 krb5_ccache id,
974 uint32_t uid,
975 uint32_t gid)
977 krb5_error_code ret;
978 krb5_kcmcache *k = KCMCACHE(id);
979 krb5_storage *request;
981 ret = kcm_storage_request(context, KCM_OP_CHOWN, &request);
982 if (ret)
983 return ret;
985 ret = krb5_store_stringz(request, k->name);
986 if (ret) {
987 krb5_storage_free(request);
988 return ret;
991 ret = krb5_store_int32(request, uid);
992 if (ret) {
993 krb5_storage_free(request);
994 return ret;
997 ret = krb5_store_int32(request, gid);
998 if (ret) {
999 krb5_storage_free(request);
1000 return ret;
1003 ret = kcm_call(context, k, request, NULL, NULL);
1005 krb5_storage_free(request);
1006 return ret;
1011 * Request:
1012 * NameZ
1013 * ServerPrincipalPresent
1014 * ServerPrincipal OPTIONAL
1015 * Key
1017 * Repsonse:
1020 krb5_error_code
1021 _krb5_kcm_get_initial_ticket(krb5_context context,
1022 krb5_ccache id,
1023 krb5_principal server,
1024 krb5_keyblock *key)
1026 krb5_error_code ret;
1027 krb5_kcmcache *k = KCMCACHE(id);
1028 krb5_storage *request;
1030 ret = kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
1031 if (ret)
1032 return ret;
1034 ret = krb5_store_stringz(request, k->name);
1035 if (ret) {
1036 krb5_storage_free(request);
1037 return ret;
1040 ret = krb5_store_int8(request, (server == NULL) ? 0 : 1);
1041 if (ret) {
1042 krb5_storage_free(request);
1043 return ret;
1046 if (server != NULL) {
1047 ret = krb5_store_principal(request, server);
1048 if (ret) {
1049 krb5_storage_free(request);
1050 return ret;
1054 ret = krb5_store_keyblock(request, *key);
1055 if (ret) {
1056 krb5_storage_free(request);
1057 return ret;
1060 ret = kcm_call(context, k, request, NULL, NULL);
1062 krb5_storage_free(request);
1063 return ret;
1068 * Request:
1069 * NameZ
1070 * KDCFlags
1071 * EncryptionType
1072 * ServerPrincipal
1074 * Repsonse:
1077 krb5_error_code
1078 _krb5_kcm_get_ticket(krb5_context context,
1079 krb5_ccache id,
1080 krb5_kdc_flags flags,
1081 krb5_enctype enctype,
1082 krb5_principal server)
1084 krb5_error_code ret;
1085 krb5_kcmcache *k = KCMCACHE(id);
1086 krb5_storage *request;
1088 ret = kcm_storage_request(context, KCM_OP_GET_TICKET, &request);
1089 if (ret)
1090 return ret;
1092 ret = krb5_store_stringz(request, k->name);
1093 if (ret) {
1094 krb5_storage_free(request);
1095 return ret;
1098 ret = krb5_store_int32(request, flags.i);
1099 if (ret) {
1100 krb5_storage_free(request);
1101 return ret;
1104 ret = krb5_store_int32(request, enctype);
1105 if (ret) {
1106 krb5_storage_free(request);
1107 return ret;
1110 ret = krb5_store_principal(request, server);
1111 if (ret) {
1112 krb5_storage_free(request);
1113 return ret;
1116 ret = kcm_call(context, k, request, NULL, NULL);
1118 krb5_storage_free(request);
1119 return ret;
1123 #endif /* HAVE_KCM */