test debug
[heimdal.git] / lib / krb5 / kcm.c
blobe19dda8966152f9590a422aaaf4198b98a2e26f6
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("$Id$");
48 typedef struct krb5_kcmcache {
49 char *name;
50 struct sockaddr_un path;
51 char *door_path;
52 } krb5_kcmcache;
54 #define KCMCACHE(X) ((krb5_kcmcache *)(X)->data.data)
55 #define CACHENAME(X) (KCMCACHE(X)->name)
56 #define KCMCURSOR(C) (*(uint32_t *)(C))
58 static krb5_error_code
59 try_door(krb5_context context, const krb5_kcmcache *k,
60 krb5_data *request_data,
61 krb5_data *response_data)
63 #ifdef HAVE_DOOR_CREATE
64 door_arg_t arg;
65 int fd;
66 int ret;
68 memset(&arg, 0, sizeof(arg));
70 fd = open(k->door_path, O_RDWR);
71 if (fd < 0)
72 return KRB5_CC_IO;
74 arg.data_ptr = request_data->data;
75 arg.data_size = request_data->length;
76 arg.desc_ptr = NULL;
77 arg.desc_num = 0;
78 arg.rbuf = NULL;
79 arg.rsize = 0;
81 ret = door_call(fd, &arg);
82 close(fd);
83 if (ret != 0)
84 return KRB5_CC_IO;
86 ret = krb5_data_copy(response_data, arg.rbuf, arg.rsize);
87 munmap(arg.rbuf, arg.rsize);
88 if (ret)
89 return ret;
91 return 0;
92 #else
93 return KRB5_CC_IO;
94 #endif
97 static krb5_error_code
98 try_unix_socket(krb5_context context, const krb5_kcmcache *k,
99 krb5_data *request_data,
100 krb5_data *response_data)
102 krb5_error_code ret;
103 int fd;
105 fd = socket(AF_UNIX, SOCK_STREAM, 0);
106 if (fd < 0)
107 return KRB5_CC_IO;
109 if (connect(fd, rk_UNCONST(&k->path), sizeof(k->path)) != 0) {
110 close(fd);
111 return KRB5_CC_IO;
114 ret = _krb5_send_and_recv_tcp(fd, context->kdc_timeout,
115 request_data, response_data);
116 close(fd);
117 return ret;
120 static krb5_error_code
121 kcm_send_request(krb5_context context,
122 krb5_kcmcache *k,
123 krb5_storage *request,
124 krb5_data *response_data)
126 krb5_error_code ret;
127 krb5_data request_data;
128 int i;
130 response_data->data = NULL;
131 response_data->length = 0;
133 ret = krb5_storage_to_data(request, &request_data);
134 if (ret) {
135 krb5_clear_error_string(context);
136 return KRB5_CC_NOMEM;
139 ret = KRB5_CC_IO;
141 for (i = 0; i < context->max_retries; i++) {
142 ret = try_door(context, k, &request_data, response_data);
143 if (ret == 0 && response_data->length != 0)
144 break;
145 ret = try_unix_socket(context, k, &request_data, response_data);
146 if (ret == 0 && response_data->length != 0)
147 break;
150 krb5_data_free(&request_data);
152 if (ret) {
153 krb5_clear_error_string(context);
154 ret = KRB5_CC_IO;
157 return ret;
160 static krb5_error_code
161 kcm_storage_request(krb5_context context,
162 kcm_operation opcode,
163 krb5_storage **storage_p)
165 krb5_storage *sp;
166 krb5_error_code ret;
168 *storage_p = NULL;
170 sp = krb5_storage_emem();
171 if (sp == NULL) {
172 krb5_set_error_string(context, "malloc: out of memory");
173 return KRB5_CC_NOMEM;
176 /* Send MAJOR | VERSION | OPCODE */
177 ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR);
178 if (ret)
179 goto fail;
180 ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR);
181 if (ret)
182 goto fail;
183 ret = krb5_store_int16(sp, opcode);
184 if (ret)
185 goto fail;
187 *storage_p = sp;
188 fail:
189 if (ret) {
190 krb5_set_error_string(context, "Failed to encode request");
191 krb5_storage_free(sp);
194 return ret;
197 static krb5_error_code
198 kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
200 krb5_kcmcache *k;
201 const char *path;
203 k = malloc(sizeof(*k));
204 if (k == NULL) {
205 krb5_set_error_string(context, "malloc: out of memory");
206 return KRB5_CC_NOMEM;
209 if (name != NULL) {
210 k->name = strdup(name);
211 if (k->name == NULL) {
212 free(k);
213 krb5_set_error_string(context, "malloc: out of memory");
214 return KRB5_CC_NOMEM;
216 } else
217 k->name = NULL;
219 path = krb5_config_get_string_default(context, NULL,
220 _PATH_KCM_SOCKET,
221 "libdefaults",
222 "kcm_socket",
223 NULL);
225 k->path.sun_family = AF_UNIX;
226 strlcpy(k->path.sun_path, path, sizeof(k->path.sun_path));
228 path = krb5_config_get_string_default(context, NULL,
229 _PATH_KCM_DOOR,
230 "libdefaults",
231 "kcm_door",
232 NULL);
233 k->door_path = strdup(path);
235 (*id)->data.data = k;
236 (*id)->data.length = sizeof(*k);
238 return 0;
241 static krb5_error_code
242 kcm_call(krb5_context context,
243 krb5_kcmcache *k,
244 krb5_storage *request,
245 krb5_storage **response_p,
246 krb5_data *response_data_p)
248 krb5_data response_data;
249 krb5_error_code ret;
250 int32_t status;
251 krb5_storage *response;
253 if (response_p != NULL)
254 *response_p = NULL;
256 ret = kcm_send_request(context, k, request, &response_data);
257 if (ret) {
258 return ret;
261 response = krb5_storage_from_data(&response_data);
262 if (response == NULL) {
263 krb5_data_free(&response_data);
264 return KRB5_CC_IO;
267 ret = krb5_ret_int32(response, &status);
268 if (ret) {
269 krb5_storage_free(response);
270 krb5_data_free(&response_data);
271 return KRB5_CC_FORMAT;
274 if (status) {
275 krb5_storage_free(response);
276 krb5_data_free(&response_data);
277 return status;
280 if (response_p != NULL) {
281 *response_data_p = response_data;
282 *response_p = response;
284 return 0;
287 krb5_storage_free(response);
288 krb5_data_free(&response_data);
290 return 0;
293 static void
294 kcm_free(krb5_context context, krb5_ccache *id)
296 krb5_kcmcache *k = KCMCACHE(*id);
298 if (k != NULL) {
299 if (k->name != NULL)
300 free(k->name);
301 if (k->door_path)
302 free(k->door_path);
303 memset(k, 0, sizeof(*k));
304 krb5_data_free(&(*id)->data);
307 *id = NULL;
310 static const char *
311 kcm_get_name(krb5_context context,
312 krb5_ccache id)
314 return CACHENAME(id);
317 static krb5_error_code
318 kcm_resolve(krb5_context context, krb5_ccache *id, const char *res)
320 return kcm_alloc(context, res, id);
324 * Request:
326 * Response:
327 * NameZ
329 static krb5_error_code
330 kcm_gen_new(krb5_context context, krb5_ccache *id)
332 krb5_kcmcache *k;
333 krb5_error_code ret;
334 krb5_storage *request, *response;
335 krb5_data response_data;
337 ret = kcm_alloc(context, NULL, id);
338 if (ret)
339 return ret;
341 k = KCMCACHE(*id);
343 ret = kcm_storage_request(context, KCM_OP_GEN_NEW, &request);
344 if (ret) {
345 kcm_free(context, id);
346 return ret;
349 ret = kcm_call(context, k, request, &response, &response_data);
350 if (ret) {
351 krb5_storage_free(request);
352 kcm_free(context, id);
353 return ret;
356 ret = krb5_ret_stringz(response, &k->name);
357 if (ret)
358 ret = KRB5_CC_IO;
360 krb5_storage_free(request);
361 krb5_storage_free(response);
362 krb5_data_free(&response_data);
364 if (ret)
365 kcm_free(context, id);
367 return ret;
371 * Request:
372 * NameZ
373 * Principal
375 * Response:
378 static krb5_error_code
379 kcm_initialize(krb5_context context,
380 krb5_ccache id,
381 krb5_principal primary_principal)
383 krb5_error_code ret;
384 krb5_kcmcache *k = KCMCACHE(id);
385 krb5_storage *request;
387 ret = kcm_storage_request(context, KCM_OP_INITIALIZE, &request);
388 if (ret)
389 return ret;
391 ret = krb5_store_stringz(request, k->name);
392 if (ret) {
393 krb5_storage_free(request);
394 return ret;
397 ret = krb5_store_principal(request, primary_principal);
398 if (ret) {
399 krb5_storage_free(request);
400 return ret;
403 ret = kcm_call(context, k, request, NULL, NULL);
405 krb5_storage_free(request);
406 return ret;
409 static krb5_error_code
410 kcm_close(krb5_context context,
411 krb5_ccache id)
413 kcm_free(context, &id);
414 return 0;
418 * Request:
419 * NameZ
421 * Response:
424 static krb5_error_code
425 kcm_destroy(krb5_context context,
426 krb5_ccache id)
428 krb5_error_code ret;
429 krb5_kcmcache *k = KCMCACHE(id);
430 krb5_storage *request;
432 ret = kcm_storage_request(context, KCM_OP_DESTROY, &request);
433 if (ret)
434 return ret;
436 ret = krb5_store_stringz(request, k->name);
437 if (ret) {
438 krb5_storage_free(request);
439 return ret;
442 ret = kcm_call(context, k, request, NULL, NULL);
444 krb5_storage_free(request);
445 return ret;
449 * Request:
450 * NameZ
451 * Creds
453 * Response:
456 static krb5_error_code
457 kcm_store_cred(krb5_context context,
458 krb5_ccache id,
459 krb5_creds *creds)
461 krb5_error_code ret;
462 krb5_kcmcache *k = KCMCACHE(id);
463 krb5_storage *request;
465 ret = kcm_storage_request(context, KCM_OP_STORE, &request);
466 if (ret)
467 return ret;
469 ret = krb5_store_stringz(request, k->name);
470 if (ret) {
471 krb5_storage_free(request);
472 return ret;
475 ret = krb5_store_creds(request, creds);
476 if (ret) {
477 krb5_storage_free(request);
478 return ret;
481 ret = kcm_call(context, k, request, NULL, NULL);
483 krb5_storage_free(request);
484 return ret;
488 * Request:
489 * NameZ
490 * WhichFields
491 * MatchCreds
493 * Response:
494 * Creds
497 static krb5_error_code
498 kcm_retrieve(krb5_context context,
499 krb5_ccache id,
500 krb5_flags which,
501 const krb5_creds *mcred,
502 krb5_creds *creds)
504 krb5_error_code ret;
505 krb5_kcmcache *k = KCMCACHE(id);
506 krb5_storage *request, *response;
507 krb5_data response_data;
509 ret = kcm_storage_request(context, KCM_OP_RETRIEVE, &request);
510 if (ret)
511 return ret;
513 ret = krb5_store_stringz(request, k->name);
514 if (ret) {
515 krb5_storage_free(request);
516 return ret;
519 ret = krb5_store_int32(request, which);
520 if (ret) {
521 krb5_storage_free(request);
522 return ret;
525 ret = krb5_store_creds_tag(request, rk_UNCONST(mcred));
526 if (ret) {
527 krb5_storage_free(request);
528 return ret;
531 ret = kcm_call(context, k, request, &response, &response_data);
532 if (ret) {
533 krb5_storage_free(request);
534 return ret;
537 ret = krb5_ret_creds(response, creds);
538 if (ret)
539 ret = KRB5_CC_IO;
541 krb5_storage_free(request);
542 krb5_storage_free(response);
543 krb5_data_free(&response_data);
545 return ret;
549 * Request:
550 * NameZ
552 * Response:
553 * Principal
555 static krb5_error_code
556 kcm_get_principal(krb5_context context,
557 krb5_ccache id,
558 krb5_principal *principal)
560 krb5_error_code ret;
561 krb5_kcmcache *k = KCMCACHE(id);
562 krb5_storage *request, *response;
563 krb5_data response_data;
565 ret = kcm_storage_request(context, KCM_OP_GET_PRINCIPAL, &request);
566 if (ret)
567 return ret;
569 ret = krb5_store_stringz(request, k->name);
570 if (ret) {
571 krb5_storage_free(request);
572 return ret;
575 ret = kcm_call(context, k, request, &response, &response_data);
576 if (ret) {
577 krb5_storage_free(request);
578 return ret;
581 ret = krb5_ret_principal(response, principal);
582 if (ret)
583 ret = KRB5_CC_IO;
585 krb5_storage_free(request);
586 krb5_storage_free(response);
587 krb5_data_free(&response_data);
589 return ret;
593 * Request:
594 * NameZ
596 * Response:
597 * Cursor
600 static krb5_error_code
601 kcm_get_first (krb5_context context,
602 krb5_ccache id,
603 krb5_cc_cursor *cursor)
605 krb5_error_code ret;
606 krb5_kcmcache *k = KCMCACHE(id);
607 krb5_storage *request, *response;
608 krb5_data response_data;
609 int32_t tmp;
611 ret = kcm_storage_request(context, KCM_OP_GET_FIRST, &request);
612 if (ret)
613 return ret;
615 ret = krb5_store_stringz(request, k->name);
616 if (ret) {
617 krb5_storage_free(request);
618 return ret;
621 ret = kcm_call(context, k, request, &response, &response_data);
622 if (ret) {
623 krb5_storage_free(request);
624 return ret;
627 ret = krb5_ret_int32(response, &tmp);
628 if (ret || tmp < 0)
629 ret = KRB5_CC_IO;
631 krb5_storage_free(request);
632 krb5_storage_free(response);
633 krb5_data_free(&response_data);
635 if (ret)
636 return ret;
638 *cursor = malloc(sizeof(tmp));
639 if (*cursor == NULL)
640 return KRB5_CC_NOMEM;
642 KCMCURSOR(*cursor) = tmp;
644 return 0;
648 * Request:
649 * NameZ
650 * Cursor
652 * Response:
653 * Creds
655 static krb5_error_code
656 kcm_get_next (krb5_context context,
657 krb5_ccache id,
658 krb5_cc_cursor *cursor,
659 krb5_creds *creds)
661 krb5_error_code ret;
662 krb5_kcmcache *k = KCMCACHE(id);
663 krb5_storage *request, *response;
664 krb5_data response_data;
666 ret = kcm_storage_request(context, KCM_OP_GET_NEXT, &request);
667 if (ret)
668 return ret;
670 ret = krb5_store_stringz(request, k->name);
671 if (ret) {
672 krb5_storage_free(request);
673 return ret;
676 ret = krb5_store_int32(request, KCMCURSOR(*cursor));
677 if (ret) {
678 krb5_storage_free(request);
679 return ret;
682 ret = kcm_call(context, k, request, &response, &response_data);
683 if (ret) {
684 krb5_storage_free(request);
685 return ret;
688 ret = krb5_ret_creds(response, creds);
689 if (ret)
690 ret = KRB5_CC_IO;
692 krb5_storage_free(request);
693 krb5_storage_free(response);
694 krb5_data_free(&response_data);
696 return ret;
700 * Request:
701 * NameZ
702 * Cursor
704 * Response:
707 static krb5_error_code
708 kcm_end_get (krb5_context context,
709 krb5_ccache id,
710 krb5_cc_cursor *cursor)
712 krb5_error_code ret;
713 krb5_kcmcache *k = KCMCACHE(id);
714 krb5_storage *request;
716 ret = kcm_storage_request(context, KCM_OP_END_GET, &request);
717 if (ret)
718 return ret;
720 ret = krb5_store_stringz(request, k->name);
721 if (ret) {
722 krb5_storage_free(request);
723 return ret;
726 ret = krb5_store_int32(request, KCMCURSOR(*cursor));
727 if (ret) {
728 krb5_storage_free(request);
729 return ret;
732 ret = kcm_call(context, k, request, NULL, NULL);
733 if (ret) {
734 krb5_storage_free(request);
735 return ret;
738 krb5_storage_free(request);
740 KCMCURSOR(*cursor) = 0;
741 free(*cursor);
742 *cursor = NULL;
744 return ret;
748 * Request:
749 * NameZ
750 * WhichFields
751 * MatchCreds
753 * Response:
756 static krb5_error_code
757 kcm_remove_cred(krb5_context context,
758 krb5_ccache id,
759 krb5_flags which,
760 krb5_creds *cred)
762 krb5_error_code ret;
763 krb5_kcmcache *k = KCMCACHE(id);
764 krb5_storage *request;
766 ret = kcm_storage_request(context, KCM_OP_REMOVE_CRED, &request);
767 if (ret)
768 return ret;
770 ret = krb5_store_stringz(request, k->name);
771 if (ret) {
772 krb5_storage_free(request);
773 return ret;
776 ret = krb5_store_int32(request, which);
777 if (ret) {
778 krb5_storage_free(request);
779 return ret;
782 ret = krb5_store_creds_tag(request, cred);
783 if (ret) {
784 krb5_storage_free(request);
785 return ret;
788 ret = kcm_call(context, k, request, NULL, NULL);
790 krb5_storage_free(request);
791 return ret;
794 static krb5_error_code
795 kcm_set_flags(krb5_context context,
796 krb5_ccache id,
797 krb5_flags flags)
799 krb5_error_code ret;
800 krb5_kcmcache *k = KCMCACHE(id);
801 krb5_storage *request;
803 ret = kcm_storage_request(context, KCM_OP_SET_FLAGS, &request);
804 if (ret)
805 return ret;
807 ret = krb5_store_stringz(request, k->name);
808 if (ret) {
809 krb5_storage_free(request);
810 return ret;
813 ret = krb5_store_int32(request, flags);
814 if (ret) {
815 krb5_storage_free(request);
816 return ret;
819 ret = kcm_call(context, k, request, NULL, NULL);
821 krb5_storage_free(request);
822 return ret;
825 static krb5_error_code
826 kcm_get_version(krb5_context context,
827 krb5_ccache id)
829 return 0;
832 static krb5_error_code
833 kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
835 krb5_set_error_string(context, "kcm_move not implemented");
836 return EINVAL;
839 static krb5_error_code
840 kcm_default_name(krb5_context context, char **str)
842 return _krb5_expand_default_cc_name(context,
843 KRB5_DEFAULT_CCNAME_KCM,
844 str);
848 * Variable containing the KCM based credential cache implemention.
850 * @ingroup krb5_ccache
853 const krb5_cc_ops krb5_kcm_ops = {
854 "KCM",
855 kcm_get_name,
856 kcm_resolve,
857 kcm_gen_new,
858 kcm_initialize,
859 kcm_destroy,
860 kcm_close,
861 kcm_store_cred,
862 kcm_retrieve,
863 kcm_get_principal,
864 kcm_get_first,
865 kcm_get_next,
866 kcm_end_get,
867 kcm_remove_cred,
868 kcm_set_flags,
869 kcm_get_version,
870 NULL,
871 NULL,
872 NULL,
873 kcm_move,
874 kcm_default_name
877 krb5_boolean
878 _krb5_kcm_is_running(krb5_context context)
880 krb5_error_code ret;
881 krb5_ccache_data ccdata;
882 krb5_ccache id = &ccdata;
883 krb5_boolean running;
885 ret = kcm_alloc(context, NULL, &id);
886 if (ret)
887 return 0;
889 running = (_krb5_kcm_noop(context, id) == 0);
891 kcm_free(context, &id);
893 return running;
897 * Request:
899 * Response:
902 krb5_error_code
903 _krb5_kcm_noop(krb5_context context,
904 krb5_ccache id)
906 krb5_error_code ret;
907 krb5_kcmcache *k = KCMCACHE(id);
908 krb5_storage *request;
910 ret = kcm_storage_request(context, KCM_OP_NOOP, &request);
911 if (ret)
912 return ret;
914 ret = kcm_call(context, k, request, NULL, NULL);
916 krb5_storage_free(request);
917 return ret;
922 * Request:
923 * NameZ
924 * Mode
926 * Response:
929 krb5_error_code
930 _krb5_kcm_chmod(krb5_context context,
931 krb5_ccache id,
932 uint16_t mode)
934 krb5_error_code ret;
935 krb5_kcmcache *k = KCMCACHE(id);
936 krb5_storage *request;
938 ret = kcm_storage_request(context, KCM_OP_CHMOD, &request);
939 if (ret)
940 return ret;
942 ret = krb5_store_stringz(request, k->name);
943 if (ret) {
944 krb5_storage_free(request);
945 return ret;
948 ret = krb5_store_int16(request, mode);
949 if (ret) {
950 krb5_storage_free(request);
951 return ret;
954 ret = kcm_call(context, k, request, NULL, NULL);
956 krb5_storage_free(request);
957 return ret;
962 * Request:
963 * NameZ
964 * UID
965 * GID
967 * Response:
970 krb5_error_code
971 _krb5_kcm_chown(krb5_context context,
972 krb5_ccache id,
973 uint32_t uid,
974 uint32_t gid)
976 krb5_error_code ret;
977 krb5_kcmcache *k = KCMCACHE(id);
978 krb5_storage *request;
980 ret = kcm_storage_request(context, KCM_OP_CHOWN, &request);
981 if (ret)
982 return ret;
984 ret = krb5_store_stringz(request, k->name);
985 if (ret) {
986 krb5_storage_free(request);
987 return ret;
990 ret = krb5_store_int32(request, uid);
991 if (ret) {
992 krb5_storage_free(request);
993 return ret;
996 ret = krb5_store_int32(request, gid);
997 if (ret) {
998 krb5_storage_free(request);
999 return ret;
1002 ret = kcm_call(context, k, request, NULL, NULL);
1004 krb5_storage_free(request);
1005 return ret;
1010 * Request:
1011 * NameZ
1012 * ServerPrincipalPresent
1013 * ServerPrincipal OPTIONAL
1014 * Key
1016 * Repsonse:
1019 krb5_error_code
1020 _krb5_kcm_get_initial_ticket(krb5_context context,
1021 krb5_ccache id,
1022 krb5_principal server,
1023 krb5_keyblock *key)
1025 krb5_error_code ret;
1026 krb5_kcmcache *k = KCMCACHE(id);
1027 krb5_storage *request;
1029 ret = kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
1030 if (ret)
1031 return ret;
1033 ret = krb5_store_stringz(request, k->name);
1034 if (ret) {
1035 krb5_storage_free(request);
1036 return ret;
1039 ret = krb5_store_int8(request, (server == NULL) ? 0 : 1);
1040 if (ret) {
1041 krb5_storage_free(request);
1042 return ret;
1045 if (server != NULL) {
1046 ret = krb5_store_principal(request, server);
1047 if (ret) {
1048 krb5_storage_free(request);
1049 return ret;
1053 ret = krb5_store_keyblock(request, *key);
1054 if (ret) {
1055 krb5_storage_free(request);
1056 return ret;
1059 ret = kcm_call(context, k, request, NULL, NULL);
1061 krb5_storage_free(request);
1062 return ret;
1067 * Request:
1068 * NameZ
1069 * KDCFlags
1070 * EncryptionType
1071 * ServerPrincipal
1073 * Repsonse:
1076 krb5_error_code
1077 _krb5_kcm_get_ticket(krb5_context context,
1078 krb5_ccache id,
1079 krb5_kdc_flags flags,
1080 krb5_enctype enctype,
1081 krb5_principal server)
1083 krb5_error_code ret;
1084 krb5_kcmcache *k = KCMCACHE(id);
1085 krb5_storage *request;
1087 ret = kcm_storage_request(context, KCM_OP_GET_TICKET, &request);
1088 if (ret)
1089 return ret;
1091 ret = krb5_store_stringz(request, k->name);
1092 if (ret) {
1093 krb5_storage_free(request);
1094 return ret;
1097 ret = krb5_store_int32(request, flags.i);
1098 if (ret) {
1099 krb5_storage_free(request);
1100 return ret;
1103 ret = krb5_store_int32(request, enctype);
1104 if (ret) {
1105 krb5_storage_free(request);
1106 return ret;
1109 ret = krb5_store_principal(request, server);
1110 if (ret) {
1111 krb5_storage_free(request);
1112 return ret;
1115 ret = kcm_call(context, k, request, NULL, NULL);
1117 krb5_storage_free(request);
1118 return ret;
1122 #endif /* HAVE_KCM */