17c478bd9Sstevel@tonic-gate /*
2a0a37ffdSShawn Emery * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate * lib/krb5/krb/init_ctx.c
87c478bd9Sstevel@tonic-gate *
9505d05c7Sgtb * Copyright 1994,1999,2000, 2002, 2003 by the Massachusetts Institute of Technology.
107c478bd9Sstevel@tonic-gate * All Rights Reserved.
117c478bd9Sstevel@tonic-gate *
127c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
137c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
147c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
157c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
16*55fea89dSDan Cross *
177c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
187c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
197c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
207c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
217c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
227c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
237c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
247c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
257c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
267c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
277c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
287c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
297c478bd9Sstevel@tonic-gate * or implied warranty.
307c478bd9Sstevel@tonic-gate *
317c478bd9Sstevel@tonic-gate * krb5_init_contex()
327c478bd9Sstevel@tonic-gate */
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC.
36*55fea89dSDan Cross *
377c478bd9Sstevel@tonic-gate * All rights reserved.
38*55fea89dSDan Cross *
397c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may require
407c478bd9Sstevel@tonic-gate * a specific license from the United States Government. It is the
417c478bd9Sstevel@tonic-gate * responsibility of any person or organization contemplating export to
427c478bd9Sstevel@tonic-gate * obtain such a license before exporting.
43*55fea89dSDan Cross *
447c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
457c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
467c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
477c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
487c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
497c478bd9Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining
507c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
517c478bd9Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of
527c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
537c478bd9Sstevel@tonic-gate * or implied warranty.
54*55fea89dSDan Cross *
557c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
567c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
577c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
587c478bd9Sstevel@tonic-gate */
597c478bd9Sstevel@tonic-gate
60159d09a2SMark Phalan #include "k5-int.h"
617c478bd9Sstevel@tonic-gate
62*55fea89dSDan Cross /*
637c478bd9Sstevel@tonic-gate * Solaris Kerberos: the code related to EF/pkcs11 and fork safety are mods Sun
647c478bd9Sstevel@tonic-gate * has made to the MIT code.
657c478bd9Sstevel@tonic-gate */
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate #ifndef _KERNEL
687c478bd9Sstevel@tonic-gate #include <ctype.h>
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate pid_t __krb5_current_pid; /* fork safety: contains the current process ID */
717c478bd9Sstevel@tonic-gate #endif
727c478bd9Sstevel@tonic-gate
73505d05c7Sgtb #ifndef _KERNEL
74505d05c7Sgtb #include <krb5_libinit.h>
75505d05c7Sgtb #endif
76505d05c7Sgtb
77505d05c7Sgtb /* The des-mdX entries are last for now, because it's easy to
78505d05c7Sgtb configure KDCs to issue TGTs with des-mdX keys and then not accept
79505d05c7Sgtb them. This'll be fixed, but for better compatibility, let's prefer
80505d05c7Sgtb des-crc for now. */
81a0a37ffdSShawn Emery /*
82a0a37ffdSShawn Emery * Solaris Kerberos:
83a0a37ffdSShawn Emery * Added arcfour-hmac-md5-exp as default enc type.
84a0a37ffdSShawn Emery * Changed des3-hmac-sha1 to des3-cbc-sha1-kd, as specified in RFC3961.
85a0a37ffdSShawn Emery */
86505d05c7Sgtb #define DEFAULT_ETYPE_LIST \
87505d05c7Sgtb "aes256-cts-hmac-sha1-96 " \
88505d05c7Sgtb "aes128-cts-hmac-sha1-96 " \
89a0a37ffdSShawn Emery "des3-cbc-sha1-kd " \
90505d05c7Sgtb "arcfour-hmac-md5 " \
91a0a37ffdSShawn Emery "arcfour-hmac-md5-exp " \
92505d05c7Sgtb "des-cbc-md5 " \
93505d05c7Sgtb "des-cbc-crc"
94505d05c7Sgtb
95505d05c7Sgtb
967c478bd9Sstevel@tonic-gate /* The only functions that are needed from this file when in kernel are
977c478bd9Sstevel@tonic-gate * krb5_init_context and krb5_free_context.
987c478bd9Sstevel@tonic-gate * In krb5_init_context we need only os_init_context since we don'it need the
997c478bd9Sstevel@tonic-gate * profile info unless we do init/accept in kernel. Currently only mport,
1007c478bd9Sstevel@tonic-gate * delete , sign/verify, wrap/unwrap routines are ported to the kernel.
1017c478bd9Sstevel@tonic-gate */
1027c478bd9Sstevel@tonic-gate
103159d09a2SMark Phalan #if (defined(_WIN32))
1047c478bd9Sstevel@tonic-gate extern krb5_error_code krb5_vercheck();
1057c478bd9Sstevel@tonic-gate extern void krb5_win_ccdll_load(krb5_context context);
1067c478bd9Sstevel@tonic-gate #endif
1077c478bd9Sstevel@tonic-gate
10854925bf6Swillf static krb5_error_code init_common (krb5_context *, krb5_boolean, krb5_boolean);
1097c478bd9Sstevel@tonic-gate
110505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_init_context(krb5_context * context)111159d09a2SMark Phalan krb5_init_context(krb5_context *context)
1127c478bd9Sstevel@tonic-gate {
113159d09a2SMark Phalan
11454925bf6Swillf return init_common (context, FALSE, FALSE);
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate
117505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_init_secure_context(krb5_context * context)118159d09a2SMark Phalan krb5_init_secure_context(krb5_context *context)
1197c478bd9Sstevel@tonic-gate {
120159d09a2SMark Phalan
121159d09a2SMark Phalan #if 0 /* Solaris Kerberos */
122159d09a2SMark Phalan /* This is to make gcc -Wall happy */
123159d09a2SMark Phalan if(0) krb5_brand[0] = krb5_brand[0];
124159d09a2SMark Phalan #endif
12554925bf6Swillf return init_common (context, TRUE, FALSE);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate #ifndef _KERNEL
12954925bf6Swillf
13054925bf6Swillf krb5_error_code
krb5int_init_context_kdc(krb5_context * context)13154925bf6Swillf krb5int_init_context_kdc(krb5_context *context)
13254925bf6Swillf {
13354925bf6Swillf return init_common (context, FALSE, TRUE);
13454925bf6Swillf }
13554925bf6Swillf
136159d09a2SMark Phalan /* Solaris Kerberos */
1377c478bd9Sstevel@tonic-gate krb5_error_code
krb5_open_pkcs11_session(CK_SESSION_HANDLE * hSession)1387c478bd9Sstevel@tonic-gate krb5_open_pkcs11_session(CK_SESSION_HANDLE *hSession)
1397c478bd9Sstevel@tonic-gate {
1407c478bd9Sstevel@tonic-gate krb5_error_code retval = 0;
141*55fea89dSDan Cross CK_RV rv;
142*55fea89dSDan Cross CK_SLOT_ID_PTR slotlist = NULL_PTR;
143*55fea89dSDan Cross CK_ULONG slotcount;
1447c478bd9Sstevel@tonic-gate CK_ULONG i;
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate /* List of all Slots */
1477c478bd9Sstevel@tonic-gate rv = C_GetSlotList(FALSE, NULL_PTR, &slotcount);
1487c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1497c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "C_GetSlotList failed with 0x%x.", rv);
1507c478bd9Sstevel@tonic-gate retval = PKCS_ERR;
1517c478bd9Sstevel@tonic-gate goto cleanup;
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate if (slotcount == 0) {
1557c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "No slot is found in PKCS11.");
1567c478bd9Sstevel@tonic-gate retval = PKCS_ERR;
1577c478bd9Sstevel@tonic-gate goto cleanup;
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate
160*55fea89dSDan Cross slotlist = (CK_SLOT_ID_PTR)malloc(slotcount * sizeof(CK_SLOT_ID));
1617c478bd9Sstevel@tonic-gate if (slotlist == NULL) {
1627c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "malloc failed for slotcount.");
1637c478bd9Sstevel@tonic-gate retval = PKCS_ERR;
1647c478bd9Sstevel@tonic-gate goto cleanup;
1657c478bd9Sstevel@tonic-gate }
166*55fea89dSDan Cross
1677c478bd9Sstevel@tonic-gate rv = C_GetSlotList(FALSE, slotlist, &slotcount);
1687c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1697c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "C_GetSlotList failed with 0x%x", rv);
1707c478bd9Sstevel@tonic-gate retval = PKCS_ERR;
1717c478bd9Sstevel@tonic-gate goto cleanup;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate for (i = 0; i < slotcount; i++) {
1747c478bd9Sstevel@tonic-gate if (slot_supports_krb5(slotlist + i))
1757c478bd9Sstevel@tonic-gate break;
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate if (i == slotcount){
1787c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "Could not find slot which supports "
1797c478bd9Sstevel@tonic-gate "Kerberos");
1807c478bd9Sstevel@tonic-gate retval = PKCS_ERR;
1817c478bd9Sstevel@tonic-gate goto cleanup;
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate rv = C_OpenSession(slotlist[i], CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR,
1847c478bd9Sstevel@tonic-gate hSession);
1857c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1867c478bd9Sstevel@tonic-gate retval = PKCS_ERR;
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate cleanup:
1897c478bd9Sstevel@tonic-gate if (slotlist != NULL)
1907c478bd9Sstevel@tonic-gate free(slotlist);
1917c478bd9Sstevel@tonic-gate return(retval);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate /*
1957c478bd9Sstevel@tonic-gate * krb5_reinit_ef_handle()
1967c478bd9Sstevel@tonic-gate *
1977c478bd9Sstevel@tonic-gate * deal with fork safety issue regarding the krb ctx and the pkcs11 hSession
1987c478bd9Sstevel@tonic-gate * field. This function is called if it is determined that the krb ctx hSession
1997c478bd9Sstevel@tonic-gate * is being accessed in a child process after a fork(). This function
2007c478bd9Sstevel@tonic-gate * re-initilizes the pkcs11 session and returns the session handle.
2017c478bd9Sstevel@tonic-gate */
2027c478bd9Sstevel@tonic-gate CK_SESSION_HANDLE
krb5_reinit_ef_handle(krb5_context ctx)2037c478bd9Sstevel@tonic-gate krb5_reinit_ef_handle(krb5_context ctx)
2047c478bd9Sstevel@tonic-gate {
2057c478bd9Sstevel@tonic-gate ctx->cryptoki_initialized = FALSE;
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate if (krb5_init_ef_handle(ctx) != 0) {
2087c478bd9Sstevel@tonic-gate /*
2097c478bd9Sstevel@tonic-gate * krb5_free_ef_handle() not needed here -- we assume that an equivalent
2107c478bd9Sstevel@tonic-gate * of C_Finalize() was done in the child-side of the fork(), so all EF
2117c478bd9Sstevel@tonic-gate * resources in this context will be invalid.
2127c478bd9Sstevel@tonic-gate */
2137c478bd9Sstevel@tonic-gate return(CK_INVALID_HANDLE);
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate /* reset the ctx pid since we're in a new process (child) */
217*55fea89dSDan Cross ctx->pid = __krb5_current_pid;
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate /* If the RC4 handles were initialized, reset them here */
2207c478bd9Sstevel@tonic-gate if (ctx->arcfour_ctx.initialized) {
2217c478bd9Sstevel@tonic-gate krb5_error_code ret;
2227c478bd9Sstevel@tonic-gate ret = krb5_open_pkcs11_session(&ctx->arcfour_ctx.eSession);
2237c478bd9Sstevel@tonic-gate if (ret) {
2247c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.initialized = 0;
2257c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.eSession = CK_INVALID_HANDLE;
2267c478bd9Sstevel@tonic-gate C_CloseSession(ctx->hSession);
2277c478bd9Sstevel@tonic-gate ctx->hSession = CK_INVALID_HANDLE;
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate ret = krb5_open_pkcs11_session(&ctx->arcfour_ctx.dSession);
2307c478bd9Sstevel@tonic-gate if (ret) {
2317c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.initialized = 0;
2327c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.eSession = CK_INVALID_HANDLE;
2337c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.dSession = CK_INVALID_HANDLE;
2347c478bd9Sstevel@tonic-gate C_CloseSession(ctx->hSession);
2357c478bd9Sstevel@tonic-gate ctx->hSession = CK_INVALID_HANDLE;
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate
239*55fea89dSDan Cross /*
2407c478bd9Sstevel@tonic-gate * It is safe for this function to access ctx->hSession directly. Do
2417c478bd9Sstevel@tonic-gate * NOT use the krb_ctx_hSession() here.
2427c478bd9Sstevel@tonic-gate */
2437c478bd9Sstevel@tonic-gate return(ctx->hSession);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate /*
2477c478bd9Sstevel@tonic-gate * krb5_pthread_atfork_child_handler() sets a global that indicates the current
2487c478bd9Sstevel@tonic-gate * PID. This is an optimization to keep getpid() from being called a zillion
2497c478bd9Sstevel@tonic-gate * times.
2507c478bd9Sstevel@tonic-gate */
2517c478bd9Sstevel@tonic-gate void
krb5_pthread_atfork_child_handler()2527c478bd9Sstevel@tonic-gate krb5_pthread_atfork_child_handler()
2537c478bd9Sstevel@tonic-gate {
254*55fea89dSDan Cross /*
2557c478bd9Sstevel@tonic-gate * __krb5_current_pid should always be set to current process ID, see the
256*55fea89dSDan Cross * definition of krb_ctx_hSession() for more info
2577c478bd9Sstevel@tonic-gate */
2587c478bd9Sstevel@tonic-gate __krb5_current_pid = getpid();
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate /*
2627c478bd9Sstevel@tonic-gate * krb5_ld_init() contains code that will be executed at load time (via the
2637c478bd9Sstevel@tonic-gate * ld -zinitarray directive).
2647c478bd9Sstevel@tonic-gate */
2657c478bd9Sstevel@tonic-gate void
krb5_ld_init()2667c478bd9Sstevel@tonic-gate krb5_ld_init()
2677c478bd9Sstevel@tonic-gate {
268*55fea89dSDan Cross /*
2697c478bd9Sstevel@tonic-gate * fork safety: __krb5_current_pid should always be set to current process
270*55fea89dSDan Cross * ID, see the definition of krb_ctx_hSession() for more info
2717c478bd9Sstevel@tonic-gate */
2727c478bd9Sstevel@tonic-gate __krb5_current_pid = getpid();
273*55fea89dSDan Cross /*
2747c478bd9Sstevel@tonic-gate * The child handler below will help reduce the number of times getpid() is
2757c478bd9Sstevel@tonic-gate * called by updating a global PID var. with the current PID whenever a fork
2767c478bd9Sstevel@tonic-gate * occurrs.
2777c478bd9Sstevel@tonic-gate */
2787c478bd9Sstevel@tonic-gate (void) pthread_atfork(NULL, NULL, krb5_pthread_atfork_child_handler);
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate #endif /* !_KERNEL */
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate krb5_error_code
krb5_init_ef_handle(krb5_context ctx)2837c478bd9Sstevel@tonic-gate krb5_init_ef_handle(krb5_context ctx)
2847c478bd9Sstevel@tonic-gate {
2857c478bd9Sstevel@tonic-gate krb5_error_code retval = 0;
2867c478bd9Sstevel@tonic-gate #ifndef _KERNEL
2877c478bd9Sstevel@tonic-gate CK_RV rv = C_Initialize(NULL_PTR);
2887c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
2897c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "C_Initialize failed with 0x%x.", rv);
2907c478bd9Sstevel@tonic-gate return (PKCS_ERR);
291*55fea89dSDan Cross
2927c478bd9Sstevel@tonic-gate }
293*55fea89dSDan Cross /*
2947c478bd9Sstevel@tonic-gate * It is safe for this function to access ctx->hSession directly. Do
2957c478bd9Sstevel@tonic-gate * NOT use the krb_ctx_hSession() here.
2967c478bd9Sstevel@tonic-gate */
2977c478bd9Sstevel@tonic-gate retval = krb5_open_pkcs11_session(&ctx->hSession);
2987c478bd9Sstevel@tonic-gate if (retval != 0)
2997c478bd9Sstevel@tonic-gate return (retval);
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate ctx->cryptoki_initialized = TRUE;
3027c478bd9Sstevel@tonic-gate #else /* ! _KERNEL */
3037c478bd9Sstevel@tonic-gate ctx->kef_cipher_mt = CRYPTO_MECH_INVALID;
3047c478bd9Sstevel@tonic-gate ctx->kef_hash_mt = CRYPTO_MECH_INVALID;
3057c478bd9Sstevel@tonic-gate ctx->kef_cksum_mt = CRYPTO_MECH_INVALID;
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate setup_kef_keytypes();
3087c478bd9Sstevel@tonic-gate setup_kef_cksumtypes();
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate #endif /* ! _KERNEL */
3117c478bd9Sstevel@tonic-gate return(retval);
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate #ifndef _KERNEL
3157c478bd9Sstevel@tonic-gate krb5_error_code
krb5_free_ef_handle(krb5_context ctx)3167c478bd9Sstevel@tonic-gate krb5_free_ef_handle(krb5_context ctx)
3177c478bd9Sstevel@tonic-gate {
318*55fea89dSDan Cross /*
3197c478bd9Sstevel@tonic-gate * fork safety: Don't free any PKCS state if we've forked since
3207c478bd9Sstevel@tonic-gate * allocating the pkcs handles.
3217c478bd9Sstevel@tonic-gate */
3227c478bd9Sstevel@tonic-gate if (ctx->cryptoki_initialized == TRUE &&
3237c478bd9Sstevel@tonic-gate ctx->pid == __krb5_current_pid) {
324*55fea89dSDan Cross /*
3257c478bd9Sstevel@tonic-gate * It is safe for this function to access ctx->hSession
3267c478bd9Sstevel@tonic-gate * directly. Do NOT use the krb_ctx_hSession() here.
3277c478bd9Sstevel@tonic-gate */
3287c478bd9Sstevel@tonic-gate if (ctx->hSession) {
3297c478bd9Sstevel@tonic-gate C_CloseSession(ctx->hSession);
3307c478bd9Sstevel@tonic-gate ctx->hSession = 0;
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate if (ctx->arcfour_ctx.dKey) {
3337c478bd9Sstevel@tonic-gate C_DestroyObject(ctx->arcfour_ctx.dSession,
3347c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.dKey);
3357c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.dKey = 0;
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate if (ctx->arcfour_ctx.eKey) {
3387c478bd9Sstevel@tonic-gate C_DestroyObject(ctx->arcfour_ctx.eSession,
3397c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.eKey);
3407c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.eKey = 0;
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate if (ctx->arcfour_ctx.eSession) {
3437c478bd9Sstevel@tonic-gate C_CloseSession(ctx->arcfour_ctx.eSession);
3447c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.eSession = 0;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate if (ctx->arcfour_ctx.dSession) {
3477c478bd9Sstevel@tonic-gate C_CloseSession(ctx->arcfour_ctx.dSession);
3487c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.eSession = 0;
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate ctx->arcfour_ctx.initialized = 0;
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate ctx->cryptoki_initialized = FALSE;
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate return(0);
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate #endif /* !_KERNEL */
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate static krb5_error_code
init_common(krb5_context * context,krb5_boolean secure,krb5_boolean kdc)35954925bf6Swillf init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc)
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate krb5_context ctx = 0;
3627c478bd9Sstevel@tonic-gate krb5_error_code retval;
3637c478bd9Sstevel@tonic-gate #ifndef _KERNEL
3647c478bd9Sstevel@tonic-gate struct {
3657c478bd9Sstevel@tonic-gate krb5_int32 now, now_usec;
3667c478bd9Sstevel@tonic-gate long pid;
3677c478bd9Sstevel@tonic-gate } seed_data;
3687c478bd9Sstevel@tonic-gate krb5_data seed;
3697c478bd9Sstevel@tonic-gate int tmp;
370159d09a2SMark Phalan /* Solaris Kerberos */
371159d09a2SMark Phalan #if 0
372159d09a2SMark Phalan /* Verify some assumptions. If the assumptions hold and the
373159d09a2SMark Phalan compiler is optimizing, this should result in no code being
374159d09a2SMark Phalan executed. If we're guessing "unsigned long long" instead
375159d09a2SMark Phalan of using uint64_t, the possibility does exist that we're
376159d09a2SMark Phalan wrong. */
377159d09a2SMark Phalan {
378159d09a2SMark Phalan krb5_ui_8 i64;
379159d09a2SMark Phalan assert(sizeof(i64) == 8);
380159d09a2SMark Phalan i64 = 0, i64--, i64 >>= 62;
381159d09a2SMark Phalan assert(i64 == 3);
382159d09a2SMark Phalan i64 = 1, i64 <<= 31, i64 <<= 31, i64 <<= 1;
383159d09a2SMark Phalan assert(i64 != 0);
384159d09a2SMark Phalan i64 <<= 1;
385159d09a2SMark Phalan assert(i64 == 0);
386159d09a2SMark Phalan }
387159d09a2SMark Phalan #endif
388159d09a2SMark Phalan retval = krb5int_initialize_library();
389159d09a2SMark Phalan if (retval)
390159d09a2SMark Phalan return retval;
3917c478bd9Sstevel@tonic-gate #endif
3927c478bd9Sstevel@tonic-gate
393505d05c7Sgtb #if (defined(_WIN32))
394*55fea89dSDan Cross /*
3957c478bd9Sstevel@tonic-gate * Load the krbcc32.dll if necessary. We do this here so that
3967c478bd9Sstevel@tonic-gate * we know to use API: later on during initialization.
3977c478bd9Sstevel@tonic-gate * The context being NULL is ok.
3987c478bd9Sstevel@tonic-gate */
3997c478bd9Sstevel@tonic-gate krb5_win_ccdll_load(ctx);
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate * krb5_vercheck() is defined in win_glue.c, and this is
4037c478bd9Sstevel@tonic-gate * where we handle the timebomb and version server checks.
4047c478bd9Sstevel@tonic-gate */
4057c478bd9Sstevel@tonic-gate retval = krb5_vercheck();
4067c478bd9Sstevel@tonic-gate if (retval)
4077c478bd9Sstevel@tonic-gate return retval;
4087c478bd9Sstevel@tonic-gate #endif
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate *context = 0;
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate ctx = MALLOC(sizeof(struct _krb5_context));
4137c478bd9Sstevel@tonic-gate if (!ctx)
4147c478bd9Sstevel@tonic-gate return ENOMEM;
4157c478bd9Sstevel@tonic-gate (void) memset(ctx, 0, sizeof(struct _krb5_context));
4167c478bd9Sstevel@tonic-gate ctx->magic = KV5M_CONTEXT;
4177c478bd9Sstevel@tonic-gate
4187c478bd9Sstevel@tonic-gate ctx->profile_secure = secure;
4197c478bd9Sstevel@tonic-gate
42054925bf6Swillf if ((retval = krb5_os_init_context(ctx, kdc)))
4217c478bd9Sstevel@tonic-gate goto cleanup;
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate /*
4247c478bd9Sstevel@tonic-gate * Initialize the EF handle, its needed before doing
4257c478bd9Sstevel@tonic-gate * the random seed.
4267c478bd9Sstevel@tonic-gate */
4277c478bd9Sstevel@tonic-gate if ((retval = krb5_init_ef_handle(ctx)))
4287c478bd9Sstevel@tonic-gate goto cleanup;
4297c478bd9Sstevel@tonic-gate
4307c478bd9Sstevel@tonic-gate #ifndef _KERNEL
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate /* fork safety: set pid to current process ID for later checking */
4337c478bd9Sstevel@tonic-gate ctx->pid = __krb5_current_pid;
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate /* Set the default encryption types, possible defined in krb5/conf */
4367c478bd9Sstevel@tonic-gate if ((retval = krb5_set_default_in_tkt_ktypes(ctx, NULL)))
4377c478bd9Sstevel@tonic-gate goto cleanup;
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate if ((retval = krb5_set_default_tgs_ktypes(ctx, NULL)))
4407c478bd9Sstevel@tonic-gate goto cleanup;
4417c478bd9Sstevel@tonic-gate
442d9976468Sps if (ctx->tgs_ktype_count != 0) {
443d9976468Sps ctx->conf_tgs_ktypes = MALLOC(ctx->tgs_ktype_count *
444d9976468Sps sizeof(krb5_enctype));
445d9976468Sps if (ctx->conf_tgs_ktypes == NULL)
446d9976468Sps goto cleanup;
4477c478bd9Sstevel@tonic-gate
448d9976468Sps (void) memcpy(ctx->conf_tgs_ktypes, ctx->tgs_ktypes,
449d9976468Sps sizeof(krb5_enctype) * ctx->tgs_ktype_count);
450d9976468Sps }
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate ctx->conf_tgs_ktypes_count = ctx->tgs_ktype_count;
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate /* initialize the prng (not well, but passable) */
4567c478bd9Sstevel@tonic-gate if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec)))
4577c478bd9Sstevel@tonic-gate goto cleanup;
4587c478bd9Sstevel@tonic-gate seed_data.pid = getpid ();
4597c478bd9Sstevel@tonic-gate seed.length = sizeof(seed_data);
4607c478bd9Sstevel@tonic-gate seed.data = (char *) &seed_data;
4617c478bd9Sstevel@tonic-gate if ((retval = krb5_c_random_seed(ctx, &seed)))
4627c478bd9Sstevel@tonic-gate /*
4637c478bd9Sstevel@tonic-gate * Solaris Kerberos: we use /dev/urandom, which is
4647c478bd9Sstevel@tonic-gate * automatically seeded, so its OK if this fails.
4657c478bd9Sstevel@tonic-gate */
4667c478bd9Sstevel@tonic-gate retval = 0;
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate ctx->default_realm = 0;
4697c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults", "clockskew",
4707c478bd9Sstevel@tonic-gate 0, 5 * 60, &tmp);
4717c478bd9Sstevel@tonic-gate ctx->clockskew = tmp;
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate #if 0
4747c478bd9Sstevel@tonic-gate /* Default ticket lifetime is currently not supported */
4757c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults", "tkt_lifetime",
4767c478bd9Sstevel@tonic-gate 0, 10 * 60 * 60, &tmp);
4777c478bd9Sstevel@tonic-gate ctx->tkt_lifetime = tmp;
4787c478bd9Sstevel@tonic-gate #endif
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2) */
4817c478bd9Sstevel@tonic-gate /* DCE add kdc_req_checksum_type = 2 to krb5.conf */
4827c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults",
483*55fea89dSDan Cross "kdc_req_checksum_type", 0, CKSUMTYPE_RSA_MD5,
4847c478bd9Sstevel@tonic-gate &tmp);
4857c478bd9Sstevel@tonic-gate ctx->kdc_req_sumtype = tmp;
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults",
4887c478bd9Sstevel@tonic-gate "ap_req_checksum_type", 0, CKSUMTYPE_RSA_MD5,
4897c478bd9Sstevel@tonic-gate &tmp);
4907c478bd9Sstevel@tonic-gate ctx->default_ap_req_sumtype = tmp;
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults",
4937c478bd9Sstevel@tonic-gate "safe_checksum_type", 0,
4947c478bd9Sstevel@tonic-gate CKSUMTYPE_RSA_MD5_DES, &tmp);
4957c478bd9Sstevel@tonic-gate ctx->default_safe_sumtype = tmp;
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults",
4987c478bd9Sstevel@tonic-gate "kdc_default_options", 0,
4997c478bd9Sstevel@tonic-gate KDC_OPT_RENEWABLE_OK, &tmp);
500505d05c7Sgtb ctx->kdc_default_options = tmp;
5017c478bd9Sstevel@tonic-gate #define DEFAULT_KDC_TIMESYNC 1
5027c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults",
5037c478bd9Sstevel@tonic-gate "kdc_timesync", 0, DEFAULT_KDC_TIMESYNC,
5047c478bd9Sstevel@tonic-gate &tmp);
5057c478bd9Sstevel@tonic-gate ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate /*
5087c478bd9Sstevel@tonic-gate * We use a default file credentials cache of 3. See
5097c478bd9Sstevel@tonic-gate * lib/krb5/krb/ccache/file/fcc.h for a description of the
5107c478bd9Sstevel@tonic-gate * credentials cache types.
5117c478bd9Sstevel@tonic-gate *
5127c478bd9Sstevel@tonic-gate * Note: DCE 1.0.3a only supports a cache type of 1
5137c478bd9Sstevel@tonic-gate * DCE 1.1 supports a cache type of 2.
5147c478bd9Sstevel@tonic-gate */
5157c478bd9Sstevel@tonic-gate #define DEFAULT_CCACHE_TYPE 4
5167c478bd9Sstevel@tonic-gate profile_get_integer(ctx->profile, "libdefaults", "ccache_type",
5177c478bd9Sstevel@tonic-gate 0, DEFAULT_CCACHE_TYPE, &tmp);
5187c478bd9Sstevel@tonic-gate ctx->fcc_default_format = tmp + 0x0500;
5197c478bd9Sstevel@tonic-gate ctx->scc_default_format = tmp + 0x0500;
5207c478bd9Sstevel@tonic-gate ctx->prompt_types = 0;
5217c478bd9Sstevel@tonic-gate ctx->use_conf_ktypes = 0;
5227c478bd9Sstevel@tonic-gate
52356a424ccSmp ctx->udp_pref_limit = -1;
5247c478bd9Sstevel@tonic-gate
5257c478bd9Sstevel@tonic-gate #endif /* !_KERNEL */
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate *context = ctx;
5287c478bd9Sstevel@tonic-gate return 0;
5297c478bd9Sstevel@tonic-gate
5307c478bd9Sstevel@tonic-gate cleanup:
5317c478bd9Sstevel@tonic-gate krb5_free_context(ctx);
5327c478bd9Sstevel@tonic-gate return retval;
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate
535505d05c7Sgtb void KRB5_CALLCONV
krb5_free_context(krb5_context ctx)536505d05c7Sgtb krb5_free_context(krb5_context ctx)
5377c478bd9Sstevel@tonic-gate {
5387c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO,"krb5_free_context() start");
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate #ifndef _KERNEL
5417c478bd9Sstevel@tonic-gate krb5_free_ef_handle(ctx);
5427c478bd9Sstevel@tonic-gate
5437c478bd9Sstevel@tonic-gate if (ctx->conf_tgs_ktypes) {
5447c478bd9Sstevel@tonic-gate FREE(ctx->conf_tgs_ktypes, sizeof(krb5_enctype) *(ctx->conf_tgs_ktypes_count));
5457c478bd9Sstevel@tonic-gate ctx->conf_tgs_ktypes = 0;
5467c478bd9Sstevel@tonic-gate ctx->conf_tgs_ktypes_count = 0;
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate
549159d09a2SMark Phalan krb5_clear_error_message(ctx);
550159d09a2SMark Phalan
5517c478bd9Sstevel@tonic-gate #endif
5527c478bd9Sstevel@tonic-gate krb5_os_free_context(ctx);
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate if (ctx->in_tkt_ktypes) {
5557c478bd9Sstevel@tonic-gate FREE(ctx->in_tkt_ktypes, sizeof(krb5_enctype) *(ctx->in_tkt_ktype_count+1) );
5567c478bd9Sstevel@tonic-gate ctx->in_tkt_ktypes = 0;
5577c478bd9Sstevel@tonic-gate }
5587c478bd9Sstevel@tonic-gate
5597c478bd9Sstevel@tonic-gate if (ctx->tgs_ktypes) {
5607c478bd9Sstevel@tonic-gate FREE(ctx->tgs_ktypes, sizeof(krb5_enctype) *(ctx->tgs_ktype_count+1));
5617c478bd9Sstevel@tonic-gate ctx->tgs_ktypes = 0;
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate
5647c478bd9Sstevel@tonic-gate if (ctx->default_realm) {
5657c478bd9Sstevel@tonic-gate FREE(ctx->default_realm, strlen(ctx->default_realm) + 1);
5667c478bd9Sstevel@tonic-gate ctx->default_realm = 0;
5677c478bd9Sstevel@tonic-gate }
5687c478bd9Sstevel@tonic-gate
5697c478bd9Sstevel@tonic-gate if (ctx->ser_ctx_count && ctx->ser_ctx) {
5707c478bd9Sstevel@tonic-gate FREE(ctx->ser_ctx,sizeof(krb5_ser_entry) * (ctx->ser_ctx_count) );
5717c478bd9Sstevel@tonic-gate ctx->ser_ctx = 0;
5727c478bd9Sstevel@tonic-gate ctx->ser_ctx_count = 0;
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate
575159d09a2SMark Phalan
5767c478bd9Sstevel@tonic-gate ctx->magic = 0;
5777c478bd9Sstevel@tonic-gate FREE(ctx, sizeof(struct _krb5_context));
5787c478bd9Sstevel@tonic-gate }
5797c478bd9Sstevel@tonic-gate
5807c478bd9Sstevel@tonic-gate #ifndef _KERNEL
5817c478bd9Sstevel@tonic-gate /*
5827c478bd9Sstevel@tonic-gate * Set the desired default ktypes, making sure they are valid.
5837c478bd9Sstevel@tonic-gate */
5847c478bd9Sstevel@tonic-gate krb5_error_code
krb5_set_default_in_tkt_ktypes(krb5_context context,const krb5_enctype * ktypes)585505d05c7Sgtb krb5_set_default_in_tkt_ktypes(krb5_context context, const krb5_enctype *ktypes)
5867c478bd9Sstevel@tonic-gate {
5877c478bd9Sstevel@tonic-gate krb5_enctype * new_ktypes;
5887c478bd9Sstevel@tonic-gate int i;
5897c478bd9Sstevel@tonic-gate
5907c478bd9Sstevel@tonic-gate if (ktypes) {
5917c478bd9Sstevel@tonic-gate for (i = 0; ktypes[i]; i++) {
592*55fea89dSDan Cross if (!krb5_c_valid_enctype(ktypes[i]))
5937c478bd9Sstevel@tonic-gate return KRB5_PROG_ETYPE_NOSUPP;
5947c478bd9Sstevel@tonic-gate }
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate /* Now copy the default ktypes into the context pointer */
5977c478bd9Sstevel@tonic-gate if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i)))
5987c478bd9Sstevel@tonic-gate (void) memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
5997c478bd9Sstevel@tonic-gate else
6007c478bd9Sstevel@tonic-gate return ENOMEM;
6017c478bd9Sstevel@tonic-gate
6027c478bd9Sstevel@tonic-gate } else {
6037c478bd9Sstevel@tonic-gate i = 0;
6047c478bd9Sstevel@tonic-gate new_ktypes = 0;
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate
607*55fea89dSDan Cross if (context->in_tkt_ktypes)
6087c478bd9Sstevel@tonic-gate free(context->in_tkt_ktypes);
6097c478bd9Sstevel@tonic-gate context->in_tkt_ktypes = new_ktypes;
6107c478bd9Sstevel@tonic-gate context->in_tkt_ktype_count = i;
6117c478bd9Sstevel@tonic-gate return 0;
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate static krb5_error_code
get_profile_etype_list(krb5_context context,krb5_enctype ** ktypes,char * profstr,unsigned int ctx_count,krb5_enctype * ctx_list)615505d05c7Sgtb get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
616159d09a2SMark Phalan unsigned int ctx_count, krb5_enctype *ctx_list)
6177c478bd9Sstevel@tonic-gate {
6187c478bd9Sstevel@tonic-gate krb5_enctype *old_ktypes = NULL;
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate if (ctx_count) {
6217c478bd9Sstevel@tonic-gate /* application-set defaults */
622*55fea89dSDan Cross if ((old_ktypes =
6237c478bd9Sstevel@tonic-gate (krb5_enctype *)malloc(sizeof(krb5_enctype) *
6247c478bd9Sstevel@tonic-gate (ctx_count + 1)))) {
6257c478bd9Sstevel@tonic-gate (void) memcpy(old_ktypes, ctx_list,
6267c478bd9Sstevel@tonic-gate sizeof(krb5_enctype) * ctx_count);
6277c478bd9Sstevel@tonic-gate old_ktypes[ctx_count] = 0;
6287c478bd9Sstevel@tonic-gate } else {
6297c478bd9Sstevel@tonic-gate return ENOMEM;
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate } else {
6327c478bd9Sstevel@tonic-gate /*
6337c478bd9Sstevel@tonic-gate XXX - For now, we only support libdefaults
6347c478bd9Sstevel@tonic-gate Perhaps this should be extended to allow for per-host / per-realm
6357c478bd9Sstevel@tonic-gate session key types.
6367c478bd9Sstevel@tonic-gate */
6377c478bd9Sstevel@tonic-gate
638505d05c7Sgtb char *retval = NULL;
6397c478bd9Sstevel@tonic-gate char *sp, *ep;
6407c478bd9Sstevel@tonic-gate int j, checked_enctypes, count;
6417c478bd9Sstevel@tonic-gate krb5_error_code code;
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate code = profile_get_string(context->profile, "libdefaults", profstr,
644505d05c7Sgtb NULL, DEFAULT_ETYPE_LIST, &retval);
6457c478bd9Sstevel@tonic-gate if (code)
6467c478bd9Sstevel@tonic-gate return code;
6477c478bd9Sstevel@tonic-gate
648505d05c7Sgtb if (!retval) /* SUNW14resync - just in case */
649505d05c7Sgtb return PROF_EINVAL; /* XXX */
650505d05c7Sgtb
6517c478bd9Sstevel@tonic-gate count = 0;
6527c478bd9Sstevel@tonic-gate sp = retval;
653505d05c7Sgtb while (*sp) {
654505d05c7Sgtb for (ep = sp; *ep && (*ep != ',') && !isspace((int) (*ep)); ep++)
6557c478bd9Sstevel@tonic-gate ;
6567c478bd9Sstevel@tonic-gate if (*ep) {
6577c478bd9Sstevel@tonic-gate *ep++ = '\0';
658505d05c7Sgtb while (isspace((int) (*ep)) || *ep == ',')
659505d05c7Sgtb *ep++ = '\0';
660505d05c7Sgtb }
6617c478bd9Sstevel@tonic-gate count++;
6627c478bd9Sstevel@tonic-gate sp = ep;
6637c478bd9Sstevel@tonic-gate }
664*55fea89dSDan Cross
6657c478bd9Sstevel@tonic-gate if ((old_ktypes =
6667c478bd9Sstevel@tonic-gate (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
6677c478bd9Sstevel@tonic-gate (krb5_enctype *) NULL)
6687c478bd9Sstevel@tonic-gate return ENOMEM;
669*55fea89dSDan Cross
6707c478bd9Sstevel@tonic-gate sp = retval;
6717c478bd9Sstevel@tonic-gate j = checked_enctypes = 0;
6727c478bd9Sstevel@tonic-gate /*CONSTCOND*/
6737c478bd9Sstevel@tonic-gate while (TRUE) {
6747c478bd9Sstevel@tonic-gate checked_enctypes++;
6757c478bd9Sstevel@tonic-gate if (krb5_string_to_enctype(sp, &old_ktypes[j]))
6767c478bd9Sstevel@tonic-gate old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN;
6777c478bd9Sstevel@tonic-gate
6787c478bd9Sstevel@tonic-gate /*
6797c478bd9Sstevel@tonic-gate * If 'null' has been specified as a tkt_enctype in
6807c478bd9Sstevel@tonic-gate * krb5.conf, we need to assign an ENCTYPE_UNKNOWN
6817c478bd9Sstevel@tonic-gate * value to the corresponding old_ktypes[j] entry.
6827c478bd9Sstevel@tonic-gate */
6837c478bd9Sstevel@tonic-gate if (old_ktypes[j] == (unsigned int)ENCTYPE_NULL)
6847c478bd9Sstevel@tonic-gate old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN;
6857c478bd9Sstevel@tonic-gate
6867c478bd9Sstevel@tonic-gate /* Only include known/valid enctypes in the final list */
6877c478bd9Sstevel@tonic-gate if (old_ktypes[j] != ENCTYPE_UNKNOWN) {
6887c478bd9Sstevel@tonic-gate j++;
6897c478bd9Sstevel@tonic-gate }
6907c478bd9Sstevel@tonic-gate /* If we checked all the enctypes, we are done */
6917c478bd9Sstevel@tonic-gate if (checked_enctypes == count) {
6927c478bd9Sstevel@tonic-gate break;
6937c478bd9Sstevel@tonic-gate }
6947c478bd9Sstevel@tonic-gate
6957c478bd9Sstevel@tonic-gate /* skip to next token */
6967c478bd9Sstevel@tonic-gate while (*sp) sp++;
697159d09a2SMark Phalan while (! *sp) sp++;
6987c478bd9Sstevel@tonic-gate }
6997c478bd9Sstevel@tonic-gate
7007c478bd9Sstevel@tonic-gate old_ktypes[j] = (krb5_enctype) 0;
7017c478bd9Sstevel@tonic-gate profile_release_string(retval);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate if (old_ktypes[0] == 0) {
7057c478bd9Sstevel@tonic-gate free (old_ktypes);
7067c478bd9Sstevel@tonic-gate *ktypes = 0;
7077c478bd9Sstevel@tonic-gate return KRB5_CONFIG_ETYPE_NOSUPP;
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate *ktypes = old_ktypes;
7117c478bd9Sstevel@tonic-gate return 0;
7127c478bd9Sstevel@tonic-gate }
7137c478bd9Sstevel@tonic-gate
7147c478bd9Sstevel@tonic-gate krb5_error_code
krb5_get_default_in_tkt_ktypes(krb5_context context,krb5_enctype ** ktypes)715505d05c7Sgtb krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes)
7167c478bd9Sstevel@tonic-gate {
7177c478bd9Sstevel@tonic-gate return(get_profile_etype_list(context, ktypes, "default_tkt_enctypes",
7187c478bd9Sstevel@tonic-gate context->in_tkt_ktype_count,
7197c478bd9Sstevel@tonic-gate context->in_tkt_ktypes));
7207c478bd9Sstevel@tonic-gate }
7217c478bd9Sstevel@tonic-gate
722159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_set_default_tgs_enctypes(krb5_context context,const krb5_enctype * ktypes)723505d05c7Sgtb krb5_set_default_tgs_enctypes (krb5_context context, const krb5_enctype *ktypes)
7247c478bd9Sstevel@tonic-gate {
7257c478bd9Sstevel@tonic-gate krb5_enctype * new_ktypes;
7267c478bd9Sstevel@tonic-gate int i;
7277c478bd9Sstevel@tonic-gate
7287c478bd9Sstevel@tonic-gate if (ktypes) {
7297c478bd9Sstevel@tonic-gate for (i = 0; ktypes[i]; i++) {
730*55fea89dSDan Cross if (!krb5_c_valid_enctype(ktypes[i]))
7317c478bd9Sstevel@tonic-gate return KRB5_PROG_ETYPE_NOSUPP;
7327c478bd9Sstevel@tonic-gate }
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate /* Now copy the default ktypes into the context pointer */
7357c478bd9Sstevel@tonic-gate if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i)))
7367c478bd9Sstevel@tonic-gate (void) memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
7377c478bd9Sstevel@tonic-gate else
7387c478bd9Sstevel@tonic-gate return ENOMEM;
7397c478bd9Sstevel@tonic-gate
7407c478bd9Sstevel@tonic-gate } else {
7417c478bd9Sstevel@tonic-gate i = 0;
7427c478bd9Sstevel@tonic-gate new_ktypes = (krb5_enctype *)NULL;
7437c478bd9Sstevel@tonic-gate }
7447c478bd9Sstevel@tonic-gate
745*55fea89dSDan Cross if (context->tgs_ktypes)
7467c478bd9Sstevel@tonic-gate krb5_free_ktypes(context, context->tgs_ktypes);
7477c478bd9Sstevel@tonic-gate context->tgs_ktypes = new_ktypes;
7487c478bd9Sstevel@tonic-gate context->tgs_ktype_count = i;
7497c478bd9Sstevel@tonic-gate return 0;
7507c478bd9Sstevel@tonic-gate }
7517c478bd9Sstevel@tonic-gate
krb5_set_default_tgs_ktypes(krb5_context context,const krb5_enctype * etypes)7527c478bd9Sstevel@tonic-gate krb5_error_code krb5_set_default_tgs_ktypes
7537c478bd9Sstevel@tonic-gate (krb5_context context, const krb5_enctype *etypes)
7547c478bd9Sstevel@tonic-gate {
7557c478bd9Sstevel@tonic-gate return (krb5_set_default_tgs_enctypes (context, etypes));
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate
7587c478bd9Sstevel@tonic-gate
7597c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7607c478bd9Sstevel@tonic-gate void
7617c478bd9Sstevel@tonic-gate KRB5_CALLCONV
krb5_free_ktypes(krb5_context context,krb5_enctype * val)762505d05c7Sgtb krb5_free_ktypes (krb5_context context, krb5_enctype *val)
7637c478bd9Sstevel@tonic-gate {
7647c478bd9Sstevel@tonic-gate free (val);
7657c478bd9Sstevel@tonic-gate }
7667c478bd9Sstevel@tonic-gate
7677c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7687c478bd9Sstevel@tonic-gate krb5_error_code
7697c478bd9Sstevel@tonic-gate KRB5_CALLCONV
krb5_get_tgs_ktypes(krb5_context context,krb5_const_principal princ,krb5_enctype ** ktypes)770505d05c7Sgtb krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, krb5_enctype **ktypes)
7717c478bd9Sstevel@tonic-gate {
7727c478bd9Sstevel@tonic-gate if (context->use_conf_ktypes)
7737c478bd9Sstevel@tonic-gate /* This one is set *only* by reading the config file; it's not
7747c478bd9Sstevel@tonic-gate set by the application. */
7757c478bd9Sstevel@tonic-gate return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
7767c478bd9Sstevel@tonic-gate context->conf_tgs_ktypes_count,
7777c478bd9Sstevel@tonic-gate context->conf_tgs_ktypes));
7787c478bd9Sstevel@tonic-gate else
7797c478bd9Sstevel@tonic-gate return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
7807c478bd9Sstevel@tonic-gate context->tgs_ktype_count,
7817c478bd9Sstevel@tonic-gate context->tgs_ktypes));
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate krb5_error_code
krb5_get_permitted_enctypes(krb5_context context,krb5_enctype ** ktypes)785505d05c7Sgtb krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes)
7867c478bd9Sstevel@tonic-gate {
7877c478bd9Sstevel@tonic-gate return(get_profile_etype_list(context, ktypes, "permitted_enctypes",
7887c478bd9Sstevel@tonic-gate context->tgs_ktype_count,
7897c478bd9Sstevel@tonic-gate context->tgs_ktypes));
7907c478bd9Sstevel@tonic-gate }
7917c478bd9Sstevel@tonic-gate
7927c478bd9Sstevel@tonic-gate krb5_boolean
krb5_is_permitted_enctype(krb5_context context,krb5_enctype etype)793505d05c7Sgtb krb5_is_permitted_enctype(krb5_context context, krb5_enctype etype)
7947c478bd9Sstevel@tonic-gate {
7957c478bd9Sstevel@tonic-gate krb5_enctype *list, *ptr;
7967c478bd9Sstevel@tonic-gate krb5_boolean ret;
7977c478bd9Sstevel@tonic-gate
7987c478bd9Sstevel@tonic-gate if (krb5_get_permitted_enctypes(context, &list))
7997c478bd9Sstevel@tonic-gate return(0);
8007c478bd9Sstevel@tonic-gate
801*55fea89dSDan Cross
8027c478bd9Sstevel@tonic-gate ret = 0;
8037c478bd9Sstevel@tonic-gate
8047c478bd9Sstevel@tonic-gate for (ptr = list; *ptr; ptr++)
8057c478bd9Sstevel@tonic-gate if (*ptr == etype)
8067c478bd9Sstevel@tonic-gate ret = 1;
8077c478bd9Sstevel@tonic-gate
8087c478bd9Sstevel@tonic-gate krb5_free_ktypes (context, list);
8097c478bd9Sstevel@tonic-gate
8107c478bd9Sstevel@tonic-gate return(ret);
8117c478bd9Sstevel@tonic-gate }
812159d09a2SMark Phalan
813159d09a2SMark Phalan static krb5_error_code
copy_ktypes(krb5_context ctx,unsigned int nktypes,krb5_enctype * oldktypes,krb5_enctype ** newktypes)814159d09a2SMark Phalan copy_ktypes(krb5_context ctx,
815159d09a2SMark Phalan unsigned int nktypes,
816159d09a2SMark Phalan krb5_enctype *oldktypes,
817159d09a2SMark Phalan krb5_enctype **newktypes)
818159d09a2SMark Phalan {
819159d09a2SMark Phalan unsigned int i;
820159d09a2SMark Phalan
821159d09a2SMark Phalan *newktypes = NULL;
822159d09a2SMark Phalan if (!nktypes)
823159d09a2SMark Phalan return 0;
824159d09a2SMark Phalan
825159d09a2SMark Phalan *newktypes = MALLOC(nktypes * sizeof(krb5_enctype));
826159d09a2SMark Phalan if (*newktypes == NULL)
827159d09a2SMark Phalan return ENOMEM;
828159d09a2SMark Phalan for (i = 0; i < nktypes; i++)
829159d09a2SMark Phalan (*newktypes)[i] = oldktypes[i];
830159d09a2SMark Phalan return 0;
831159d09a2SMark Phalan }
832159d09a2SMark Phalan
833159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_copy_context(krb5_context ctx,krb5_context * nctx_out)834159d09a2SMark Phalan krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
835159d09a2SMark Phalan {
836159d09a2SMark Phalan krb5_error_code ret;
837159d09a2SMark Phalan krb5_context nctx;
838159d09a2SMark Phalan
839159d09a2SMark Phalan *nctx_out = NULL;
840159d09a2SMark Phalan if (ctx == NULL)
841159d09a2SMark Phalan return EINVAL; /* XXX */
842159d09a2SMark Phalan
843159d09a2SMark Phalan nctx = MALLOC(sizeof(*nctx));
844159d09a2SMark Phalan if (nctx == NULL)
845159d09a2SMark Phalan return ENOMEM;
846159d09a2SMark Phalan
847159d09a2SMark Phalan *nctx = *ctx;
848159d09a2SMark Phalan
849159d09a2SMark Phalan nctx->in_tkt_ktypes = NULL;
850159d09a2SMark Phalan nctx->in_tkt_ktype_count = 0;
851159d09a2SMark Phalan nctx->tgs_ktypes = NULL;
852159d09a2SMark Phalan nctx->tgs_ktype_count = 0;
853159d09a2SMark Phalan nctx->default_realm = NULL;
854159d09a2SMark Phalan nctx->profile = NULL;
855159d09a2SMark Phalan nctx->db_context = NULL;
856159d09a2SMark Phalan nctx->ser_ctx_count = 0;
857159d09a2SMark Phalan nctx->ser_ctx = NULL;
858159d09a2SMark Phalan nctx->prompt_types = NULL;
859159d09a2SMark Phalan nctx->os_context->default_ccname = NULL;
860159d09a2SMark Phalan
861159d09a2SMark Phalan memset(&nctx->preauth_plugins, 0, sizeof(nctx->preauth_plugins));
862159d09a2SMark Phalan nctx->preauth_context = NULL;
863159d09a2SMark Phalan
864159d09a2SMark Phalan memset(&nctx->libkrb5_plugins, 0, sizeof(nctx->libkrb5_plugins));
865159d09a2SMark Phalan nctx->vtbl = NULL;
866159d09a2SMark Phalan nctx->locate_fptrs = NULL;
867159d09a2SMark Phalan
868159d09a2SMark Phalan memset(&nctx->err, 0, sizeof(nctx->err));
869159d09a2SMark Phalan
870159d09a2SMark Phalan ret = copy_ktypes(nctx, ctx->in_tkt_ktype_count,
871159d09a2SMark Phalan ctx->in_tkt_ktypes, &nctx->in_tkt_ktypes);
872159d09a2SMark Phalan if (ret)
873159d09a2SMark Phalan goto errout;
874159d09a2SMark Phalan nctx->in_tkt_ktype_count = ctx->in_tkt_ktype_count;
875159d09a2SMark Phalan
876159d09a2SMark Phalan ret = copy_ktypes(nctx, ctx->tgs_ktype_count,
877159d09a2SMark Phalan ctx->tgs_ktypes, &nctx->in_tkt_ktypes);
878159d09a2SMark Phalan if (ret)
879159d09a2SMark Phalan goto errout;
880159d09a2SMark Phalan nctx->tgs_ktype_count = ctx->tgs_ktype_count;
881159d09a2SMark Phalan
882159d09a2SMark Phalan if (ctx->os_context->default_ccname != NULL) {
883159d09a2SMark Phalan nctx->os_context->default_ccname =
884159d09a2SMark Phalan strdup(ctx->os_context->default_ccname);
885159d09a2SMark Phalan if (nctx->os_context->default_ccname == NULL) {
886159d09a2SMark Phalan ret = ENOMEM;
887159d09a2SMark Phalan goto errout;
888159d09a2SMark Phalan }
889159d09a2SMark Phalan }
890159d09a2SMark Phalan ret = krb5_get_profile(ctx, &nctx->profile);
891159d09a2SMark Phalan if (ret)
892159d09a2SMark Phalan goto errout;
893159d09a2SMark Phalan
894159d09a2SMark Phalan errout:
895159d09a2SMark Phalan if (ret) {
896159d09a2SMark Phalan krb5_free_context(nctx);
897159d09a2SMark Phalan } else {
898159d09a2SMark Phalan *nctx_out = nctx;
899159d09a2SMark Phalan }
900159d09a2SMark Phalan return ret;
901159d09a2SMark Phalan }
9027c478bd9Sstevel@tonic-gate #endif /* !KERNEL */
903159d09a2SMark Phalan
904159d09a2SMark Phalan
905