heimdal: import heimdal's trunk svn rev 23697 + lorikeet-heimdal patches
[Samba/vfs_proxy.git] / source4 / heimdal / lib / krb5 / kcm.c
blobd5f38c5aaf8ce92dcd8bb3894de131966522cb38
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,
60 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;
74 rk_cloexec(fd);
76 arg.data_ptr = request_data->data;
77 arg.data_size = request_data->length;
78 arg.desc_ptr = NULL;
79 arg.desc_num = 0;
80 arg.rbuf = NULL;
81 arg.rsize = 0;
83 ret = door_call(fd, &arg);
84 close(fd);
85 if (ret != 0)
86 return KRB5_CC_IO;
88 ret = krb5_data_copy(response_data, arg.rbuf, arg.rsize);
89 munmap(arg.rbuf, arg.rsize);
90 if (ret)
91 return ret;
93 return 0;
94 #else
95 return KRB5_CC_IO;
96 #endif
99 static krb5_error_code
100 try_unix_socket(krb5_context context,
101 krb5_kcmcache *k,
102 krb5_data *request_data,
103 krb5_data *response_data)
105 krb5_error_code ret;
106 int fd;
108 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
109 if (fd < 0)
110 return KRB5_CC_IO;
111 rk_cloexec(fd);
113 if (connect(fd, rk_UNCONST(&k->path), sizeof(k->path)) != 0) {
114 close(fd);
115 return KRB5_CC_IO;
118 ret = _krb5_send_and_recv_tcp(fd, context->kdc_timeout,
119 request_data, response_data);
120 close(fd);
121 return ret;
124 static krb5_error_code
125 kcm_send_request(krb5_context context,
126 krb5_kcmcache *k,
127 krb5_storage *request,
128 krb5_data *response_data)
130 krb5_error_code ret;
131 krb5_data request_data;
132 int i;
134 response_data->data = NULL;
135 response_data->length = 0;
137 ret = krb5_storage_to_data(request, &request_data);
138 if (ret) {
139 krb5_clear_error_string(context);
140 return KRB5_CC_NOMEM;
143 ret = KRB5_CC_NOSUPP;
145 for (i = 0; i < context->max_retries; i++) {
146 ret = try_door(context, k, &request_data, response_data);
147 if (ret == 0 && response_data->length != 0)
148 break;
149 ret = try_unix_socket(context, k, &request_data, response_data);
150 if (ret == 0 && response_data->length != 0)
151 break;
154 krb5_data_free(&request_data);
156 if (ret) {
157 krb5_clear_error_string(context);
158 ret = KRB5_CC_NOSUPP;
161 return ret;
164 static krb5_error_code
165 kcm_storage_request(krb5_context context,
166 kcm_operation opcode,
167 krb5_storage **storage_p)
169 krb5_storage *sp;
170 krb5_error_code ret;
172 *storage_p = NULL;
174 sp = krb5_storage_emem();
175 if (sp == NULL) {
176 krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
177 return KRB5_CC_NOMEM;
180 /* Send MAJOR | VERSION | OPCODE */
181 ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR);
182 if (ret)
183 goto fail;
184 ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR);
185 if (ret)
186 goto fail;
187 ret = krb5_store_int16(sp, opcode);
188 if (ret)
189 goto fail;
191 *storage_p = sp;
192 fail:
193 if (ret) {
194 krb5_set_error_message(context, ret, "Failed to encode request");
195 krb5_storage_free(sp);
198 return ret;
201 static krb5_error_code
202 kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
204 krb5_kcmcache *k;
205 const char *path;
207 k = malloc(sizeof(*k));
208 if (k == NULL) {
209 krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
210 return KRB5_CC_NOMEM;
213 if (name != NULL) {
214 k->name = strdup(name);
215 if (k->name == NULL) {
216 free(k);
217 krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
218 return KRB5_CC_NOMEM;
220 } else
221 k->name = NULL;
223 path = krb5_config_get_string_default(context, NULL,
224 _PATH_KCM_SOCKET,
225 "libdefaults",
226 "kcm_socket",
227 NULL);
229 k->path.sun_family = AF_UNIX;
230 strlcpy(k->path.sun_path, path, sizeof(k->path.sun_path));
232 path = krb5_config_get_string_default(context, NULL,
233 _PATH_KCM_DOOR,
234 "libdefaults",
235 "kcm_door",
236 NULL);
237 k->door_path = strdup(path);
239 (*id)->data.data = k;
240 (*id)->data.length = sizeof(*k);
242 return 0;
245 static krb5_error_code
246 kcm_call(krb5_context context,
247 krb5_kcmcache *k,
248 krb5_storage *request,
249 krb5_storage **response_p,
250 krb5_data *response_data_p)
252 krb5_data response_data;
253 krb5_error_code ret;
254 int32_t status;
255 krb5_storage *response;
257 if (response_p != NULL)
258 *response_p = NULL;
260 ret = kcm_send_request(context, k, request, &response_data);
261 if (ret) {
262 return ret;
265 response = krb5_storage_from_data(&response_data);
266 if (response == NULL) {
267 krb5_data_free(&response_data);
268 return KRB5_CC_IO;
271 ret = krb5_ret_int32(response, &status);
272 if (ret) {
273 krb5_storage_free(response);
274 krb5_data_free(&response_data);
275 return KRB5_CC_FORMAT;
278 if (status) {
279 krb5_storage_free(response);
280 krb5_data_free(&response_data);
281 return status;
284 if (response_p != NULL) {
285 *response_data_p = response_data;
286 *response_p = response;
288 return 0;
291 krb5_storage_free(response);
292 krb5_data_free(&response_data);
294 return 0;
297 static void
298 kcm_free(krb5_context context, krb5_ccache *id)
300 krb5_kcmcache *k = KCMCACHE(*id);
302 if (k != NULL) {
303 if (k->name != NULL)
304 free(k->name);
305 if (k->door_path)
306 free(k->door_path);
307 memset(k, 0, sizeof(*k));
308 krb5_data_free(&(*id)->data);
311 *id = NULL;
314 static const char *
315 kcm_get_name(krb5_context context,
316 krb5_ccache id)
318 return CACHENAME(id);
321 static krb5_error_code
322 kcm_resolve(krb5_context context, krb5_ccache *id, const char *res)
324 return kcm_alloc(context, res, id);
328 * Request:
330 * Response:
331 * NameZ
333 static krb5_error_code
334 kcm_gen_new(krb5_context context, krb5_ccache *id)
336 krb5_kcmcache *k;
337 krb5_error_code ret;
338 krb5_storage *request, *response;
339 krb5_data response_data;
341 ret = kcm_alloc(context, NULL, id);
342 if (ret)
343 return ret;
345 k = KCMCACHE(*id);
347 ret = kcm_storage_request(context, KCM_OP_GEN_NEW, &request);
348 if (ret) {
349 kcm_free(context, id);
350 return ret;
353 ret = kcm_call(context, k, request, &response, &response_data);
354 if (ret) {
355 krb5_storage_free(request);
356 kcm_free(context, id);
357 return ret;
360 ret = krb5_ret_stringz(response, &k->name);
361 if (ret)
362 ret = KRB5_CC_IO;
364 krb5_storage_free(request);
365 krb5_storage_free(response);
366 krb5_data_free(&response_data);
368 if (ret)
369 kcm_free(context, id);
371 return ret;
375 * Request:
376 * NameZ
377 * Principal
379 * Response:
382 static krb5_error_code
383 kcm_initialize(krb5_context context,
384 krb5_ccache id,
385 krb5_principal primary_principal)
387 krb5_error_code ret;
388 krb5_kcmcache *k = KCMCACHE(id);
389 krb5_storage *request;
391 ret = kcm_storage_request(context, KCM_OP_INITIALIZE, &request);
392 if (ret)
393 return ret;
395 ret = krb5_store_stringz(request, k->name);
396 if (ret) {
397 krb5_storage_free(request);
398 return ret;
401 ret = krb5_store_principal(request, primary_principal);
402 if (ret) {
403 krb5_storage_free(request);
404 return ret;
407 ret = kcm_call(context, k, request, NULL, NULL);
409 krb5_storage_free(request);
410 return ret;
413 static krb5_error_code
414 kcm_close(krb5_context context,
415 krb5_ccache id)
417 kcm_free(context, &id);
418 return 0;
422 * Request:
423 * NameZ
425 * Response:
428 static krb5_error_code
429 kcm_destroy(krb5_context context,
430 krb5_ccache id)
432 krb5_error_code ret;
433 krb5_kcmcache *k = KCMCACHE(id);
434 krb5_storage *request;
436 ret = kcm_storage_request(context, KCM_OP_DESTROY, &request);
437 if (ret)
438 return ret;
440 ret = krb5_store_stringz(request, k->name);
441 if (ret) {
442 krb5_storage_free(request);
443 return ret;
446 ret = kcm_call(context, k, request, NULL, NULL);
448 krb5_storage_free(request);
449 return ret;
453 * Request:
454 * NameZ
455 * Creds
457 * Response:
460 static krb5_error_code
461 kcm_store_cred(krb5_context context,
462 krb5_ccache id,
463 krb5_creds *creds)
465 krb5_error_code ret;
466 krb5_kcmcache *k = KCMCACHE(id);
467 krb5_storage *request;
469 ret = kcm_storage_request(context, KCM_OP_STORE, &request);
470 if (ret)
471 return ret;
473 ret = krb5_store_stringz(request, k->name);
474 if (ret) {
475 krb5_storage_free(request);
476 return ret;
479 ret = krb5_store_creds(request, creds);
480 if (ret) {
481 krb5_storage_free(request);
482 return ret;
485 ret = kcm_call(context, k, request, NULL, NULL);
487 krb5_storage_free(request);
488 return ret;
492 * Request:
493 * NameZ
494 * WhichFields
495 * MatchCreds
497 * Response:
498 * Creds
501 static krb5_error_code
502 kcm_retrieve(krb5_context context,
503 krb5_ccache id,
504 krb5_flags which,
505 const krb5_creds *mcred,
506 krb5_creds *creds)
508 krb5_error_code ret;
509 krb5_kcmcache *k = KCMCACHE(id);
510 krb5_storage *request, *response;
511 krb5_data response_data;
513 ret = kcm_storage_request(context, KCM_OP_RETRIEVE, &request);
514 if (ret)
515 return ret;
517 ret = krb5_store_stringz(request, k->name);
518 if (ret) {
519 krb5_storage_free(request);
520 return ret;
523 ret = krb5_store_int32(request, which);
524 if (ret) {
525 krb5_storage_free(request);
526 return ret;
529 ret = krb5_store_creds_tag(request, rk_UNCONST(mcred));
530 if (ret) {
531 krb5_storage_free(request);
532 return ret;
535 ret = kcm_call(context, k, request, &response, &response_data);
536 if (ret) {
537 krb5_storage_free(request);
538 return ret;
541 ret = krb5_ret_creds(response, creds);
542 if (ret)
543 ret = KRB5_CC_IO;
545 krb5_storage_free(request);
546 krb5_storage_free(response);
547 krb5_data_free(&response_data);
549 return ret;
553 * Request:
554 * NameZ
556 * Response:
557 * Principal
559 static krb5_error_code
560 kcm_get_principal(krb5_context context,
561 krb5_ccache id,
562 krb5_principal *principal)
564 krb5_error_code ret;
565 krb5_kcmcache *k = KCMCACHE(id);
566 krb5_storage *request, *response;
567 krb5_data response_data;
569 ret = kcm_storage_request(context, KCM_OP_GET_PRINCIPAL, &request);
570 if (ret)
571 return ret;
573 ret = krb5_store_stringz(request, k->name);
574 if (ret) {
575 krb5_storage_free(request);
576 return ret;
579 ret = kcm_call(context, k, request, &response, &response_data);
580 if (ret) {
581 krb5_storage_free(request);
582 return ret;
585 ret = krb5_ret_principal(response, principal);
586 if (ret)
587 ret = KRB5_CC_IO;
589 krb5_storage_free(request);
590 krb5_storage_free(response);
591 krb5_data_free(&response_data);
593 return ret;
597 * Request:
598 * NameZ
600 * Response:
601 * Cursor
604 static krb5_error_code
605 kcm_get_first (krb5_context context,
606 krb5_ccache id,
607 krb5_cc_cursor *cursor)
609 krb5_error_code ret;
610 krb5_kcmcache *k = KCMCACHE(id);
611 krb5_storage *request, *response;
612 krb5_data response_data;
613 int32_t tmp;
615 ret = kcm_storage_request(context, KCM_OP_GET_FIRST, &request);
616 if (ret)
617 return ret;
619 ret = krb5_store_stringz(request, k->name);
620 if (ret) {
621 krb5_storage_free(request);
622 return ret;
625 ret = kcm_call(context, k, request, &response, &response_data);
626 if (ret) {
627 krb5_storage_free(request);
628 return ret;
631 ret = krb5_ret_int32(response, &tmp);
632 if (ret || tmp < 0)
633 ret = KRB5_CC_IO;
635 krb5_storage_free(request);
636 krb5_storage_free(response);
637 krb5_data_free(&response_data);
639 if (ret)
640 return ret;
642 *cursor = malloc(sizeof(tmp));
643 if (*cursor == NULL)
644 return KRB5_CC_NOMEM;
646 KCMCURSOR(*cursor) = tmp;
648 return 0;
652 * Request:
653 * NameZ
654 * Cursor
656 * Response:
657 * Creds
659 static krb5_error_code
660 kcm_get_next (krb5_context context,
661 krb5_ccache id,
662 krb5_cc_cursor *cursor,
663 krb5_creds *creds)
665 krb5_error_code ret;
666 krb5_kcmcache *k = KCMCACHE(id);
667 krb5_storage *request, *response;
668 krb5_data response_data;
670 ret = kcm_storage_request(context, KCM_OP_GET_NEXT, &request);
671 if (ret)
672 return ret;
674 ret = krb5_store_stringz(request, k->name);
675 if (ret) {
676 krb5_storage_free(request);
677 return ret;
680 ret = krb5_store_int32(request, KCMCURSOR(*cursor));
681 if (ret) {
682 krb5_storage_free(request);
683 return ret;
686 ret = kcm_call(context, k, request, &response, &response_data);
687 if (ret) {
688 krb5_storage_free(request);
689 return ret;
692 ret = krb5_ret_creds(response, creds);
693 if (ret)
694 ret = KRB5_CC_IO;
696 krb5_storage_free(request);
697 krb5_storage_free(response);
698 krb5_data_free(&response_data);
700 return ret;
704 * Request:
705 * NameZ
706 * Cursor
708 * Response:
711 static krb5_error_code
712 kcm_end_get (krb5_context context,
713 krb5_ccache id,
714 krb5_cc_cursor *cursor)
716 krb5_error_code ret;
717 krb5_kcmcache *k = KCMCACHE(id);
718 krb5_storage *request;
720 ret = kcm_storage_request(context, KCM_OP_END_GET, &request);
721 if (ret)
722 return ret;
724 ret = krb5_store_stringz(request, k->name);
725 if (ret) {
726 krb5_storage_free(request);
727 return ret;
730 ret = krb5_store_int32(request, KCMCURSOR(*cursor));
731 if (ret) {
732 krb5_storage_free(request);
733 return ret;
736 ret = kcm_call(context, k, request, NULL, NULL);
737 if (ret) {
738 krb5_storage_free(request);
739 return ret;
742 krb5_storage_free(request);
744 KCMCURSOR(*cursor) = 0;
745 free(*cursor);
746 *cursor = NULL;
748 return ret;
752 * Request:
753 * NameZ
754 * WhichFields
755 * MatchCreds
757 * Response:
760 static krb5_error_code
761 kcm_remove_cred(krb5_context context,
762 krb5_ccache id,
763 krb5_flags which,
764 krb5_creds *cred)
766 krb5_error_code ret;
767 krb5_kcmcache *k = KCMCACHE(id);
768 krb5_storage *request;
770 ret = kcm_storage_request(context, KCM_OP_REMOVE_CRED, &request);
771 if (ret)
772 return ret;
774 ret = krb5_store_stringz(request, k->name);
775 if (ret) {
776 krb5_storage_free(request);
777 return ret;
780 ret = krb5_store_int32(request, which);
781 if (ret) {
782 krb5_storage_free(request);
783 return ret;
786 ret = krb5_store_creds_tag(request, cred);
787 if (ret) {
788 krb5_storage_free(request);
789 return ret;
792 ret = kcm_call(context, k, request, NULL, NULL);
794 krb5_storage_free(request);
795 return ret;
798 static krb5_error_code
799 kcm_set_flags(krb5_context context,
800 krb5_ccache id,
801 krb5_flags flags)
803 krb5_error_code ret;
804 krb5_kcmcache *k = KCMCACHE(id);
805 krb5_storage *request;
807 ret = kcm_storage_request(context, KCM_OP_SET_FLAGS, &request);
808 if (ret)
809 return ret;
811 ret = krb5_store_stringz(request, k->name);
812 if (ret) {
813 krb5_storage_free(request);
814 return ret;
817 ret = krb5_store_int32(request, flags);
818 if (ret) {
819 krb5_storage_free(request);
820 return ret;
823 ret = kcm_call(context, k, request, NULL, NULL);
825 krb5_storage_free(request);
826 return ret;
829 static int
830 kcm_get_version(krb5_context context,
831 krb5_ccache id)
833 return 0;
836 static krb5_error_code
837 kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
839 krb5_error_code ret;
840 krb5_kcmcache *oldk = KCMCACHE(from);
841 krb5_kcmcache *newk = KCMCACHE(to);
842 krb5_storage *request;
844 ret = kcm_storage_request(context, KCM_OP_MOVE_CACHE, &request);
845 if (ret)
846 return ret;
848 ret = krb5_store_stringz(request, oldk->name);
849 if (ret) {
850 krb5_storage_free(request);
851 return ret;
854 ret = krb5_store_stringz(request, newk->name);
855 if (ret) {
856 krb5_storage_free(request);
857 return ret;
859 ret = kcm_call(context, oldk, request, NULL, NULL);
861 krb5_storage_free(request);
862 return ret;
865 static krb5_error_code
866 kcm_default_name(krb5_context context, char **str)
868 return _krb5_expand_default_cc_name(context,
869 KRB5_DEFAULT_CCNAME_KCM,
870 str);
874 * Variable containing the KCM based credential cache implemention.
876 * @ingroup krb5_ccache
879 KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops = {
880 KRB5_CC_OPS_VERSION,
881 "KCM",
882 kcm_get_name,
883 kcm_resolve,
884 kcm_gen_new,
885 kcm_initialize,
886 kcm_destroy,
887 kcm_close,
888 kcm_store_cred,
889 kcm_retrieve,
890 kcm_get_principal,
891 kcm_get_first,
892 kcm_get_next,
893 kcm_end_get,
894 kcm_remove_cred,
895 kcm_set_flags,
896 kcm_get_version,
897 NULL,
898 NULL,
899 NULL,
900 kcm_move,
901 kcm_default_name
904 krb5_boolean
905 _krb5_kcm_is_running(krb5_context context)
907 krb5_error_code ret;
908 krb5_ccache_data ccdata;
909 krb5_ccache id = &ccdata;
910 krb5_boolean running;
912 ret = kcm_alloc(context, NULL, &id);
913 if (ret)
914 return 0;
916 running = (_krb5_kcm_noop(context, id) == 0);
918 kcm_free(context, &id);
920 return running;
924 * Request:
926 * Response:
929 krb5_error_code
930 _krb5_kcm_noop(krb5_context context,
931 krb5_ccache id)
933 krb5_error_code ret;
934 krb5_kcmcache *k = KCMCACHE(id);
935 krb5_storage *request;
937 ret = kcm_storage_request(context, KCM_OP_NOOP, &request);
938 if (ret)
939 return ret;
941 ret = kcm_call(context, k, request, NULL, NULL);
943 krb5_storage_free(request);
944 return ret;
949 * Request:
950 * NameZ
951 * Mode
953 * Response:
956 krb5_error_code
957 _krb5_kcm_chmod(krb5_context context,
958 krb5_ccache id,
959 uint16_t mode)
961 krb5_error_code ret;
962 krb5_kcmcache *k = KCMCACHE(id);
963 krb5_storage *request;
965 ret = kcm_storage_request(context, KCM_OP_CHMOD, &request);
966 if (ret)
967 return ret;
969 ret = krb5_store_stringz(request, k->name);
970 if (ret) {
971 krb5_storage_free(request);
972 return ret;
975 ret = krb5_store_int16(request, mode);
976 if (ret) {
977 krb5_storage_free(request);
978 return ret;
981 ret = kcm_call(context, k, request, NULL, NULL);
983 krb5_storage_free(request);
984 return ret;
989 * Request:
990 * NameZ
991 * UID
992 * GID
994 * Response:
997 krb5_error_code
998 _krb5_kcm_chown(krb5_context context,
999 krb5_ccache id,
1000 uint32_t uid,
1001 uint32_t gid)
1003 krb5_error_code ret;
1004 krb5_kcmcache *k = KCMCACHE(id);
1005 krb5_storage *request;
1007 ret = kcm_storage_request(context, KCM_OP_CHOWN, &request);
1008 if (ret)
1009 return ret;
1011 ret = krb5_store_stringz(request, k->name);
1012 if (ret) {
1013 krb5_storage_free(request);
1014 return ret;
1017 ret = krb5_store_int32(request, uid);
1018 if (ret) {
1019 krb5_storage_free(request);
1020 return ret;
1023 ret = krb5_store_int32(request, gid);
1024 if (ret) {
1025 krb5_storage_free(request);
1026 return ret;
1029 ret = kcm_call(context, k, request, NULL, NULL);
1031 krb5_storage_free(request);
1032 return ret;
1037 * Request:
1038 * NameZ
1039 * ServerPrincipalPresent
1040 * ServerPrincipal OPTIONAL
1041 * Key
1043 * Repsonse:
1046 krb5_error_code
1047 _krb5_kcm_get_initial_ticket(krb5_context context,
1048 krb5_ccache id,
1049 krb5_principal server,
1050 krb5_keyblock *key)
1052 krb5_error_code ret;
1053 krb5_kcmcache *k = KCMCACHE(id);
1054 krb5_storage *request;
1056 ret = kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
1057 if (ret)
1058 return ret;
1060 ret = krb5_store_stringz(request, k->name);
1061 if (ret) {
1062 krb5_storage_free(request);
1063 return ret;
1066 ret = krb5_store_int8(request, (server == NULL) ? 0 : 1);
1067 if (ret) {
1068 krb5_storage_free(request);
1069 return ret;
1072 if (server != NULL) {
1073 ret = krb5_store_principal(request, server);
1074 if (ret) {
1075 krb5_storage_free(request);
1076 return ret;
1080 ret = krb5_store_keyblock(request, *key);
1081 if (ret) {
1082 krb5_storage_free(request);
1083 return ret;
1086 ret = kcm_call(context, k, request, NULL, NULL);
1088 krb5_storage_free(request);
1089 return ret;
1094 * Request:
1095 * NameZ
1096 * KDCFlags
1097 * EncryptionType
1098 * ServerPrincipal
1100 * Repsonse:
1103 krb5_error_code
1104 _krb5_kcm_get_ticket(krb5_context context,
1105 krb5_ccache id,
1106 krb5_kdc_flags flags,
1107 krb5_enctype enctype,
1108 krb5_principal server)
1110 krb5_error_code ret;
1111 krb5_kcmcache *k = KCMCACHE(id);
1112 krb5_storage *request;
1114 ret = kcm_storage_request(context, KCM_OP_GET_TICKET, &request);
1115 if (ret)
1116 return ret;
1118 ret = krb5_store_stringz(request, k->name);
1119 if (ret) {
1120 krb5_storage_free(request);
1121 return ret;
1124 ret = krb5_store_int32(request, flags.i);
1125 if (ret) {
1126 krb5_storage_free(request);
1127 return ret;
1130 ret = krb5_store_int32(request, enctype);
1131 if (ret) {
1132 krb5_storage_free(request);
1133 return ret;
1136 ret = krb5_store_principal(request, server);
1137 if (ret) {
1138 krb5_storage_free(request);
1139 return ret;
1142 ret = kcm_call(context, k, request, NULL, NULL);
1144 krb5_storage_free(request);
1145 return ret;
1148 #endif /* HAVE_KCM */