# HG changeset patch # User gtb # Date 1189807284 25200 # Node ID 532e59d6bffd755680b409174564afcfe31d7bae # Parent 82bdd5527b91ad5ab4a20728632e9a539ca62828 6573019 mit 1.4 sub-glue layer resync diff -r 82bdd5527b91 -r 532e59d6bffd deleted_files/usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,148 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * XXX: I know where to find this header, but it really is using a + * private interface. I dont want to export the gss_mechanism + * structure, so I hide it in a non-published header. Thats ok, + * we know where to find it. + */ +#include + +#include +#include +#include +/* + * These are the extern declarations, one group per mechanism. They are + * contained in the files named _gssd_extern_srvr.conf. + */ + +static OM_uint32 +krb5_gss_get_context + PROTOTYPE((void**)); + +/* + * This is the declaration of the mechs_array table for Kerberos V5. + * If the gss_mechanism structure changes, so should this array! I + * told you it was a private interface! + */ + +static struct gss_config krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + 0, /* context, to be filled */ + krb5_gss_acquire_cred, + krb5_gss_release_cred, + krb5_gss_init_sec_context, + krb5_gss_accept_sec_context, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + krb5_gss_unseal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + krb5_gss_process_context_token, + krb5_gss_delete_sec_context, + krb5_gss_context_time, + krb5_gss_display_status, + krb5_gss_indicate_mechs, + krb5_gss_compare_name, + krb5_gss_display_name, + krb5_gss_import_name, + krb5_gss_release_name, + krb5_gss_inquire_cred, + krb5_gss_add_cred, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + krb5_gss_seal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + krb5_gss_export_sec_context, + krb5_gss_import_sec_context, + krb5_gss_inquire_cred_by_mech, + krb5_gss_inquire_names_for_mech, + krb5_gss_inquire_context, + krb5_gss_internal_release_oid, + krb5_gss_wrap_size_limit, + krb5_pname_to_uid, + krb5_gss_userok, + NULL, /* export_name */ +/* EXPORT DELETE START */ +/* CRYPT DELETE START */ +#if 0 +/* CRYPT DELETE END */ + krb5_gss_seal, + krb5_gss_unseal, +/* CRYPT DELETE START */ +#endif +/* CRYPT DELETE END */ +/* EXPORT DELETE END */ + krb5_gss_sign, + krb5_gss_verify, + krb5_gss_store_cred, + }; + +#include + + +OM_uint32 +krb5_gss_get_context(context) +void ** context; +{ + /* Solaris Kerberos: the following is a global variable declared + * and initialized in gssapi_krb5.c */ + /* static krb5_context kg_context = NULL; */ + krb5_error_code errCode = 0; + + if (context == NULL) + return (GSS_S_FAILURE); + if (kg_context) { + *context = kg_context; + return (GSS_S_COMPLETE); + } + + if ((errCode = krb5_init_context(&kg_context))) + goto error; + + if (((errCode = krb5_ser_context_init(kg_context)) != 0) || + ((errCode = krb5_ser_auth_context_init(kg_context)) != 0) || + ((errCode = krb5_ser_ccache_init(kg_context)) != 0) || + ((errCode = krb5_ser_rcache_init(kg_context)) != 0) || + ((errCode = krb5_ser_keytab_init(kg_context)) != 0) || + ((errCode = krb5_ser_context_init(kg_context)) != 0)) { + krb5_free_context(kg_context); + kg_context = 0; + goto error; + } + + *context = kg_context; + return (GSS_S_COMPLETE); + +error: + if (errCode != 0) { + syslog(LOG_ERR, + dgettext(TEXT_DOMAIN, + + "Kerberos mechanism library" + " initialization error: %s."), + error_message((long)errCode)); + } + return (GSS_S_FAILURE); +} + +/* + * entry point for the gss layer, + * called "krb5_gss_initialize()" in MIT 1.2.1 + */ +gss_mechanism +gss_mech_initialize(oid) +const gss_OID oid; +{ + /* ensure that the requested oid matches our oid */ + if (oid == NULL || !g_OID_equal(oid, &krb5_mechanism.mech_type)) + return (NULL); + + if (krb5_gss_get_context(&(krb5_mechanism.context)) != + GSS_S_COMPLETE) + return (NULL); + + return (&krb5_mechanism); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/Makefile --- a/usr/src/lib/gss_mechs/mech_krb5/Makefile Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/Makefile Fri Sep 14 15:01:24 2007 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -99,7 +99,7 @@ $(RM) Makefile+ Makefile.mech_krb5+\ crypto/des/afsstring2key.c+ \ crypto/des/string2key.c+ \ - mech/k5mech.c+ + mech/krb5_gss_glue.c+ $(SED) -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \ < crypto/des/afsstring2key.c > crypto/des/afsstring2key.c+ @@ -110,8 +110,8 @@ $(MV) crypto/des/string2key.c+ crypto/des/string2key.c $(SED) -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \ - < mech/k5mech.c > mech/k5mech.c+ - $(MV) mech/k5mech.c+ mech/k5mech.c + < mech/krb5_gss_glue.c > mech/krb5_gss_glue.c+ + $(MV) mech/krb5_gss_glue.c+ mech/krb5_gss_glue.c $(SED) -e "/^# EXPORT DELETE START/,/^# EXPORT DELETE END/d" \ < Makefile.mech_krb5 > Makefile.mech_krb5+ @@ -124,18 +124,18 @@ $(CHMOD) 444 Makefile Makefile.mech_krb5 \ crypto/des/afsstring2key.c \ crypto/des/string2key.c \ - mech/k5mech.c + mech/krb5_gss_glue.c # CRYPT DELETE START # Special target to clean up the source tree for domestic distribution # Warning: This target changes the source tree CRYPT_SRC: - $(RM) Makefile+ mech/k5mech.c+ + $(RM) Makefile+ mech/krb5_gss_glue.c+ $(SED) -e "/CRYPT DELETE START/,/CRYPT DELETE END/d" \ - > mech/k5mech.c+ < mech/k5mech.c - $(MV) mech/k5mech.c+ mech/k5mech.c + > mech/krb5_gss_glue.c+ < mech/krb5_gss_glue.c + $(MV) mech/krb5_gss_glue.c+ mech/krb5_gss_glue.c $(SED) -e "/^# CRYPT DELETE START/,/^# CRYPT DELETE END/d" \ < Makefile \ @@ -143,7 +143,7 @@ > Makefile+ $(MV) Makefile+ Makefile - $(CHMOD) 444 mech/k5mech.c Makefile + $(CHMOD) 444 mech/krb5_gss_glue.c Makefile # CRYPT DELETE END # EXPORT DELETE END diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/Makefile.com --- a/usr/src/lib/gss_mechs/mech_krb5/Makefile.com Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/Makefile.com Fri Sep 14 15:01:24 2007 -0700 @@ -169,13 +169,14 @@ disp_name.o disp_status.o export_sec_context.o \ get_tkt_flags.o import_name.o indicate_mechs.o \ inq_context.o inq_cred.o inq_names.o \ - k5mech.o \ + krb5_gss_glue.o \ pname_to_uid.o process_context_token.o \ rel_buffer.o rel_oid.o rel_oid_set.o \ rel_cred.o rel_name.o util_buffer.o \ util_dup.o util_localhost.o \ util_cksum.o acquire_cred.o init_sec_context.o \ - util_ctxsetup.o set_ccache.o acquire_cred_with_pw.o + set_ccache.o acquire_cred_with_pw.o lucid_context.o \ + set_allowable_enctypes.o oid_ops.o export_name.o gss_libinit.o MECH_UTS= delete_sec_context.o gssapi_krb5.o \ import_sec_context.o k5seal.o k5sealv3.o \ @@ -185,13 +186,15 @@ util_set.o util_token.o util_validate.o \ val_cred.o verify.o wrap_size_limit.o +GSSAPI_UTS= gen_oids.o + PROFILE_OBJS= prof_tree.o prof_file.o prof_parse.o prof_init.o \ prof_set.o prof_get.o -SUPPORT_OBJS= fake-addrinfo.o threads.o errors.o plugins.o +SUPPORT_OBJS= fake-addrinfo.o threads.o errors.o plugins.o OBJECTS= \ - $(MECH) $(MECH_UTS) \ + $(MECH) $(MECH_UTS) $(GSSAPI_UTS)\ $(SUPPORT_OBJS) \ $(PROFILE_OBJS) \ $(CRYPTO) $(CRYPTO_UTS) \ @@ -230,6 +233,7 @@ CPPFLAGS += -I$(REL_PATH)/libgss -I../include \ -I$(SRC)/uts/common/gssapi \ -I$(SRC)/uts/common/gssapi/include \ + -I$(SRC)/lib/gss_mechs/mech_krb5/mech \ -I$(SRC)/lib/gss_mechs/mech_krb5/include/krb5 \ -I../include/krb5 \ -I../krb5/keytab \ @@ -302,6 +306,10 @@ # mech lib needs special initialization at load time DYNFLAGS += -zinitarray=krb5_ld_init +objs/%.o pics/%.o: $(SRC)/uts/common/gssapi/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) + objs/%.o pics/%.o: $(SRC)/uts/common/gssapi/mechs/krb5/mech/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) @@ -481,8 +489,7 @@ -DHAVE_ERRNO -DHAVE_STRFTIME -DHAVE_STRPTIME -DHAVE_STRERROR \ -DHAVE_STAT -DSIZEOF_INT=4 -DPROVIDE_KERNEL_IMPORT \ -DHAVE_STDINT_H -DPOSIX_SIGNALS -DHAVE_GETENV -DHAVE_SETENV \ - -DHAVE_UNSETENV -DHAVE_FCHMOD -DHAVE_STRUCT_LIFCONF \ - -DHAVE_ACCESS + -DHAVE_UNSETENV -DHAVE_FCHMOD -DHAVE_STRUCT_LIFCONF CPPFLAGS += -I$(REL_PATH)krb5/ccache/file $(OS_FLAGS) @@ -522,6 +529,7 @@ $(K5_RCACHE:%.o= $(SRC)/lib/gss_mechs/mech_krb5/krb5/rcache/%.c) \ $(MECH:%.o= $(SRC)/lib/gss_mechs/mech_krb5/mech/%.c) \ $(MECH_UTS:%.o= $(SRC)/uts/common/gssapi/mechs/krb5/mech/%.c) \ + $(GSSAPI_UTS:%.o= $(SRC)/uts/common/gssapi/%.c) \ $(PROFILE_OBJS:%.o= $(SRC)/lib/gss_mechs/mech_krb5/profile/%.c) \ $(SUPPORT_OBJS:%.o= $(SRC)/lib/gss_mechs/mech_krb5/support/%.c) diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c --- a/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,3 +66,14 @@ return(ret); } + +size_t KRB5_CALLCONV +krb5_encrypt_size(size_t length, krb5_enctype crypto) +{ + size_t ret; + + if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret)) + return(-1); /* XXX */ + + return(ret); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/file/ktfile.h --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/file/ktfile.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/file/ktfile.h Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * lib/krb5/keytab/file/ktfile.h @@ -79,103 +79,103 @@ extern struct _krb5_kt_ops krb5_ktf_writable_ops; krb5_error_code KRB5_CALLCONV krb5_ktfile_resolve - PROTOTYPE((krb5_context, + (krb5_context, const char *, - krb5_keytab *)); + krb5_keytab *); krb5_error_code KRB5_CALLCONV krb5_ktfile_wresolve - PROTOTYPE((krb5_context, + (krb5_context, const char *, - krb5_keytab *)); + krb5_keytab *); krb5_error_code KRB5_CALLCONV krb5_ktfile_get_name - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, char *, - int)); + int); krb5_error_code KRB5_CALLCONV krb5_ktfile_close - PROTOTYPE((krb5_context, - krb5_keytab)); + (krb5_context, + krb5_keytab); krb5_error_code KRB5_CALLCONV krb5_ktfile_get_entry - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, krb5_const_principal, krb5_kvno, krb5_enctype, - krb5_keytab_entry *)); + krb5_keytab_entry *); krb5_error_code KRB5_CALLCONV krb5_ktfile_start_seq_get - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_kt_cursor *)); + krb5_kt_cursor *); krb5_error_code KRB5_CALLCONV krb5_ktfile_get_next - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, krb5_keytab_entry *, - krb5_kt_cursor *)); + krb5_kt_cursor *); krb5_error_code KRB5_CALLCONV krb5_ktfile_end_get - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_kt_cursor *)); + krb5_kt_cursor *); /* routines to be included on extended version (write routines) */ krb5_error_code KRB5_CALLCONV krb5_ktfile_add - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_keytab_entry *)); + krb5_keytab_entry *); krb5_error_code KRB5_CALLCONV krb5_ktfile_remove - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_keytab_entry *)); + krb5_keytab_entry *); krb5_error_code krb5_ktfileint_openr - PROTOTYPE((krb5_context, - krb5_keytab)); + (krb5_context, + krb5_keytab); krb5_error_code krb5_ktfileint_openw - PROTOTYPE((krb5_context, - krb5_keytab)); + (krb5_context, + krb5_keytab); krb5_error_code krb5_ktfileint_close - PROTOTYPE((krb5_context, - krb5_keytab)); + (krb5_context, + krb5_keytab); krb5_error_code krb5_ktfileint_read_entry - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_keytab_entry *)); + krb5_keytab_entry *); krb5_error_code krb5_ktfileint_write_entry - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_keytab_entry *)); + krb5_keytab_entry *); krb5_error_code krb5_ktfileint_delete_entry - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, - krb5_int32)); + krb5_int32); krb5_error_code krb5_ktfileint_internal_read_entry - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, krb5_keytab_entry *, - krb5_int32 *)); + krb5_int32 *); krb5_error_code krb5_ktfileint_size_entry - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab_entry *, - krb5_int32 *)); + krb5_int32 *); krb5_error_code krb5_ktfileint_find_slot - PROTOTYPE((krb5_context, + (krb5_context, krb5_keytab, krb5_int32 *, - krb5_int32 *)); + krb5_int32 *); #endif /* _KRB5_KTFILE */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -721,14 +721,18 @@ if (strncmp(krb5_princ_component(context, aname, 1)->data, def_realm, realm_length) || realm_length != - krb5_princ_component(context, aname, 1)->length) + krb5_princ_component(context, aname, 1)->length) { /* XXX an_to_ln_realm_chk ? */ + free(def_realm); return KRB5_LNAME_NOTRANS; + } } - else + else { /* no components or more than one component to non-realm part of name --no translation. */ + free(def_realm); return KRB5_LNAME_NOTRANS; + } } free(def_realm); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -359,12 +359,14 @@ } OM_uint32 -krb5_gss_userok(void *ctxt, - OM_uint32 *minor, +krb5_gss_userok(OM_uint32 *minor, const gss_name_t pname, const char *user, int *user_ok) { + krb5_context ctxt; + OM_uint32 kret; + if (pname == NULL || user == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); @@ -373,13 +375,22 @@ *user_ok = 0; + kret = krb5_gss_init_context(&ctxt); + if (kret) { + *minor = kret; + return (GSS_S_FAILURE); + } + if (! kg_validate_name(pname)) { - *minor = (OM_uint32) G_VALIDATE_FAILED; - return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + *minor = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(ctxt); + return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } if (krb5_kuserok(ctxt, (krb5_principal) pname, user)) { *user_ok = 1; } + + krb5_free_context(ctxt); return (GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mapfile-vers --- a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers Fri Sep 14 15:01:24 2007 -0700 @@ -212,7 +212,6 @@ decode_krb5_tgs_rep; decode_krb5_tgs_req; decode_krb5_ticket; - display_unknown; encode_krb5_alt_method; encode_krb5_ap_rep; encode_krb5_ap_rep_enc_part; @@ -247,47 +246,16 @@ encode_krb5_tgs_req; encode_krb5_ticket; error_message; - g_delete_cred_id; - g_delete_ctx_id; - g_delete_name; - g_display_com_err_status; - g_display_major_status; - g_local_host_name; - g_make_string_buffer; - g_make_token_header; - g_order_check; - g_order_free; - g_order_init; - g_queue_externalize; - g_queue_internalize; - g_queue_size; - g_save_cred_id; - g_save_ctx_id; - g_save_name; - g_set_destroy; - g_set_entry_add; - g_set_entry_delete; - g_set_entry_get; - g_set_init; - g_strdup; - g_token_size; - g_validate_cred_id; - g_validate_ctx_id; - g_validate_name; - g_verify_token_header; ggss_error_table; gmt_mktime; + gss_krb5int_get_tkt_flags; gss_krb5_ccache_name; gss_krb5_copy_ccache; - gss_krb5_get_tkt_flags; gss_mech_krb5; gss_mech_krb5_old; - gss_mech_krb5_v2; gss_mech_set_krb5; gss_mech_set_krb5_both; gss_mech_set_krb5_old; - gss_mech_set_krb5_v1v2; - gss_mech_set_krb5_v2; gss_nt_krb5_name; gss_nt_krb5_principal; gssspi_acquire_cred_with_password; @@ -298,25 +266,18 @@ kadm_error_table; kdb5_error_table; kdc5_error_table; - kg2_parse_token; - kg_checksum_channel_bindings; kg_confounder_size; - kg_context; kg_ctx_externalize; kg_ctx_internalize; kg_ctx_size; kg_decrypt; kg_encrypt; kg_encrypt_size; - kg_get_context; kg_get_defcred; kg_get_seq_num; kg_make_confounder; kg_make_seed; kg_make_seq_num; - kg_oid_size; - kg_queue_size; - kg_release_defcred; kg_seal; kg_unseal; kg_vdb; @@ -551,7 +512,6 @@ krb5_get_validated_creds; krb5_getenv; krb5_gss_import_name; - krb5_gss_init_sec_context; krb5_gss_oid_array; krb5_gss_userok; krb5_hmac; @@ -619,7 +579,6 @@ krb5_mk_req; krb5_mk_req_extended; krb5_mk_safe; - krb5_mutex; krb5_net_read; krb5_net_write; krb5_nfold; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -6,7 +6,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" /* - * Copyright 2000 by the Massachusetts Institute of Technology. + * Copyright 2000, 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -80,20 +80,21 @@ #include #include #include +#ifdef HAVE_MEMORY_H #include +#endif #include -#define CACHENAME_LEN 35 /* Solaris kerberos: XXX kludgy but there is no include file for the * krb5_fcc_ops extern declaration. */ extern krb5_cc_ops krb5_fcc_ops; +#ifdef CFX_EXERCISE +#define CFX_ACCEPTOR_SUBKEY (time(0) & 1) +#else #define CFX_ACCEPTOR_SUBKEY 1 - -/* - * $Id: accept_sec_context.c,v 1.51.2.3 2000/06/08 00:25:48 tlyu Exp $ - */ +#endif /* * Decode, decrypt and store the forwarded creds in the local ccache. @@ -109,6 +110,7 @@ { krb5_creds ** creds; krb5_error_code retval; + krb5_ccache template_ccache = NULL; krb5_ccache ccache = NULL; krb5_gss_cred_id_t cred = NULL; krb5_auth_context new_auth_ctx = NULL; @@ -177,13 +179,15 @@ /* Lots of kludging going on here... Some day the ccache interface will be rewritten though */ - retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &ccache); + retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &template_ccache); if (retval) { KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error " "krb5_cc_resolve() retval = %d\n", retval); goto cleanup; } + ccache = template_ccache; /* krb5_cc_gen_new will replace so make a copy */ + retval = krb5_cc_gen_new(context, &ccache); if (retval) { KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error " @@ -218,11 +222,19 @@ /* zero it out... */ (void) memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); + retval = k5_mutex_init(&cred->lock); + if (retval) { + xfree(cred); + cred = NULL; + goto cleanup; + } + /* copy the client principle into it... */ if ((retval = krb5_copy_principal(context, creds[0]->client, &(cred->princ)))) { KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error " "krb5_copy_principal() retval = %d\n", retval); + k5_mutex_destroy(&cred->lock); retval = ENOMEM; /* out of memory? */ xfree(cred); /* clean up memory on failure */ *out_cred = cred = NULL; @@ -231,15 +243,13 @@ cred->usage = GSS_C_INITIATE; /* we can't accept with this */ /* cred->princ already set */ - cred->actual_mechs = gss_mech_set_krb5_both; cred->prerfc_mech = 1; /* this cred will work with all three mechs */ cred->rfc_mech = 1; cred->keytab = NULL; /* no keytab associated with this... */ - cred->ccache = ccache; /* but there is a credential cache */ /* The cred expires when the original cred was set to expire */ cred->tgt_expire = creds[0]->times.endtime; - - *out_cred = cred; + cred->ccache = ccache; /* the ccache containing the credential */ + ccache = NULL; /* cred takes ownership so don't destroy */ } /* If there were errors, there might have been a memory leak @@ -248,10 +258,19 @@ goto cleanup; */ cleanup: - krb5_free_tgt_creds(context, creds); + if (creds) + krb5_free_tgt_creds(context, creds); + + if (ccache) + (void)krb5_cc_destroy(context, ccache); - if (!cred && ccache) - (void)krb5_cc_close(context, ccache); + /* + * SUNW15resync + * Added this cc_destroy for template_cache, w/out it causes memory + * leak via "ssh -o gssapidelegatecredentials=yes ..." + */ + if (template_ccache) + (void)krb5_cc_destroy(context, template_ccache); if (out_cred) *out_cred = cred; /* return credential */ @@ -265,13 +284,17 @@ return retval; } +/* + * SUNW15resync + * Most of the logic here left "as is" because of lots of fixes MIT + * does not have yet + */ OM_uint32 -krb5_gss_accept_sec_context(ct, minor_status, context_handle, +krb5_gss_accept_sec_context(minor_status, context_handle, verifier_cred_handle, input_token, input_chan_bindings, src_name, mech_type, output_token, ret_flags, time_rec, delegated_cred_handle) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_cred_id_t verifier_cred_handle; @@ -284,7 +307,7 @@ OM_uint32 *time_rec; gss_cred_id_t *delegated_cred_handle; { - krb5_context context = ct; + krb5_context context; unsigned char *ptr, *ptr2; char *sptr; long tmp; @@ -314,17 +337,22 @@ gss_cred_id_t cred_handle = NULL; krb5_gss_cred_id_t deleg_cred = NULL; OM_uint32 saved_ap_options = 0; + krb5int_access kaccess; + int cred_rcache = 0; KRB5_LOG0(KRB5_INFO,"krb5_gss_accept_sec_context() start"); - mutex_lock(&krb5_mutex); + code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); + if (code) { + *minor_status = code; + return(GSS_S_FAILURE); + } - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } /* set up returns to be freeable */ @@ -363,7 +391,7 @@ major_status = GSS_S_NO_CONTEXT; KRB5_LOG0(KRB5_ERR,"krb5_gss_accept_sec_context() " "error GSS_S_NO_CONTEXT"); - goto unlock; + goto cleanup; } /* verify the token's integrity, and leave the token in ap_req. @@ -371,13 +399,13 @@ ptr = (unsigned char *) input_token->value; - if (!(code = g_verify_token_header((gss_OID) gss_mech_krb5, + if (!(code = g_verify_token_header(gss_mech_krb5, (uint32_t *)&(ap_req.length), &ptr, KG_TOK_CTX_AP_REQ, input_token->length, 1))) { mech_used = gss_mech_krb5; } else if ((code == G_WRONG_MECH) && - !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old, + !(code = g_verify_token_header(gss_mech_krb5_old, (uint32_t *)&(ap_req.length), &ptr, KG_TOK_CTX_AP_REQ, input_token->length, 1))) { @@ -446,7 +474,7 @@ major_status = GSS_S_FAILURE; goto fail; } - major_status = krb5_gss_acquire_cred_no_lock(context, (OM_uint32*) &code, + major_status = krb5_gss_acquire_cred((OM_uint32*) &code, (gss_name_t) princ, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_ACCEPT, &cred_handle, @@ -470,7 +498,7 @@ cred_handle = verifier_cred_handle; } - major_status = krb5_gss_validate_cred_no_lock(context, (OM_uint32*) &code, + major_status = krb5_gss_validate_cred((OM_uint32*) &code, cred_handle); if (GSS_ERROR(major_status)){ @@ -527,12 +555,14 @@ (void) krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); - if (cred->rcache && - (code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) { - major_status = GSS_S_FAILURE; - KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() " - "krb5_auth_con_setrcache() error code %d", code); - goto fail; + if (cred->rcache) { + cred_rcache = 1; + if ((code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) { + major_status = GSS_S_FAILURE; + KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() " + "krb5_auth_con_setrcache() error code %d", code); + goto fail; + } } if ((code = krb5_auth_con_setaddrs(context, auth_context, NULL, paddr))) { major_status = GSS_S_FAILURE; @@ -731,24 +761,7 @@ memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); - /* Solaris Kerberos: we allocate the memory for mech_used here - * because we store mech_used as a gss_OID and not a (gss_OID *) - */ -#if 0 - ctx->mech_used = mech_used; -#else - /* begin Solaris Kerberos solution */ - ctx->mech_used.elements = (void *)malloc(mech_used->length); - if ( (ctx->mech_used.elements) == NULL ) - { - code = ENOMEM; - major_status = GSS_S_FAILURE; - goto fail; - } - ctx->mech_used.length = mech_used->length; - memcpy(ctx->mech_used.elements, mech_used->elements, mech_used->length); -#endif - + ctx->mech_used = (gss_OID) mech_used; ctx->auth_context = auth_context; ctx->initiate = 0; ctx->gss_flags = (GSS_C_TRANS_FLAG | @@ -757,6 +770,7 @@ GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))); ctx->seed_init = 0; ctx->big_endian = bigend; + ctx->cred_rcache = cred_rcache; /* Intern the ctx pointer so that delete_sec_context works */ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { @@ -970,7 +984,7 @@ /* the reply token hasn't been sent yet, but that's ok. */ ctx->gss_flags |= GSS_C_PROT_READY_FLAG; ctx->established = 1; - token.length = g_token_size((gss_OID) mech_used, ap_rep.length); + token.length = g_token_size(mech_used, ap_rep.length); if ((token.value = (unsigned char *) xmalloc(token.length)) == NULL) { @@ -979,7 +993,7 @@ goto fail; } ptr = token.value; - g_make_token_header((gss_OID) mech_used, ap_rep.length, + g_make_token_header(mech_used, ap_rep.length, &ptr, KG_TOK_CTX_AP_REP); TWRITE_STR(ptr, ap_rep.data, ap_rep.length); @@ -1040,9 +1054,12 @@ fail: if (authdat) krb5_free_authenticator(context, authdat); + /* The ctx structure has the handle of the auth_context */ if (auth_context && !ctx) { - (void)krb5_auth_con_setrcache(context, auth_context, NULL); - krb5_auth_con_free(context, auth_context); + if (cred_rcache) + (void)krb5_auth_con_setrcache(context, auth_context, NULL); + + krb5_auth_con_free(context, auth_context); } if (reqcksum.contents) xfree(reqcksum.contents); @@ -1055,13 +1072,21 @@ request = NULL; } - if (!GSS_ERROR(major_status)) - goto unlock; + if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED) { + if (!verifier_cred_handle && cred_handle) { + krb5_gss_release_cred(minor_status, &cred_handle); + } + + if (ctx) + ctx->k5_context = context; + + return(major_status); + } /* from here on is the real "fail" code */ if (ctx) - (void) krb5_gss_delete_sec_context_no_lock(context, minor_status, + (void) krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL); if (deleg_cred) { /* free memory associated with the deleg credential */ if (deleg_cred->ccache) @@ -1104,18 +1129,18 @@ code = krb5_mk_error(context, &krb_error_data, &scratch); if (code) - goto unlock; + goto cleanup; tmsglen = scratch.length; toktype = KG_TOK_CTX_ERROR; - token.length = g_token_size((gss_OID) mech_used, tmsglen); + token.length = g_token_size(mech_used, tmsglen); token.value = (unsigned char *) xmalloc(token.length); if (!token.value) - goto unlock; + goto cleanup; ptr = token.value; - g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype); + g_make_token_header(mech_used, tmsglen, &ptr, toktype); TWRITE_STR(ptr, scratch.data, scratch.length); xfree(scratch.data); @@ -1123,12 +1148,13 @@ *output_token = token; } -unlock: +cleanup: if (!verifier_cred_handle && cred_handle) { - krb5_gss_release_cred_no_lock(context, (OM_uint32*) &code, &cred_handle); + krb5_gss_release_cred(minor_status, &cred_handle); } - mutex_unlock(&krb5_mutex); + krb5_free_context(context); + KRB5_LOG(KRB5_ERR,"krb5_gss_accept_sec_context() end, " "major_status = %d", major_status); return (major_status); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -13,7 +13,7 @@ * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -27,12 +27,11 @@ * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * */ - /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -42,7 +41,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -54,14 +53,14 @@ /* * Copyright (C) 1998 by the FundsXpress, INC. - * + * * All rights reserved. - * + * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -72,24 +71,70 @@ * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#include -#include - +#include "k5-int.h" +#include "gss_libinit.h" +#include "gssapiP_krb5.h" +#include "mglueP.h" #ifdef HAVE_STRING_H #include #else #include #endif -/* - * $Id: acquire_cred.c,v 1.25.6.2 2000/05/22 20:41:32 meeroh Exp $ - */ +/* SUNW15resync - Solaris kerberos does not need this feature in this file */ +#ifdef USE_LOGIN_LIBRARY +#undef USE_LOGIN_LIBRARY +#endif + +#if defined(USE_LOGIN_LIBRARY) +#include +#elif defined(USE_LEASH) +static void (*pLeash_AcquireInitialTicketsIfNeeded)(krb5_context,krb5_principal,char*,int) = NULL; +static HANDLE hLeashDLL = INVALID_HANDLE_VALUE; +#endif + +k5_mutex_t gssint_krb5_keytab_lock = K5_MUTEX_PARTIAL_INITIALIZER; +static char *krb5_gss_keytab = NULL; + +/* Heimdal calls this gsskrb5_register_acceptor_identity. */ +OM_uint32 KRB5_CALLCONV +krb5_gss_register_acceptor_identity(const char *keytab) +{ + size_t len; + char *new, *old; + int err; + + err = gssint_initialize_library(); + if (err != 0) + return GSS_S_FAILURE; + + if (keytab == NULL) + return GSS_S_FAILURE; + + len = strlen(keytab); + new = malloc(len + 1); + if (new == NULL) + return GSS_S_FAILURE; + strcpy(new, keytab); + + err = k5_mutex_lock(&gssint_krb5_keytab_lock); + if (err) { + free(new); + return GSS_S_FAILURE; + } + old = krb5_gss_keytab; + krb5_gss_keytab = new; + k5_mutex_unlock(&gssint_krb5_keytab_lock); + if (old != NULL) + free(old); + return GSS_S_COMPLETE; +} /* get credentials corresponding to a key in the krb5 keytab. If the default name is requested, return the name in output_princ. @@ -98,7 +143,7 @@ If successful, set the keytab-specific fields in cred */ -static OM_uint32 +static OM_uint32 acquire_accept_cred(context, minor_status, desired_name, output_princ, cred) krb5_context context; OM_uint32 *minor_status; @@ -116,9 +161,27 @@ /* open the default keytab */ - if ((code = krb5_kt_default(context, &kt))) { + code = gssint_initialize_library(); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + code = k5_mutex_lock(&gssint_krb5_keytab_lock); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } + if (krb5_gss_keytab != NULL) { + code = krb5_kt_resolve(context, krb5_gss_keytab, &kt); + k5_mutex_unlock(&gssint_krb5_keytab_lock); + } else { + k5_mutex_unlock(&gssint_krb5_keytab_lock); + code = krb5_kt_default(context, &kt); + } + + if (code) { *minor_status = code; - /* NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */ + /* Solaris Kerb NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */ return(GSS_S_NO_CRED); } @@ -130,7 +193,7 @@ *minor_status = KG_KEYTAB_NOMATCH; else *minor_status = code; - /* NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */ + /* Solaris Kerb NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */ return(GSS_S_NO_CRED); } krb5_kt_free_entry(context, &entry); @@ -145,7 +208,7 @@ } - /* hooray. we made it */ +/* hooray. we made it */ cred->keytab = kt; @@ -159,7 +222,7 @@ If successful, set the ccache-specific fields in cred. */ -static OM_uint32 +static OM_uint32 acquire_init_cred(context, minor_status, desired_name, output_princ, cred) krb5_context context; OM_uint32 *minor_status; @@ -177,19 +240,77 @@ cred->ccache = NULL; - /* SUNW14resync - do we need this? */ -#if 0 /* load the GSS ccache name into the kg_context */ + if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) return(GSS_S_FAILURE); -#endif - - /* open the default credential cache */ - code = krb5int_cc_default(context, &ccache); - if (code) { - *minor_status = code; - return(GSS_S_NO_CRED); +#if defined(USE_LOGIN_LIBRARY) || defined(USE_LEASH) + if (desired_name != NULL) { +#if defined(USE_LOGIN_LIBRARY) + char *ccache_name = NULL; + KLPrincipal kl_desired_princ = NULL; + + if ((code = __KLCreatePrincipalFromKerberos5Principal ((krb5_principal) desired_name, + &kl_desired_princ))) { + *minor_status = code; + return(GSS_S_NO_CRED); + } + + if ((code = KLAcquireInitialTickets (kl_desired_princ, NULL, NULL, &ccache_name))) { + KLDisposePrincipal (kl_desired_princ); + *minor_status = code; + return(GSS_S_NO_CRED); + } + + if ((code = krb5_cc_resolve (context, ccache_name, &ccache))) { + KLDisposeString (ccache_name); + KLDisposePrincipal (kl_desired_princ); + *minor_status = code; + return(GSS_S_NO_CRED); + } + + if (kl_desired_princ != NULL) { KLDisposePrincipal (kl_desired_princ); } + if (ccache_name != NULL) { KLDisposeString (ccache_name); } +#elif defined(USE_LEASH) + if ( hLeashDLL == INVALID_HANDLE_VALUE ) { + hLeashDLL = LoadLibrary("leashw32.dll"); + if ( hLeashDLL != INVALID_HANDLE_VALUE ) { + (FARPROC) pLeash_AcquireInitialTicketsIfNeeded = + GetProcAddress(hLeashDLL, "not_an_API_Leash_AcquireInitialTicketsIfNeeded"); + } + } + + if ( pLeash_AcquireInitialTicketsIfNeeded ) { + char ccname[256]=""; + pLeash_AcquireInitialTicketsIfNeeded(context, (krb5_principal) desired_name, ccname, sizeof(ccname)); + if (!ccname[0]) { + *minor_status = KRB5_CC_NOTFOUND; + return(GSS_S_NO_CRED); + } + + if ((code = krb5_cc_resolve (context, ccname, &ccache))) { + *minor_status = code; + return(GSS_S_NO_CRED); + } + } else { + /* leash dll not available, open the default credential cache */ + + if ((code = krb5int_cc_default(context, &ccache))) { + *minor_status = code; + return(GSS_S_NO_CRED); + } + } +#endif /* USE_LEASH */ + } else +#endif /* USE_LOGIN_LIBRARY || USE_LEASH */ + { + /* open the default credential cache */ + + if ((code = krb5int_cc_default(context, &ccache))) { + *minor_status = code; + return(GSS_S_NO_CRED); + } } /* turn off OPENCLOSE mode while extensive frobbing is going on */ @@ -200,7 +321,7 @@ * the file like it used to and caused STC test gss.27 to fail. */ flags = 0; /* turns off OPENCLOSE mode */ - if ((code = krb5_cc_set_flags(context, ccache, flags)) != 0) { + if ((code = krb5_cc_set_flags(context, ccache, flags))) { (void)krb5_cc_close(context, ccache); *minor_status = code; return(GSS_S_NO_CRED); @@ -208,7 +329,7 @@ /* get out the principal name and see if it matches */ - if ((code = krb5_cc_get_principal(context, ccache, &princ)) != 0) { + if ((code = krb5_cc_get_principal(context, ccache, &princ))) { (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE); (void)krb5_cc_close(context, ccache); *minor_status = code; @@ -218,7 +339,7 @@ if (desired_name != (gss_name_t) NULL) { if (! krb5_principal_compare(context, princ, (krb5_principal) desired_name)) { (void)krb5_free_principal(context, princ); - (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE); + (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE); (void)krb5_cc_close(context, ccache); *minor_status = KG_CCACHE_NOMATCH; return(GSS_S_NO_CRED); @@ -231,7 +352,7 @@ /* iterate over the ccache, find the tgt */ - if ((code = krb5_cc_start_seq_get(context, ccache, &cur)) != 0) { + if ((code = krb5_cc_start_seq_get(context, ccache, &cur))) { (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE); (void)krb5_cc_close(context, ccache); *minor_status = code; @@ -257,7 +378,7 @@ *minor_status = code; return(GSS_S_FAILURE); } - while ((code = krb5_cc_next_cred(context, ccache, &cur, &creds)) == 0) { + while (!(code = krb5_cc_next_cred(context, ccache, &cur, &creds))) { if (krb5_principal_compare(context, tmp_princ, creds.server)) { cred->tgt_expire = creds.times.endtime; got_endtime = 1; @@ -290,14 +411,14 @@ return(GSS_S_FAILURE); } else { /* this means that we found an endtime to use. */ - if ((code = krb5_cc_end_seq_get(context, ccache, &cur)) != 0) { + if ((code = krb5_cc_end_seq_get(context, ccache, &cur))) { (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE); (void)krb5_cc_close(context, ccache); *minor_status = code; return(GSS_S_FAILURE); } flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */ - if ((code = krb5_cc_set_flags(context, ccache, flags)) != 0) { + if ((code = krb5_cc_set_flags(context, ccache, flags))) { (void)krb5_cc_close(context, ccache); *minor_status = code; return(GSS_S_FAILURE); @@ -310,37 +431,12 @@ /* minor_status is set while we are iterating over the ccache */ return(GSS_S_COMPLETE); } - + +/*ARGSUSED*/ OM_uint32 -krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, +krb5_gss_acquire_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec) - void *ctx; - OM_uint32 *minor_status; - gss_name_t desired_name; - OM_uint32 time_req; - gss_OID_set desired_mechs; - gss_cred_usage_t cred_usage; - gss_cred_id_t *output_cred_handle; - gss_OID_set *actual_mechs; - OM_uint32 *time_rec; -{ - OM_uint32 ret; - - mutex_lock(&krb5_mutex); - ret = krb5_gss_acquire_cred_no_lock(ctx, minor_status, desired_name, - time_req, desired_mechs, cred_usage, output_cred_handle, - actual_mechs, time_rec); - mutex_unlock(&krb5_mutex); - return(ret); -} - -/*ARGSUSED*/ -OM_uint32 -krb5_gss_acquire_cred_no_lock(ctx, minor_status, desired_name, time_req, - desired_mechs, cred_usage, output_cred_handle, - actual_mechs, time_rec) - void *ctx; OM_uint32 *minor_status; gss_name_t desired_name; OM_uint32 time_req; @@ -353,20 +449,22 @@ krb5_context context; size_t i; krb5_gss_cred_id_t cred; - gss_OID_set ret_mechs = GSS_C_NULL_OID_SET; - const gss_OID_set_desc * valid_mechs; + gss_OID_set ret_mechs; int req_old, req_new; OM_uint32 ret; krb5_error_code code; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif + code = gssint_initialize_library(); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } - context = ctx; + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } /* make sure all outputs are valid */ @@ -382,6 +480,7 @@ if ((desired_name != (gss_name_t) NULL) && (! kg_validate_name(desired_name))) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } @@ -389,7 +488,6 @@ contains krb5 */ if (desired_mechs == GSS_C_NULL_OID_SET) { - valid_mechs = gss_mech_set_krb5_both; req_old = 1; req_new = 1; } else { @@ -405,6 +503,7 @@ if (!req_old && !req_new) { *minor_status = 0; + krb5_free_context(context); return(GSS_S_BAD_MECH); } } @@ -414,24 +513,36 @@ if ((cred = (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) == NULL) { *minor_status = ENOMEM; + krb5_free_context(context); return(GSS_S_FAILURE); } memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); cred->usage = cred_usage; cred->princ = NULL; - cred->actual_mechs = valid_mechs; cred->prerfc_mech = req_old; cred->rfc_mech = req_new; cred->keytab = NULL; cred->ccache = NULL; + code = k5_mutex_init(&cred->lock); + if (code) { + *minor_status = code; + krb5_free_context(context); + return GSS_S_FAILURE; + } + /* Note that we don't need to lock this GSSAPI credential record + here, because no other thread can gain access to it until we + return it. */ + if ((cred_usage != GSS_C_INITIATE) && (cred_usage != GSS_C_ACCEPT) && (cred_usage != GSS_C_BOTH)) { + k5_mutex_destroy(&cred->lock); xfree(cred); *minor_status = (OM_uint32) G_BAD_USAGE; + krb5_free_context(context); return(GSS_S_FAILURE); } @@ -445,8 +556,10 @@ != GSS_S_COMPLETE) { if (cred->princ) krb5_free_principal(context, cred->princ); - xfree(cred); + k5_mutex_destroy(&cred->lock); + xfree(cred); /* minor_status set by acquire_accept_cred() */ + krb5_free_context(context); return(ret); } @@ -462,18 +575,21 @@ &(cred->princ), cred)) != GSS_S_COMPLETE) { if (cred->keytab) - (void) krb5_kt_close(context, cred->keytab); + krb5_kt_close(context, cred->keytab); if (cred->princ) krb5_free_principal(context, cred->princ); - xfree(cred); + k5_mutex_destroy(&cred->lock); + xfree(cred); /* minor_status set by acquire_init_cred() */ + krb5_free_context(context); return(ret); } /* Solaris Kerberos: - * if the princ wasn't filled in already, fill it in now unless + * if the princ wasn't filled in already, fill it in now unless * a cred with no associated princ is requested (will invoke default * behaviour when gss_accept_init_context() is called). + * Note MIT 1.4 has GSS_C_NO_CREDENTIAL instead of GSS_C_NO_NAME */ if (!cred->princ && (desired_name != GSS_C_NO_NAME)) if ((code = krb5_copy_principal(context, (krb5_principal) desired_name, @@ -482,8 +598,10 @@ (void)krb5_cc_close(context, cred->ccache); if (cred->keytab) (void)krb5_kt_close(context, cred->keytab); - xfree(cred); + k5_mutex_destroy(&cred->lock); + xfree(cred); *minor_status = code; + krb5_free_context(context); return(GSS_S_FAILURE); } @@ -504,8 +622,10 @@ (void)krb5_kt_close(context, cred->keytab); if (cred->princ) krb5_free_principal(context, cred->princ); - xfree(cred); + k5_mutex_destroy(&cred->lock); + xfree(cred); *minor_status = code; + krb5_free_context(context); return(GSS_S_FAILURE); } @@ -516,15 +636,15 @@ /* create mechs */ if (actual_mechs) { - if (GSS_ERROR(ret = gss_create_empty_oid_set(minor_status, + if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status, &ret_mechs)) || (cred->prerfc_mech && - GSS_ERROR(ret = gss_add_oid_set_member(minor_status, - (gss_OID) gss_mech_krb5_old, + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + (const gss_OID) gss_mech_krb5_old, &ret_mechs))) || (cred->rfc_mech && - GSS_ERROR(ret = gss_add_oid_set_member(minor_status, - (gss_OID) gss_mech_krb5, + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + (const gss_OID) gss_mech_krb5, &ret_mechs)))) { if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); @@ -532,8 +652,10 @@ (void)krb5_kt_close(context, cred->keytab); if (cred->princ) krb5_free_principal(context, cred->princ); + k5_mutex_destroy(&cred->lock); xfree(cred); - /* (*minor_status) set above */ + /* *minor_status set above */ + krb5_free_context(context); return(ret); } } @@ -541,7 +663,6 @@ /* intern the credential handle */ if (! kg_save_cred_id((gss_cred_id_t) cred)) { - (void) gss_release_oid_set(NULL, &ret_mechs); free(ret_mechs->elements); free(ret_mechs); if (cred->ccache) @@ -550,8 +671,10 @@ (void)krb5_kt_close(context, cred->keytab); if (cred->princ) krb5_free_principal(context, cred->princ); + k5_mutex_destroy(&cred->lock); xfree(cred); *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); return(GSS_S_FAILURE); } @@ -561,5 +684,7 @@ *output_cred_handle = (gss_cred_id_t) cred; if (actual_mechs) *actual_mechs = ret_mechs; + + krb5_free_context(context); return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred_with_pw.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred_with_pw.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred_with_pw.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -78,6 +78,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#include "gss_libinit.h" #include #include @@ -203,12 +204,11 @@ /*ARGSUSED*/ OM_uint32 -krb5_gss_acquire_cred_with_password_no_lock(ctx, minor_status, +krb5_gss_acquire_cred_with_password(minor_status, desired_name, password, time_req, desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec) -void *ctx; OM_uint32 *minor_status; gss_name_t desired_name; const gss_buffer_t password; @@ -228,16 +228,21 @@ OM_uint32 ret; krb5_error_code code; -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return (GSS_S_FAILURE); -#endif - - context = ctx; - if (desired_name == GSS_C_NO_NAME) return (GSS_S_BAD_NAME); + code = gssint_initialize_library(); + if (code) { + *minor_status = code; + return (GSS_S_FAILURE); + } + + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return (GSS_S_FAILURE); + } + /* make sure all outputs are valid */ *output_cred_handle = NULL; @@ -249,6 +254,7 @@ /* validate the name */ if (!kg_validate_name(desired_name)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } @@ -276,6 +282,7 @@ if (!req_old && !req_new) { *minor_status = 0; + krb5_free_context(context); return (GSS_S_BAD_MECH); } } @@ -284,13 +291,13 @@ if ((cred = (krb5_gss_cred_id_t) xmalloc(sizeof (krb5_gss_cred_id_rec))) == NULL) { *minor_status = ENOMEM; + krb5_free_context(context); return (GSS_S_FAILURE); } memset(cred, 0, sizeof (krb5_gss_cred_id_rec)); cred->usage = cred_usage; cred->princ = NULL; - cred->actual_mechs = valid_mechs; cred->prerfc_mech = req_old; cred->rfc_mech = req_new; @@ -302,6 +309,7 @@ (cred_usage != GSS_C_BOTH)) { xfree(cred); *minor_status = (OM_uint32) G_BAD_USAGE; + krb5_free_context(context); return (GSS_S_FAILURE); } @@ -319,6 +327,7 @@ if (cred->princ) krb5_free_principal(context, cred->princ); xfree(cred); + krb5_free_context(context); /* minor_status set by acquire_accept_cred() */ return (ret); } @@ -340,6 +349,7 @@ if (cred->princ) krb5_free_principal(context, cred->princ); xfree(cred); + krb5_free_context(context); /* minor_status set by acquire_init_cred() */ return (ret); } @@ -355,6 +365,7 @@ (void) krb5_kt_close(context, cred->keytab); xfree(cred); *minor_status = code; + krb5_free_context(context); return (GSS_S_FAILURE); } @@ -377,6 +388,7 @@ krb5_free_principal(context, cred->princ); xfree(cred); *minor_status = code; + krb5_free_context(context); return (GSS_S_FAILURE); } @@ -405,6 +417,7 @@ if (cred->princ) krb5_free_principal(context, cred->princ); xfree(cred); + krb5_free_context(context); /* (*minor_status) set above */ return (ret); } @@ -423,12 +436,14 @@ if (cred->princ) krb5_free_principal(context, cred->princ); xfree(cred); + krb5_free_context(context); *minor_status = (OM_uint32) G_VALIDATE_FAILED; return (GSS_S_FAILURE); } + krb5_free_context(context); + /* return success */ - *minor_status = 0; *output_cred_handle = (gss_cred_id_t)cred; if (actual_mechs) @@ -436,6 +451,7 @@ return (GSS_S_COMPLETE); } +/*ARGSUSED*/ OM_uint32 gssspi_acquire_cred_with_password(ctx, minor_status, desired_name, password, time_req, desired_mechs, cred_usage, @@ -453,10 +469,8 @@ { OM_uint32 ret; - mutex_lock(&krb5_mutex); - ret = krb5_gss_acquire_cred_with_password_no_lock(ctx, minor_status, + ret = krb5_gss_acquire_cred_with_password(minor_status, desired_name, password, time_req, desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec); - mutex_unlock(&krb5_mutex); return (ret); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -13,7 +8,7 @@ * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -27,18 +22,18 @@ * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * */ /* * Copyright (C) 1998 by the FundsXpress, INC. - * + * * All rights reserved. - * + * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -49,15 +44,13 @@ * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#include -#include -#include +#include "gssapiP_krb5.h" #ifdef HAVE_STRING_H #include #else @@ -65,19 +58,16 @@ #endif /* - * $Id: add_cred.c,v 1.2.6.2 2000/05/03 20:00:26 raeburn Exp $ + * $Id: add_cred.c 18015 2006-05-17 05:26:12Z raeburn $ */ /* V2 interface */ -/*ARGSUSED*/ OM_uint32 -krb5_gss_add_cred(ct, minor_status, input_cred_handle, +krb5_gss_add_cred(minor_status, input_cred_handle, desired_name, desired_mech, cred_usage, initiator_time_req, acceptor_time_req, - output_cred_handle, actual_mechs, + output_cred_handle, actual_mechs, initiator_time_rec, acceptor_time_rec) - - void * ct; OM_uint32 *minor_status; gss_cred_id_t input_cred_handle; gss_name_t desired_name; @@ -90,13 +80,10 @@ OM_uint32 *initiator_time_rec; OM_uint32 *acceptor_time_rec; { - krb5_context context = ct; - OM_uint32 lifetime; + krb5_context context; + OM_uint32 major_status, lifetime; krb5_gss_cred_id_t cred; krb5_error_code code; - OM_uint32 major_status = GSS_S_FAILURE; - - *minor_status = 0; /* this is pretty simple, since there's not really any difference between the underlying mechanisms. The main hair is in copying @@ -104,8 +91,7 @@ /* check if the desired_mech is bogus */ - if (!g_OID_equal(desired_mech, gss_mech_krb5_v2) && - !g_OID_equal(desired_mech, gss_mech_krb5) && + if (!g_OID_equal(desired_mech, gss_mech_krb5) && !g_OID_equal(desired_mech, gss_mech_krb5_old)) { *minor_status = 0; return(GSS_S_BAD_MECH); @@ -129,22 +115,21 @@ return(GSS_S_DUPLICATE_ELEMENT); } - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context))) - return(GSS_S_FAILURE); -#endif + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } - mutex_lock(&krb5_mutex); - - /* verify the credential */ - if (GSS_ERROR(major_status = krb5_gss_validate_cred_no_lock(&context, - minor_status, input_cred_handle))) { - goto unlock; + major_status = krb5_gss_validate_cred_1(minor_status, input_cred_handle, + context); + if (GSS_ERROR(major_status)) { + krb5_free_context(context); + return major_status; } cred = (krb5_gss_cred_id_t) input_cred_handle; + k5_mutex_assert_locked(&cred->lock); /* check if the cred_usage is equal or "less" than the passed-in cred if copying */ @@ -152,9 +137,9 @@ if (!((cred->usage == cred_usage) || ((cred->usage == GSS_C_BOTH) && (output_cred_handle != NULL)))) { - *minor_status = (OM_uint32) G_BAD_USAGE; - major_status = GSS_S_FAILURE; - goto unlock; + *minor_status = (OM_uint32) G_BAD_USAGE; + krb5_free_context(context); + return(GSS_S_FAILURE); } /* check that desired_mech isn't already in the credential */ @@ -162,8 +147,13 @@ if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) || (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) { *minor_status = 0; - major_status = GSS_S_DUPLICATE_ELEMENT; - goto unlock; + krb5_free_context(context); + return(GSS_S_DUPLICATE_ELEMENT); + } + + if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) { + krb5_free_context(context); + return GSS_S_FAILURE; } /* verify the desired_name */ @@ -172,8 +162,8 @@ if ((desired_name != (gss_name_t) NULL) && (! kg_validate_name(desired_name))) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - major_status = (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); - goto unlock; + krb5_free_context(context); + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } /* make sure the desired_name is the same as the existing one */ @@ -182,8 +172,8 @@ !krb5_principal_compare(context, (krb5_principal) desired_name, cred->princ)) { *minor_status = 0; - major_status = GSS_S_BAD_NAME; - goto unlock; + krb5_free_context(context); + return(GSS_S_BAD_NAME); } /* copy the cred if necessary */ @@ -199,8 +189,8 @@ (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) == NULL) { *minor_status = ENOMEM; - major_status = GSS_S_FAILURE; - goto unlock; + krb5_free_context(context); + return(GSS_S_FAILURE); } memset(new_cred, 0, sizeof(krb5_gss_cred_id_rec)); @@ -209,48 +199,54 @@ new_cred->rfc_mech = cred->rfc_mech; new_cred->tgt_expire = cred->tgt_expire; - if (code = krb5_copy_principal(context, cred->princ, - &new_cred->princ)) { - free(new_cred); + if (cred->princ) + code = krb5_copy_principal(context, cred->princ, &new_cred->princ); + if (code) { + xfree(new_cred); *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + krb5_free_context(context); + return(GSS_S_FAILURE); } - + if (cred->keytab) { kttype = krb5_kt_get_type(context, cred->keytab); if ((strlen(kttype)+2) > sizeof(ktboth)) { - krb5_free_principal(context, new_cred->princ); - free(new_cred); + if (new_cred->princ) + krb5_free_principal(context, new_cred->princ); + xfree(new_cred); *minor_status = ENOMEM; - major_status = GSS_S_FAILURE; - goto unlock; + krb5_free_context(context); + return(GSS_S_FAILURE); } strncpy(ktboth, kttype, sizeof(ktboth) - 1); ktboth[sizeof(ktboth) - 1] = '\0'; strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth)); - code = krb5_kt_get_name(context, cred->keytab, - ktboth+strlen(ktboth), sizeof(ktboth)-strlen(ktboth)); + code = krb5_kt_get_name(context, cred->keytab, + ktboth+strlen(ktboth), + sizeof(ktboth)-strlen(ktboth)); if (code) { - krb5_free_principal(context, new_cred->princ); - free(new_cred); + if(new_cred->princ) + krb5_free_principal(context, new_cred->princ); + xfree(new_cred); *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + krb5_free_context(context); + return(GSS_S_FAILURE); } - if (code = krb5_kt_resolve(context, ktboth, &new_cred->keytab)) { + code = krb5_kt_resolve(context, ktboth, &new_cred->keytab); + if (code) { + if (new_cred->princ) krb5_free_principal(context, new_cred->princ); - free(new_cred); + xfree(new_cred); *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + krb5_free_context(context); + return(GSS_S_FAILURE); } } else { new_cred->keytab = NULL; @@ -263,12 +259,13 @@ &new_cred->rcache))) { if (new_cred->keytab) krb5_kt_close(context, new_cred->keytab); - krb5_free_principal(context, new_cred->princ); - free(new_cred); + if (new_cred->princ) + krb5_free_principal(context, new_cred->princ); + xfree(new_cred); + krb5_free_context(context); *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + return(GSS_S_FAILURE); } } else { new_cred->rcache = NULL; @@ -283,12 +280,13 @@ krb5_rc_close(context, new_cred->rcache); if (new_cred->keytab) krb5_kt_close(context, new_cred->keytab); + if (new_cred->princ) krb5_free_principal(context, new_cred->princ); - free(new_cred); + xfree(new_cred); + krb5_free_context(context); *minor_status = ENOMEM; - major_status = GSS_S_FAILURE; - goto unlock; + return(GSS_S_FAILURE); } strncpy(ccboth, cctype, sizeof(ccboth) - 1); @@ -296,17 +294,19 @@ strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth)); strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth)); - if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) { + code = krb5_cc_resolve(context, ccboth, &new_cred->ccache); + if (code) { if (new_cred->rcache) krb5_rc_close(context, new_cred->rcache); if (new_cred->keytab) krb5_kt_close(context, new_cred->keytab); - krb5_free_principal(context, new_cred->princ); - free(new_cred); + if (new_cred->princ) + krb5_free_principal(context, new_cred->princ); + xfree(new_cred); + krb5_free_context(context); *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + return(GSS_S_FAILURE); } } else { new_cred->ccache = NULL; @@ -321,12 +321,13 @@ krb5_rc_close(context, new_cred->rcache); if (new_cred->keytab) krb5_kt_close(context, new_cred->keytab); + if (new_cred->princ) krb5_free_principal(context, new_cred->princ); - free(new_cred); + xfree(new_cred); + krb5_free_context(context); *minor_status = (OM_uint32) G_VALIDATE_FAILED; - major_status = GSS_S_FAILURE; - goto unlock; + return(GSS_S_FAILURE); } /* modify new_cred */ @@ -343,18 +344,17 @@ /* set the outputs */ - major_status = krb5_gss_inquire_cred_no_lock(&context, minor_status, - (gss_cred_id_t)cred, - NULL, &lifetime, - NULL, actual_mechs); - - if (GSS_ERROR(major_status)) { + if (GSS_ERROR(major_status = krb5_gss_inquire_cred(minor_status, + (gss_cred_id_t) cred, + NULL, &lifetime, + NULL, actual_mechs))) { OM_uint32 dummy; if (output_cred_handle) - (void) krb5_gss_release_cred_no_lock(&context, &dummy, (gss_cred_id_t *) &cred); + (void) krb5_gss_release_cred(&dummy, (gss_cred_id_t *) &cred); + krb5_free_context(context); - goto unlock; + return(major_status); } if (initiator_time_rec) @@ -363,12 +363,9 @@ *acceptor_time_rec = lifetime; if (output_cred_handle) - *output_cred_handle = (gss_cred_id_t)cred; - - *minor_status = 0; - major_status = GSS_S_COMPLETE; + *output_cred_handle = (gss_cred_id_t) cred; -unlock: - mutex_unlock(&krb5_mutex); - return(major_status); + krb5_free_context(context); + *minor_status = 0; + return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/compare_name.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/compare_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/compare_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -28,45 +23,40 @@ */ /* - * $Id: compare_name.c,v 1.9 1996/07/22 20:33:38 marc Exp $ + * $Id: compare_name.c 18015 2006-05-17 05:26:12Z raeburn $ */ -#include +#include "gssapiP_krb5.h" OM_uint32 -krb5_gss_compare_name(ctx, minor_status, name1, name2, name_equal) - void *ctx; +krb5_gss_compare_name(minor_status, name1, name2, name_equal) OM_uint32 *minor_status; gss_name_t name1; gss_name_t name2; int *name_equal; -{ +{ krb5_context context; - mutex_lock(&krb5_mutex); - context = ctx; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context))) - return(GSS_S_FAILURE); -#endif + krb5_error_code code; if (! kg_validate_name(name1)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } if (! kg_validate_name(name2)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } + *minor_status = 0; *name_equal = krb5_principal_compare(context, (krb5_principal) name1, (krb5_principal) name2); - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/context_time.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/context_time.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/context_time.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,7 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" -/* - * Copyright 1993 by OpenVision Technologies, Inc. - * +/* Copyright 1993 by OpenVision Technologies, Inc. + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +11,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,38 +21,26 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: context_time.c,v 1.9 1996/07/22 20:33:41 marc Exp $ + * $Id: context_time.c 16187 2004-03-19 09:33:57Z raeburn $ */ OM_uint32 -krb5_gss_context_time(ct, minor_status, context_handle, time_rec) - void *ct; +krb5_gss_context_time(minor_status, context_handle, time_rec) OM_uint32 *minor_status; gss_ctx_id_t context_handle; OM_uint32 *time_rec; { - krb5_context context = ct; krb5_error_code code; krb5_gss_ctx_id_rec *ctx; krb5_timestamp now; krb5_deltat lifetime; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - /* validate the context handle */ if (! kg_validate_ctx_id(context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } @@ -66,25 +48,21 @@ if (! ctx->established) { *minor_status = KG_CTX_INCOMPLETE; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } - if (code = krb5_timeofday(context, &now)) { + if ((code = krb5_timeofday(ctx->k5_context, &now))) { *minor_status = code; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } if ((lifetime = ctx->endtime - now) <= 0) { *time_rec = 0; *minor_status = 0; - mutex_unlock(&krb5_mutex); return(GSS_S_CONTEXT_EXPIRED); } else { *time_rec = lifetime; *minor_status = 0; - mutex_unlock(&krb5_mutex); return(GSS_S_COMPLETE); } } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,75 +1,61 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" -/* - * /usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c - */ +#include "gssapiP_krb5.h" -#include - -GSS_DLLIMP OM_uint32 KRB5_CALLCONV -gss_krb5_copy_ccache(ctx, minor_status, cred_handle, out_ccache) - void *ctx; +OM_uint32 KRB5_CALLCONV +gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache) OM_uint32 *minor_status; gss_cred_id_t cred_handle; krb5_ccache out_ccache; { - OM_uint32 major_status; + OM_uint32 stat; krb5_gss_cred_id_t k5creds; krb5_cc_cursor cursor; krb5_creds creds; krb5_error_code code; - krb5_context context = ctx; - - mutex_lock(&krb5_mutex); - - *minor_status = 0; + krb5_context context; /* validate the cred handle */ - major_status = krb5_gss_validate_cred_no_lock(context, minor_status, - cred_handle); - if (major_status) - goto unlock; - + stat = krb5_gss_validate_cred(minor_status, cred_handle); + if (stat) + return(stat); + k5creds = (krb5_gss_cred_id_t) cred_handle; + code = k5_mutex_lock(&k5creds->lock); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } if (k5creds->usage == GSS_C_ACCEPT) { + k5_mutex_unlock(&k5creds->lock); *minor_status = (OM_uint32) G_BAD_USAGE; - major_status = GSS_S_FAILURE; - goto unlock; + return(GSS_S_FAILURE); } - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return (GSS_S_FAILURE); -#endif + code = krb5_gss_init_context(&context); + if (code) { + k5_mutex_unlock(&k5creds->lock); + *minor_status = code; + return GSS_S_FAILURE; + } code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor); if (code) { + k5_mutex_unlock(&k5creds->lock); *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + krb5_free_context(context); + return(GSS_S_FAILURE); } - while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, &creds)) + while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, &creds)) code = krb5_cc_store_cred(context, out_ccache, &creds); krb5_cc_end_seq_get(context, k5creds->ccache, &cursor); - + k5_mutex_unlock(&k5creds->lock); + krb5_free_context(context); if (code) { *minor_status = code; - major_status = GSS_S_FAILURE; - goto unlock; + return(GSS_S_FAILURE); } else { *minor_status = 0; - major_status = GSS_S_COMPLETE; - goto unlock; + return(GSS_S_COMPLETE); } - -unlock: - mutex_unlock(&krb5_mutex); - return(major_status); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -28,28 +23,28 @@ */ /* - * $Id: disp_com_err_status.c,v 1.5 1996/07/22 20:32:59 marc Exp $ + * $Id: disp_com_err_status.c 16391 2004-06-02 23:40:12Z raeburn $ */ -#include -#include +#include "gssapiP_generic.h" +#include "com_err.h" +#include "gss_libinit.h" -/* - * Solaris Kerberos does not dynamically load the error tables - */ -#if 0 -static int init_et = 0; -#endif +/* XXXX internationalization!! */ + +/**/ + static const char * const no_error = "No error"; -/* - * if status_type == GSS_C_GSS_CODE, return up to three error messages, - * for routine errors, call error, and status, in that order. - * message_context == 0 : print the routine error - * message_context == 1 : print the calling error - * message_context > 2 : print supplementary info bit (message_context-2) - * if status_type == GSS_C_MECH_CODE, return the output from error_message() - */ +/**/ + +/* if status_type == GSS_C_GSS_CODE, return up to three error messages, + for routine errors, call error, and status, in that order. + message_context == 0 : print the routine error + message_context == 1 : print the calling error + message_context > 2 : print supplementary info bit (message_context-2) + if status_type == GSS_C_MECH_CODE, return the output from error_message() + */ OM_uint32 g_display_com_err_status(minor_status, status_value, status_string) @@ -60,13 +55,7 @@ status_string->length = 0; status_string->value = NULL; -/* Solaris Kerberos does not dynamically load the error tables */ -#if 0 - if (!init_et) { - initialize_ggss_error_table(); - init_et = 1; - } -#endif + (void) gssint_initialize_library(); if (! g_make_string_buffer(((status_value == 0)?no_error: error_message(status_value)), diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/disp_major_status.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_major_status.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_major_status.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,5 @@ #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -21,19 +22,24 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_generic.h" #include #include /* - * $Id: disp_major_status.c,v 1.6 1996/07/22 20:33:01 marc Exp $ + * $Id: disp_major_status.c 13236 2001-05-08 17:10:18Z epeisach $ */ -#define GSS_CALLING_ERROR_FIELD(x) \ - (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK) +/* XXXX these are not part of the GSSAPI C bindings! (but should be) */ +/* SUNW15resync - MIT 1.5 has these in gssapi.h */ -#define GSS_ROUTINE_ERROR_FIELD(x) \ - (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK) +#define GSS_CALLING_ERROR_FIELD(x) \ + (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK) +#define GSS_ROUTINE_ERROR_FIELD(x) \ + (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK) +#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \ + (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK) + /* This code has knowledge of the min and max errors of each type within the gssapi major status */ @@ -114,16 +120,16 @@ /**/ -int display_unknown(kind, value, buffer) +static int +display_unknown(kind, value, buffer) const char *kind; OM_uint32 value; gss_buffer_t buffer; { - size_t len; char *str; - str = (char *) xmalloc(strlen(unknown_error)+strlen(kind)+7); - if (str == NULL) + if ((str = + (char *) xmalloc(strlen(unknown_error)+strlen(kind)+7)) == NULL) return(0); sprintf(str, unknown_error, kind, value); @@ -143,7 +149,7 @@ { const char *str; - if ((str = GSS_CALLING_ERROR_STR(code)) != NULL) { + if ((str = GSS_CALLING_ERROR_STR(code))) { if (! g_make_string_buffer(str, status_string)) { *minor_status = ENOMEM; return(GSS_S_FAILURE); @@ -168,7 +174,7 @@ { const char *str; - if ((str = GSS_ROUTINE_ERROR_STR(code)) != NULL) { + if ((str = GSS_ROUTINE_ERROR_STR(code))) { if (! g_make_string_buffer(str, status_string)) { *minor_status = ENOMEM; return(GSS_S_FAILURE); @@ -193,7 +199,7 @@ { const char *str; - if ((str = GSS_SINFO_STR(code)) != NULL) { + if ((str = GSS_SINFO_STR(code))) { if (! g_make_string_buffer(str, status_string)) { *minor_status = ENOMEM; return(GSS_S_FAILURE); @@ -242,7 +248,7 @@ /*** do routine error */ if (*message_context == 0) { - if ((tmp = GSS_ROUTINE_ERROR(status_value)) != 0) { + if ((tmp = GSS_ROUTINE_ERROR(status_value))) { status_value -= tmp; if ((ret = display_routine(minor_status, tmp, status_string))) return(ret); @@ -264,7 +270,7 @@ /*** do calling error */ if (*message_context == 1) { - if ((tmp = GSS_CALLING_ERROR(status_value)) != 0) { + if ((tmp = GSS_CALLING_ERROR(status_value))) { status_value -= tmp; if ((ret = display_calling(minor_status, tmp, status_string))) return(ret); @@ -285,7 +291,7 @@ /*** do sinfo bits (*message_context == 2 + number of bits done) */ - tmp = ((GSS_SUPPLEMENTARY_INFO(status_value)) >> GSS_C_SUPPLEMENTARY_OFFSET); + tmp = GSS_SUPPLEMENTARY_INFO_FIELD(status_value); /* mask off the bits which have been done */ if (*message_context > 2) { tmp &= ~LSBMASK(*message_context-3); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/disp_name.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,59 +22,55 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" OM_uint32 -krb5_gss_display_name(ctx, minor_status, input_name, output_name_buffer, +krb5_gss_display_name(minor_status, input_name, output_name_buffer, output_name_type) - void *ctx; OM_uint32 *minor_status; gss_name_t input_name; gss_buffer_t output_name_buffer; gss_OID *output_name_type; { - krb5_context context = ctx; + krb5_context context; krb5_error_code code; char *str; - mutex_lock(&krb5_mutex); - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } output_name_buffer->length = 0; output_name_buffer->value = NULL; if (! kg_validate_name(input_name)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } if ((code = krb5_unparse_name(context, (krb5_principal) input_name, &str))) { *minor_status = code; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_FAILURE); } if (! g_make_string_buffer(str, output_name_buffer)) { - xfree(str); + krb5_free_unparsed_name(context, str); + krb5_free_context(context); *minor_status = (OM_uint32) G_BUFFER_ALLOC; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } - xfree(str); + krb5_free_unparsed_name(context, str); + krb5_free_context(context); *minor_status = 0; if (output_name_type) *output_name_type = (gss_OID) gss_nt_krb5_name; - mutex_unlock(&krb5_mutex); return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,6 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +10,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,21 +20,19 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "gssapiP_krb5.h" +#include "gss_libinit.h" +#include "com_err.h" /* XXXX internationalization!! */ -/* Solaris Kerberos does not dynamically load the error tables */ -#if 0 -static int init_et = 0; -#endif +/**/ -/*ARGSUSED*/ OM_uint32 -krb5_gss_display_status(ctx, minor_status, status_value, status_type, +krb5_gss_display_status(minor_status, status_value, status_type, mech_type, message_context, status_string) - void *ctx; OM_uint32 *minor_status; OM_uint32 status_value; int status_type; @@ -49,57 +40,31 @@ OM_uint32 *message_context; gss_buffer_t status_string; { - OM_uint32 major_status = 0; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); status_string->length = 0; status_string->value = NULL; if ((mech_type != GSS_C_NULL_OID) && - !g_OID_equal(gss_mech_krb5_v2, mech_type) && !g_OID_equal(gss_mech_krb5, mech_type) && !g_OID_equal(gss_mech_krb5_old, mech_type)) { *minor_status = 0; - mutex_unlock(&krb5_mutex); return(GSS_S_BAD_MECH); } if (status_type == GSS_C_GSS_CODE) { - - major_status = g_display_major_status(minor_status, status_value, - message_context, status_string); - mutex_unlock(&krb5_mutex); - return(major_status); + return(g_display_major_status(minor_status, status_value, + message_context, status_string)); } else if (status_type == GSS_C_MECH_CODE) { - -/* Solaris Kerberos does not dynamically load the error tables */ -#if 0 - if (!init_et) { - initialize_k5g_error_table(); - init_et = 1; - } -#endif + (void) gssint_initialize_library(); if (*message_context) { *minor_status = (OM_uint32) G_BAD_MSG_CTX; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } - major_status = g_display_com_err_status(minor_status, status_value, - status_string); - mutex_unlock(&krb5_mutex); - return(major_status); + return(g_display_com_err_status(minor_status, status_value, + status_string)); } else { *minor_status = 0; - mutex_unlock(&krb5_mutex); return(GSS_S_BAD_STATUS); } } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/export_name.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/export_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,98 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * lib/gssapi/krb5/export_name.c + * + * Copyright 1997 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +#include "gssapiP_krb5.h" + +OM_uint32 krb5_gss_export_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_buffer_t exported_name) +{ + krb5_context context; + krb5_error_code code; + size_t length; + char *str, *cp; + + if (minor_status) + *minor_status = 0; + + code = krb5_gss_init_context(&context); + if (code) { + if (minor_status) + *minor_status = code; + return GSS_S_FAILURE; + } + + exported_name->length = 0; + exported_name->value = NULL; + + if (! kg_validate_name(input_name)) { + if (minor_status) + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + if ((code = krb5_unparse_name(context, (krb5_principal) input_name, + &str))) { + if (minor_status) + *minor_status = code; + krb5_free_context(context); + return(GSS_S_FAILURE); + } + + krb5_free_context(context); + length = strlen(str); + exported_name->length = 10 + length + gss_mech_krb5->length; + exported_name->value = malloc(exported_name->length); + if (!exported_name->value) { + free(str); + if (minor_status) + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + cp = exported_name->value; + + /* Note: we assume the OID will be less than 128 bytes... */ + *cp++ = 0x04; *cp++ = 0x01; + *cp++ = (gss_mech_krb5->length+2) >> 8; + *cp++ = (gss_mech_krb5->length+2) & 0xFF; + *cp++ = 0x06; + *cp++ = (gss_mech_krb5->length) & 0xFF; + memcpy(cp, gss_mech_krb5->elements, gss_mech_krb5->length); + cp += gss_mech_krb5->length; + *cp++ = length >> 24; + *cp++ = length >> 16; + *cp++ = length >> 8; + *cp++ = length & 0xFF; + memcpy(cp, str, length); + + free(str); + + return(GSS_S_COMPLETE); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -35,33 +30,21 @@ /* * export_sec_context.c - Externalize the security context. */ -#include -#include +#include "gssapiP_krb5.h" OM_uint32 -krb5_gss_export_sec_context(ct, minor_status, context_handle, interprocess_token) - void *ct; +krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token) OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_buffer_t interprocess_token; { - krb5_context context = ct; + krb5_context context; krb5_error_code kret; OM_uint32 retval; size_t bufsize, blen; krb5_gss_ctx_id_t ctx; krb5_octet *obuffer, *obp; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ct; - /* Assume a tragic failure */ obuffer = (krb5_octet *) NULL; retval = GSS_S_FAILURE; @@ -74,6 +57,14 @@ } ctx = (krb5_gss_ctx_id_t) *context_handle; + context = ctx->k5_context; + kret = krb5_gss_ser_init(context); + if (kret) + goto error_out; + + { gss_OID go = ctx->mech_used; + printf("export ctx len=%lu\n", go->length); + } /* Determine size needed for externalization of context */ bufsize = 0; @@ -101,20 +92,17 @@ retval = GSS_S_COMPLETE; /* Now, clean up the context state */ - /* Note, calling non-locking interface */ - (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, context_handle, NULL); + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); *context_handle = GSS_C_NO_CONTEXT; - mutex_unlock(&krb5_mutex); return (GSS_S_COMPLETE); error_out: if (obuffer && bufsize) { memset(obuffer, 0, bufsize); - krb5_xfree(obuffer); + xfree(obuffer); } - if (*minor_status == 0) + if (*minor_status == 0) *minor_status = (OM_uint32) kret; - mutex_unlock(&krb5_mutex); return(retval); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/get_tkt_flags.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/get_tkt_flags.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/get_tkt_flags.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,5 @@ #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -21,14 +22,14 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: get_tkt_flags.c,v 1.7.4.1 1996/11/21 02:19:40 marc Exp $ + * $Id: get_tkt_flags.c 18131 2006-06-14 22:27:54Z tlyu $ */ -OM_uint32 -gss_krb5_get_tkt_flags(minor_status, context_handle, ticket_flags) +OM_uint32 KRB5_CALLCONV +gss_krb5int_get_tkt_flags(minor_status, context_handle, ticket_flags) OM_uint32 *minor_status; gss_ctx_id_t context_handle; krb5_flags *ticket_flags; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,90 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include + +#include "gssapi_err_generic.h" +#include "gssapi_err_krb5.h" +#include "gssapiP_krb5.h" + +#include "gss_libinit.h" +#include "k5-platform.h" + +#include "mglueP.h" + +/* + * Initialize the GSSAPI library. + */ + +MAKE_INIT_FUNCTION(gssint_lib_init); +MAKE_FINI_FUNCTION(gssint_lib_fini); + +int gssint_lib_init(void) +{ + int err; + +#ifdef SHOW_INITFINI_FUNCS + printf("gssint_lib_init\n"); +#endif + +#if !USE_BUNDLE_ERROR_STRINGS + add_error_table(&et_k5g_error_table); + add_error_table(&et_ggss_error_table); +#endif +#if 0 /* SUNW15resync */ + err = gssint_mechglue_init(); + if (err) + return err; +#endif + err = k5_mutex_finish_init(&gssint_krb5_keytab_lock); + if (err) + return err; + err = k5_key_register(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, free); + if (err) + return err; + err = k5_key_register(K5_KEY_GSS_KRB5_CCACHE_NAME, free); + if (err) + return err; +#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */ + err = k5_mutex_finish_init(&kg_kdc_flag_mutex); + if (err) + return err; +#endif + return k5_mutex_finish_init(&kg_vdb.mutex); +} + +void gssint_lib_fini(void) +{ + if (!INITIALIZER_RAN(gssint_lib_init) || PROGRAM_EXITING()) { +#ifdef SHOW_INITFINI_FUNCS + printf("gssint_lib_fini: skipping\n"); +#endif + return; + } +#ifdef SHOW_INITFINI_FUNCS + printf("gssint_lib_fini\n"); +#endif +#if !USE_BUNDLE_ERROR_STRINGS + remove_error_table(&et_k5g_error_table); + remove_error_table(&et_ggss_error_table); +#endif + k5_key_delete(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME); + k5_key_delete(K5_KEY_GSS_KRB5_CCACHE_NAME); + k5_mutex_destroy(&kg_vdb.mutex); +#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */ + k5_mutex_destroy(&kg_kdc_flag_mutex); +#endif + k5_mutex_destroy(&gssint_krb5_keytab_lock); +#if 0 /* SUNW15resync */ + gssint_mechglue_fini(); +#endif +} + +OM_uint32 gssint_initialize_library (void) +{ + return CALL_INIT_FUNCTION(gssint_lib_init); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.h Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,11 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifndef GSSAPI_LIBINIT_H +#define GSSAPI_LIBINIT_H + +#include "gssapi.h" + +OM_uint32 gssint_initialize_library (void); +void gssint_cleanup_library (void); + +#endif /* GSSAPI_LIBINIT_H */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/import_name.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/import_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/import_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -28,14 +23,14 @@ */ /* - * $Id: import_name.c,v 1.17 1998/10/30 02:54:21 marc Exp $ + * $Id: import_name.c 18015 2006-05-17 05:26:12Z raeburn $ */ -#include -#include +#include "gssapiP_krb5.h" #ifndef NO_PASSWORD #include +#include #endif #ifdef HAVE_STRING_H @@ -52,9 +47,8 @@ */ OM_uint32 -krb5_gss_import_name(ctx, minor_status, input_name_buffer, +krb5_gss_import_name(minor_status, input_name_buffer, input_name_type, output_name) - void *ctx; OM_uint32 *minor_status; gss_buffer_t input_name_buffer; gss_OID input_name_type; @@ -69,15 +63,11 @@ struct passwd *pw; #endif - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ctx; + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } /* set up default returns */ @@ -86,21 +76,15 @@ /* Go find the appropriate string rep to pass into parse_name */ - /* We support both nametypes: new and official nametype - * GSS_C_NT_HOSTBASED_SERVICE and - * old and unofficial nametype gss_nt_service_name - */ - if ((input_name_type != GSS_C_NULL_OID) && - (g_OID_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) || - g_OID_equal(input_name_type, gss_nt_service_name) || + (g_OID_equal(input_name_type, gss_nt_service_name) || g_OID_equal(input_name_type, gss_nt_service_name_v2))) { char *service, *host; if ((tmp = (char *) xmalloc(input_name_buffer->length + 1)) == NULL) { *minor_status = ENOMEM; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_FAILURE); } @@ -108,7 +92,7 @@ tmp[input_name_buffer->length] = 0; service = tmp; - if (host = strchr(tmp, '@')) { + if ((host = strchr(tmp, '@'))) { *host = '\0'; host++; } @@ -123,7 +107,7 @@ if (input_name_buffer->length != sizeof(krb5_principal)) { *minor_status = (OM_uint32) G_WRONG_SIZE; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_BAD_NAME); } @@ -131,16 +115,22 @@ if ((code = krb5_copy_principal(context, input, &princ))) { *minor_status = code; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_FAILURE); } } else { +#ifndef NO_PASSWORD + uid_t uid; + struct passwd pwx; + char pwbuf[BUFSIZ]; +#endif + stringrep = NULL; if ((tmp = (char *) xmalloc(input_name_buffer->length + 1)) == NULL) { *minor_status = ENOMEM; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_FAILURE); } tmp2 = 0; @@ -150,19 +140,19 @@ if ((input_name_type == GSS_C_NULL_OID) || g_OID_equal(input_name_type, gss_nt_krb5_name) || - g_OID_equal(input_name_type, GSS_C_NT_USER_NAME)) { + g_OID_equal(input_name_type, gss_nt_user_name)) { stringrep = (char *) tmp; #ifndef NO_PASSWORD - } else if (g_OID_equal(input_name_type, GSS_C_NT_MACHINE_UID_NAME)) { - if ((pw = getpwuid(*((uid_t *) input_name_buffer->value)))) - stringrep = pw->pw_name; + } else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) { + uid = *(uid_t *) input_name_buffer->value; + do_getpwuid: + if (k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw) == 0) + stringrep = pw->pw_name; else *minor_status = (OM_uint32) G_NOUSER; - } else if (g_OID_equal(input_name_type, GSS_C_NT_STRING_UID_NAME)) { - if ((pw = getpwuid((uid_t) atoi(tmp)))) - stringrep = pw->pw_name; - else - *minor_status = (OM_uint32) G_NOUSER; + } else if (g_OID_equal(input_name_type, gss_nt_string_uid_name)) { + uid = atoi(tmp); + goto do_getpwuid; #endif } else if (g_OID_equal(input_name_type, gss_nt_exported_name)) { cp = tmp; @@ -191,15 +181,16 @@ if (tmp2 == NULL) { xfree(tmp); *minor_status = ENOMEM; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return GSS_S_FAILURE; } strncpy(tmp2, cp, length); tmp2[length] = 0; - + stringrep = tmp2; } else { - mutex_unlock(&krb5_mutex); + xfree(tmp); + krb5_free_context(context); return(GSS_S_BAD_NAMETYPE); } @@ -212,10 +203,10 @@ xfree(tmp); if (tmp2) xfree(tmp2); - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_BAD_NAME); } - + if (tmp2) xfree(tmp2); xfree(tmp); @@ -226,7 +217,7 @@ if (code) { *minor_status = (OM_uint32) code; - mutex_unlock(&krb5_mutex); + krb5_free_context(context); return(GSS_S_BAD_NAME); } @@ -234,14 +225,15 @@ if (! kg_save_name((gss_name_t) princ)) { krb5_free_principal(context, princ); + krb5_free_context(context); *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } + krb5_free_context(context); + /* return it */ *output_name = (gss_name_t) princ; - mutex_unlock(&krb5_mutex); return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -28,26 +23,22 @@ */ /* - * $Id: indicate_mechs.c,v 1.11 1999/03/26 03:51:43 tytso Exp $ + * $Id: indicate_mechs.c 18131 2006-06-14 22:27:54Z tlyu $ */ -#include +#include "gssapiP_krb5.h" +#include "mglueP.h" -/*ARGSUSED*/ OM_uint32 -krb5_gss_indicate_mechs(ctx, minor_status, mech_set) - void *ctx; +krb5_gss_indicate_mechs(minor_status, mech_set) OM_uint32 *minor_status; gss_OID_set *mech_set; { *minor_status = 0; - /* Solaris Kerberos: note that we use gss_copy_oid_set() here - * instead of g_copy_OID_set(). Ours is defined in oid_ops.c - */ - if (gss_copy_oid_set(minor_status, gss_mech_set_krb5_v1v2, - mech_set) == GSS_S_FAILURE) { + if (! gssint_copy_oid_set(minor_status, gss_mech_set_krb5_both, mech_set)) { *mech_set = GSS_C_NO_OID_SET; + *minor_status = ENOMEM; return(GSS_S_FAILURE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -6,14 +6,14 @@ #pragma ident "%Z%%M% %I% %E% SMI" /* - * Copyright 2000 by the Massachusetts Institute of Technology. + * Copyright 2000,2002, 2003 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -27,11 +27,11 @@ * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * */ /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -41,7 +41,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -53,14 +53,14 @@ /* * Copyright (C) 1998 by the FundsXpress, INC. - * + * * All rights reserved. - * + * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -71,33 +71,32 @@ * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#include -#include +#include "k5-int.h" +#include "gssapiP_krb5.h" +#include "gss_libinit.h" +#include "mglueP.h" +#ifdef HAVE_MEMORY_H #include +#endif #include -#include #include -#define ROOT_UID 0 -#define KRB5_DEFAULT_LIFE 60*60*10 -#define CACHE_FILENAME_LEN 35 + +/* Solaris Kerberos start */ +static OM_uint32 get_default_cred(OM_uint32 *, void *, gss_cred_id_t *); +/* Solaris Kerberos end */ /* - * $Id: init_sec_context.c,v 1.51.2.7 2000/06/28 02:48:22 tlyu Exp $ + * $Id: init_sec_context.c 18131 2006-06-14 22:27:54Z tlyu $ */ -extern int -safechown(const char *src, uid_t uid, gid_t gid, int mode); - -/* - * XXX This is for debugging only!!! Should become a real bitfield - * at some point - */ +/* XXX This is for debugging only!!! Should become a real bitfield + at some point */ int krb5_gss_dbg_client_expcreds = 0; /* @@ -116,8 +115,7 @@ krb5_error_code code; krb5_creds in_creds; - KRB5_LOG0(KRB5_INFO, "get_credentials() start\n"); - + k5_mutex_assert_locked(&cred->lock); memset((char *) &in_creds, 0, sizeof(krb5_creds)); if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client))) @@ -143,18 +141,14 @@ code = KRB5KRB_AP_ERR_TKT_EXPIRED; goto cleanup; } - + cleanup: if (in_creds.client) krb5_free_principal(context, in_creds.client); if (in_creds.server) krb5_free_principal(context, in_creds.server); - - KRB5_LOG(KRB5_INFO, "get_credentials() end, code = %d\n", code); - return code; } - struct gss_checksum_data { krb5_gss_ctx_id_rec *ctx; krb5_gss_cred_id_t cred; @@ -162,16 +156,19 @@ krb5_data checksum_data; }; +#ifdef CFX_EXERCISE +#include "../../krb5/krb/auth_con.h" +#endif static krb5_error_code KRB5_CALLCONV make_gss_checksum (krb5_context context, krb5_auth_context auth_context, - void *cksum_data, krb5_data **out) + void *cksum_data, krb5_data **out) { krb5_error_code code; krb5_int32 con_flags; unsigned char *ptr; struct gss_checksum_data *data = cksum_data; krb5_data credmsg; - int junk; + unsigned int junk; data->checksum_data.data = 0; credmsg.data = 0; @@ -183,19 +180,19 @@ /* clear the time check flag that was set in krb5_auth_con_init() */ krb5_auth_con_getflags(context, auth_context, &con_flags); krb5_auth_con_setflags(context, auth_context, - con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME); + con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME); code = krb5_fwd_tgt_creds(context, auth_context, 0, - data->cred->princ, data->ctx->there, - data->cred->ccache, 1, - &credmsg); + data->cred->princ, data->ctx->there, + data->cred->ccache, 1, + &credmsg); /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */ krb5_auth_con_setflags(context, auth_context, con_flags); if (code) { /* don't fail here; just don't accept/do the delegation - request */ + request */ data->ctx->gss_flags &= ~GSS_C_DELEG_FLAG; data->checksum_data.length = 24; @@ -203,22 +200,23 @@ if (credmsg.length+28 > KRB5_INT16_MAX) { krb5_free_data_contents(context, &credmsg); return(KRB5KRB_ERR_FIELD_TOOLONG); - } + } - data->checksum_data.length = 28+credmsg.length; + data->checksum_data.length = 28+credmsg.length; } } else { data->checksum_data.length = 24; } #ifdef CFX_EXERCISE - if (data->ctx->auth_context->keyblock->enctype == 18) { + if (data->ctx->auth_context->keyblock != NULL + && data->ctx->auth_context->keyblock->enctype == 18) { srand(time(0) ^ getpid()); /* Our ftp client code stupidly assumes a base64-encoded version of the token will fit in 10K, so don't make this too big. */ junk = rand() & 0xff; } else - junk = 0; + junk = 0; #else junk = 0; #endif @@ -226,16 +224,16 @@ data->checksum_data.length += junk; /* now allocate a buffer to hold the checksum data and - (maybe) KRB_CRED msg */ + (maybe) KRB_CRED msg */ if ((data->checksum_data.data = (char *) xmalloc(data->checksum_data.length)) == NULL) { if (credmsg.data) - krb5_free_data_contents(context, &credmsg); + krb5_free_data_contents(context, &credmsg); return(ENOMEM); } - ptr = (uchar_t *)data->checksum_data.data; + ptr = (uchar_t *)data->checksum_data.data; /* SUNW15resync */ TWRITE_INT(ptr, data->md5.length, 0); TWRITE_STR(ptr, (unsigned char *) data->md5.contents, data->md5.length); @@ -257,7 +255,7 @@ *out = &data->checksum_data; return 0; } - + static krb5_error_code make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token) krb5_context context; @@ -276,13 +274,11 @@ krb5_data *checksum_data = NULL; unsigned char *ptr; unsigned char *t; - int tlen; + unsigned int tlen; + k5_mutex_assert_locked(&cred->lock); ap_req.data = 0; - /* build the checksum buffer */ - KRB5_LOG0(KRB5_INFO, "make_ap_req_v1() start\n"); - /* compute the hash of the channel bindings */ if ((code = kg_checksum_channel_bindings(context, chan_bindings, &md5, 0))) @@ -290,7 +286,6 @@ krb5_auth_con_set_req_cksumtype(context, ctx->auth_context, CKSUMTYPE_KG_CB); - cksum_struct.md5 = md5; cksum_struct.ctx = ctx; cksum_struct.cred = cred; @@ -300,17 +295,18 @@ case ENCTYPE_DES_CBC_MD4: case ENCTYPE_DES_CBC_MD5: case ENCTYPE_DES3_CBC_SHA1: - code = make_gss_checksum(context, ctx->auth_context, &cksum_struct, - &checksum_data); - if (code) + code = make_gss_checksum(context, ctx->auth_context, &cksum_struct, + &checksum_data); + if (code) goto cleanup; - break; + break; default: krb5_auth_con_set_checksum_func(context, ctx->auth_context, - make_gss_checksum, &cksum_struct); - break; + make_gss_checksum, &cksum_struct); + break; } + /* call mk_req. subkey and ap_req need to be used or destroyed */ mk_req_flags = AP_OPTS_USE_SUBKEY; @@ -318,8 +314,10 @@ if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; - if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags, - checksum_data, k_cred, &ap_req))) + code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags, + checksum_data, k_cred, &ap_req); + krb5_free_data_contents(context, &cksum_struct.checksum_data); + if (code) goto cleanup; /* store the interesting stuff from creds and authent */ @@ -340,7 +338,7 @@ ptr = t; - g_make_token_header((gss_OID) mech_type, ap_req.length, + g_make_token_header(mech_type, ap_req.length, &ptr, KG_TOK_CTX_AP_REQ); TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length); @@ -351,23 +349,712 @@ token->value = (void *) t; code = 0; - -cleanup: - /* - * We only free cksum_struct.checksum_data here, because checksum_data - * could point to cksum_struct.checksum_data or NULL. - */ - if (cksum_struct.checksum_data.data) - krb5_free_data_contents(context, &cksum_struct.checksum_data); + + cleanup: + if (checksum_data && checksum_data->data) + krb5_free_data_contents(context, checksum_data); if (ap_req.data) - xfree(ap_req.data); - - KRB5_LOG(KRB5_INFO, "make_ap_req_v1() end, code = %d\n", code); + krb5_free_data_contents(context, &ap_req); return (code); } +/* + * setup_enc + * + * Fill in the encryption descriptors. Called after AP-REQ is made. + */ +static OM_uint32 +setup_enc( + OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + krb5_context context) +{ + krb5_error_code code; + OM_uint32 ret = GSS_S_COMPLETE; + int i; + krb5int_access kaccess; + + code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); + if (code) + goto fail; + + ctx->have_acceptor_subkey = 0; + ctx->proto = 0; + ctx->cksumtype = 0; + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = SGN_ALG_DES_MAC_MD5; + ctx->cksum_size = 8; + ctx->sealalg = SEAL_ALG_DES; + + /* The encryption key is the session key XOR + 0xf0f0f0f0f0f0f0f0. */ + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) + goto fail; + + for (i=0; ienc->length; i++) + ctx->enc->contents[i] ^= 0xf0; + + goto copy_subkey_to_seq; + + case ENCTYPE_DES3_CBC_SHA1: + /* MIT extension */ + ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; + ctx->cksum_size = 20; + ctx->sealalg = SEAL_ALG_DES3KD; + + copy_subkey: + code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc); + if (code) + goto fail; + copy_subkey_to_seq: + code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq); + if (code) { + krb5_free_keyblock (context, ctx->enc); + goto fail; + } + goto success; + + case ENCTYPE_ARCFOUR_HMAC: + /* Microsoft extension */ + ctx->signalg = SGN_ALG_HMAC_MD5 ; + ctx->cksum_size = 8; + ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ; + + goto copy_subkey; + + default: + /* Fill some fields we shouldn't be using on this path + with garbage. */ + ctx->signalg = -10; + ctx->sealalg = -10; + + ctx->proto = 1; + code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype, + &ctx->cksumtype); + if (code) + goto fail; + code = krb5_c_checksum_length(context, ctx->cksumtype, + &ctx->cksum_size); + if (code) + goto fail; + goto copy_subkey; + } + +fail: + /* SUNW15resync - (as in prev snv code) add if-code and success label fix */ + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } + +success: + return (ret); +} + +/* + * new_connection + * + * Do the grunt work of setting up a new context. + */ +static OM_uint32 +new_connection( + OM_uint32 *minor_status, + krb5_gss_cred_id_t cred, + gss_ctx_id_t *context_handle, + gss_name_t target_name, + gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + gss_channel_bindings_t input_chan_bindings, + gss_buffer_t input_token, + gss_OID *actual_mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + krb5_context context, + int default_mech) +{ + OM_uint32 major_status; + krb5_error_code code; + krb5_creds *k_cred; + krb5_gss_ctx_id_rec *ctx, *ctx_free; + krb5_timestamp now; + gss_buffer_desc token; + + k5_mutex_assert_locked(&cred->lock); + major_status = GSS_S_FAILURE; + token.length = 0; + token.value = NULL; + + /* make sure the cred is usable for init */ + + if ((cred->usage != GSS_C_INITIATE) && + (cred->usage != GSS_C_BOTH)) { + *minor_status = 0; + return(GSS_S_NO_CRED); + } + + /* complain if the input token is non-null */ + + if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + /* create the ctx */ + + if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) + == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + /* fill in the ctx */ + memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); + ctx_free = ctx; + if ((code = krb5_auth_con_init(context, &ctx->auth_context))) + goto fail; + krb5_auth_con_setflags(context, ctx->auth_context, + KRB5_AUTH_CONTEXT_DO_SEQUENCE); + + /* limit the encryption types negotiated (if requested) */ + if (cred->req_enctypes) { + if ((code = krb5_set_default_tgs_enctypes(context, + cred->req_enctypes))) { + goto fail; + } + } + + ctx->initiate = 1; + ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | + GSS_C_TRANS_FLAG | + ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | + GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))); + ctx->seed_init = 0; + ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ + ctx->seqstate = 0; + + if ((code = krb5_timeofday(context, &now))) + goto fail; + + if (time_req == 0 || time_req == GSS_C_INDEFINITE) { + ctx->endtime = 0; + } else { + ctx->endtime = now + time_req; + } + + if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) + goto fail; + + if ((code = krb5_copy_principal(context, (krb5_principal) target_name, + &ctx->there))) + goto fail; + + code = get_credentials(context, cred, ctx->there, now, + ctx->endtime, &k_cred); + if (code) + goto fail; + + if (default_mech) { + mech_type = (gss_OID) gss_mech_krb5; + } + + if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used) + != GSS_S_COMPLETE) { + code = *minor_status; + goto fail; + } + /* + * Now try to make it static if at all possible.... + */ + ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used); + + { + /* gsskrb5 v1 */ + krb5_ui_4 seq_temp; + if ((code = make_ap_req_v1(context, ctx, + cred, k_cred, input_chan_bindings, + mech_type, &token))) { + if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || + (code == KG_EMPTY_CCACHE)) + major_status = GSS_S_NO_CRED; + if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) + major_status = GSS_S_CREDENTIALS_EXPIRED; + goto fail; + } + + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, + (krb5_int32 *)&seq_temp); /* SUNW15resync */ + ctx->seq_send = seq_temp; + krb5_auth_con_getsendsubkey(context, ctx->auth_context, + &ctx->subkey); + } + + major_status = setup_enc(minor_status, ctx, context); + + if (k_cred) { + krb5_free_creds(context, k_cred); + k_cred = 0; + } + + /* at this point, the context is constructed and valid, + hence, releaseable */ + + /* intern the context handle */ + + if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { + code = G_VALIDATE_FAILED; + goto fail; + } + *context_handle = (gss_ctx_id_t) ctx; + ctx_free = 0; + + /* compute time_rec */ + if (time_rec) { + if ((code = krb5_timeofday(context, &now))) + goto fail; + *time_rec = ctx->endtime - now; + } + + /* set the other returns */ + *output_token = token; + + if (ret_flags) + *ret_flags = ctx->gss_flags; + + if (actual_mech_type) + *actual_mech_type = mech_type; + + /* return successfully */ + + *minor_status = 0; + if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) { + ctx->established = 0; + return(GSS_S_CONTINUE_NEEDED); + } else { + ctx->seq_recv = ctx->seq_send; + g_order_init(&(ctx->seqstate), ctx->seq_recv, + (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, + (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto); + ctx->gss_flags |= GSS_C_PROT_READY_FLAG; + ctx->established = 1; + return(GSS_S_COMPLETE); + } + +fail: + if (ctx_free) { + if (ctx_free->auth_context) + krb5_auth_con_free(context, ctx_free->auth_context); + if (ctx_free->here) + krb5_free_principal(context, ctx_free->here); + if (ctx_free->there) + krb5_free_principal(context, ctx_free->there); + if (ctx_free->subkey) + krb5_free_keyblock(context, ctx_free->subkey); + xfree(ctx_free); + } else + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + + *minor_status = code; + return (major_status); +} + +/* + * mutual_auth + * + * Handle the reply from the acceptor, if we're doing mutual auth. + */ +static OM_uint32 +mutual_auth( + OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_name_t target_name, + gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + gss_channel_bindings_t input_chan_bindings, + gss_buffer_t input_token, + gss_OID *actual_mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + krb5_context context) +{ + OM_uint32 major_status; + unsigned char *ptr; + char *sptr; + krb5_data ap_rep; + krb5_ap_rep_enc_part *ap_rep_data; + krb5_timestamp now; + krb5_gss_ctx_id_rec *ctx; + krb5_error *krb_error; + krb5_error_code code; + krb5int_access kaccess; + + major_status = GSS_S_FAILURE; + + code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); + if (code) + goto fail; + + /* validate the context handle */ + /*SUPPRESS 29*/ + if (! kg_validate_ctx_id(*context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } + + ctx = (krb5_gss_ctx_id_rec *)*context_handle; /* SUNW15resync */ + + /* make sure the context is non-established, and that certain + arguments are unchanged */ + + if ((ctx->established) || + ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) { + code = KG_CONTEXT_ESTABLISHED; + goto fail; + } + + if (! krb5_principal_compare(context, ctx->there, + (krb5_principal) target_name)) { + (void)krb5_gss_delete_sec_context(minor_status, + context_handle, NULL); + code = 0; + major_status = GSS_S_BAD_NAME; + goto fail; + } + + /* verify the token and leave the AP_REP message in ap_rep */ + + if (input_token == GSS_C_NO_BUFFER) { + (void)krb5_gss_delete_sec_context(minor_status, + context_handle, NULL); + code = 0; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + + ptr = (unsigned char *) input_token->value; + + if (g_verify_token_header(ctx->mech_used, + &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length, 1)) { + if (g_verify_token_header((gss_OID) ctx->mech_used, + &(ap_rep.length), + &ptr, KG_TOK_CTX_ERROR, + input_token->length, 1) == 0) { + + /* Handle a KRB_ERROR message from the server */ + + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + + code = krb5_rd_error(context, &ap_rep, &krb_error); + if (code) + goto fail; + if (krb_error->error) + code = krb_error->error + ERROR_TABLE_BASE_krb5; + else + code = 0; + krb5_free_error(context, krb_error); + goto fail; + } else { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + } + + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + + /* decode the ap_rep */ + if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, + &ap_rep_data))) { + /* + * XXX A hack for backwards compatiblity. + * To be removed in 1999 -- proven + */ + krb5_auth_con_setuseruserkey(context, ctx->auth_context, + ctx->subkey); + if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, + &ap_rep_data))) + goto fail; + } + + /* store away the sequence number */ + ctx->seq_recv = ap_rep_data->seq_number; + g_order_init(&(ctx->seqstate), ctx->seq_recv, + (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, + (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto); + + if (ctx->proto == 1 && ap_rep_data->subkey) { + /* Keep acceptor's subkey. */ + ctx->have_acceptor_subkey = 1; + code = krb5_copy_keyblock(context, ap_rep_data->subkey, + &ctx->acceptor_subkey); + if (code) + goto fail; + code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, + ctx->acceptor_subkey->enctype, + &ctx->acceptor_subkey_cksumtype); + if (code) + goto fail; + } + + /* free the ap_rep_data */ + krb5_free_ap_rep_enc_part(context, ap_rep_data); + + /* set established */ + ctx->established = 1; + + /* set returns */ + + if (time_rec) { + if ((code = krb5_timeofday(context, &now))) + goto fail; + *time_rec = ctx->endtime - now; + } + + if (ret_flags) + *ret_flags = ctx->gss_flags; + + if (actual_mech_type) + *actual_mech_type = mech_type; + + /* success */ + + *minor_status = 0; + return GSS_S_COMPLETE; + +fail: + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + + *minor_status = code; + return (major_status); +} + +OM_uint32 +krb5_gss_init_sec_context(minor_status, claimant_cred_handle, + context_handle, target_name, mech_type, + req_flags, time_req, input_chan_bindings, + input_token, actual_mech_type, output_token, + ret_flags, time_rec) + OM_uint32 *minor_status; + gss_cred_id_t claimant_cred_handle; + gss_ctx_id_t *context_handle; + gss_name_t target_name; + gss_OID mech_type; + OM_uint32 req_flags; + OM_uint32 time_req; + gss_channel_bindings_t input_chan_bindings; + gss_buffer_t input_token; + gss_OID *actual_mech_type; + gss_buffer_t output_token; + OM_uint32 *ret_flags; + OM_uint32 *time_rec; +{ + krb5_context context; + krb5_gss_cred_id_t cred; + int err; + krb5_error_code kerr; + int default_mech = 0; + OM_uint32 major_status; + OM_uint32 tmp_min_stat; + + if (*context_handle == GSS_C_NO_CONTEXT) { + kerr = krb5_gss_init_context(&context); + if (kerr) { + *minor_status = kerr; + return GSS_S_FAILURE; + } + if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) + return GSS_S_FAILURE; + } else { + context = ((krb5_gss_ctx_id_rec *)*context_handle)->k5_context; + } + + /* set up return values so they can be "freed" successfully */ + + major_status = GSS_S_FAILURE; /* Default major code */ + output_token->length = 0; + output_token->value = NULL; + if (actual_mech_type) + *actual_mech_type = NULL; + + /* verify that the target_name is valid and usable */ + + if (! kg_validate_name(target_name)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + /* verify the credential, or use the default */ + /*SUPPRESS 29*/ + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { + /* + * Solaris Kerberos: here we are using the Solaris specific + * function get_default_cred() to handle the special case of a + * root principal + */ + major_status = get_default_cred(minor_status, context, + (gss_cred_id_t *)&cred); + if (major_status && GSS_ERROR(major_status)) { + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + return(major_status); + } + } else { + major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle); + if (GSS_ERROR(major_status)) { + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + return(major_status); + } + cred = (krb5_gss_cred_id_t) claimant_cred_handle; + } + kerr = k5_mutex_lock(&cred->lock); + if (kerr) { + krb5_free_context(context); + *minor_status = kerr; + return GSS_S_FAILURE; + } + + /* verify the mech_type */ + + err = 0; + if (mech_type == GSS_C_NULL_OID) { + default_mech = 1; + if (cred->rfc_mech) { + mech_type = (gss_OID) gss_mech_krb5; + } else if (cred->prerfc_mech) { + mech_type = (gss_OID) gss_mech_krb5_old; + } else { + err = 1; + } + } else if (g_OID_equal(mech_type, gss_mech_krb5)) { + if (!cred->rfc_mech) + err = 1; + } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) { + if (!cred->prerfc_mech) + err = 1; + } else if (g_OID_equal(mech_type, gss_mech_krb5_wrong)) { + if (!cred->rfc_mech) + err = 1; + } else { + err = 1; + } + + if (err) { + k5_mutex_unlock(&cred->lock); + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) + krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred); + *minor_status = 0; + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + return(GSS_S_BAD_MECH); + } + + /* is this a new connection or not? */ + + /*SUPPRESS 29*/ + if (*context_handle == GSS_C_NO_CONTEXT) { + major_status = new_connection(minor_status, cred, context_handle, + target_name, mech_type, req_flags, + time_req, input_chan_bindings, + input_token, actual_mech_type, + output_token, ret_flags, time_rec, + context, default_mech); + k5_mutex_unlock(&cred->lock); + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + else + ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context; + } else { + /* mutual_auth doesn't care about the credentials */ + k5_mutex_unlock(&cred->lock); + major_status = mutual_auth(minor_status, context_handle, + target_name, mech_type, req_flags, + time_req, input_chan_bindings, + input_token, actual_mech_type, + output_token, ret_flags, time_rec, + context); + /* If context_handle is now NO_CONTEXT, mutual_auth called + delete_sec_context, which would've zapped the krb5 context + too. */ + } + + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) + krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred); + + return(major_status); +} + +#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */ +k5_mutex_t kg_kdc_flag_mutex = K5_MUTEX_PARTIAL_INITIALIZER; +static int kdc_flag = 0; +#endif + +krb5_error_code +krb5_gss_init_context (krb5_context *ctxp) +{ + krb5_error_code err; + int is_kdc; + + err = gssint_initialize_library(); + if (err) + return err; +#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */ + err = k5_mutex_lock(&kg_kdc_flag_mutex); + if (err) + return err; + is_kdc = kdc_flag; + k5_mutex_unlock(&kg_kdc_flag_mutex); + + if (is_kdc) + return krb5int_init_context_kdc(ctxp); + else + return krb5_init_context(ctxp); +#endif + return krb5_init_context(ctxp); + +} + +#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */ +krb5_error_code +krb5_gss_use_kdc_context() +{ + krb5_error_code err; + + err = gssint_initialize_library(); + if (err) + return err; + err = k5_mutex_lock(&kg_kdc_flag_mutex); + if (err) + return err; + kdc_flag = 1; + k5_mutex_unlock(&kg_kdc_flag_mutex); + return 0; +} +#endif + +/* Solaris Kerberos specific routines start */ + +#define ROOT_UID 0 +#define KRB5_DEFAULT_LIFE 60*60*10 +#define CACHE_FILENAME_LEN 35 + +extern int +safechown(const char *src, uid_t uid, gid_t gid, int mode); static krb5_boolean principal_ignore_inst_compare(context, princ1, princ2) @@ -709,7 +1396,6 @@ *minor_status = code; return (GSS_S_FAILURE); } - /* * Solaris Kerberos: * If the client's realm is empty (using a fallback method to determine @@ -774,6 +1460,11 @@ return (GSS_S_FAILURE); } + /* + * Evidently (sigh), on success, krb5_get_init_creds_keytab + * changes the my_creds princ ptrs so we need to free those + * princs (me&server) as well as freeing all of my_creds contents. + */ code = krb5_get_init_creds_keytab(context, &my_creds, me, keytab, 0, svcname, &opt); @@ -788,16 +1479,23 @@ return (GSS_S_FAILURE); } + + krb5_free_principal(context, server); + server = NULL; + code = krb5_cc_resolve (context, krb5_cc_default_name(context), &ccache); if (code != 0) { *minor_status = code; krb5_free_cred_contents(context, &my_creds); + krb5_free_principal(context, me); return (GSS_S_FAILURE); } code = krb5_cc_initialize (context, ccache, me); + krb5_free_principal(context, me); + me = NULL; if (code != 0) { *minor_status = code; krb5_free_cred_contents(context, &my_creds); @@ -981,13 +1679,13 @@ /* If we can't get the time, assume the worst. */ if (krb5_timeofday(context, &now)) { - (void) krb5_gss_release_cred_no_lock(ct, &mntmp, cred_handle); + (void) krb5_gss_release_cred(&mntmp, cred_handle); return (GSS_S_CREDENTIALS_EXPIRED); } /* If root's cred has expired re-get it */ if (cred->tgt_expire < now + MIN_REFRESH_TIME && uid == ROOT_UID) { - (void) krb5_gss_release_cred_no_lock(ct, &mntmp, cred_handle); + (void) krb5_gss_release_cred(&mntmp, cred_handle); major = load_root_cred_using_keytab(minor_status, context, "root", 1); @@ -1010,7 +1708,7 @@ /* Any body else is SOL unless we can renew their credential cache */ } else if ((cred->tgt_expire < now + MIN_RENEW_TIME) && (cred->tgt_expire > now)) { - (void) krb5_gss_release_cred_no_lock(ct, &mntmp, cred_handle); + (void) krb5_gss_release_cred(&mntmp, cred_handle); major = renew_ccache(minor_status, context, uid); if ((major != GSS_S_COMPLETE) && @@ -1030,617 +1728,4 @@ return (GSS_S_COMPLETE); } -/* - * setup_enc - * - * Fill in the encryption descriptors. Called after AP-REQ is made. - */ -static OM_uint32 -setup_enc( - OM_uint32 *minor_status, - krb5_gss_ctx_id_rec *ctx, - krb5_context context) -{ - krb5_error_code code; - OM_uint32 ret = GSS_S_COMPLETE; - int i; - - ctx->have_acceptor_subkey = 0; - ctx->proto = 0; - ctx->cksumtype = 0; - - KRB5_LOG(KRB5_ERR, "setup_enc() enctype = %d\n", - ctx->subkey->enctype); - - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_CRC: - ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = SGN_ALG_DES_MAC_MD5; - ctx->cksum_size = 8; - ctx->sealalg = SEAL_ALG_DES; - - /* The encryption key is the session key XOR - 0xf0f0f0f0f0f0f0f0. */ - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) - goto fail; - - for (i=0; ienc->length; i++) - ctx->enc->contents[i] ^= 0xf0; - - goto copy_subkey_to_seq; - - case ENCTYPE_DES3_CBC_SHA1: - /* MIT extension */ - ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; - ctx->cksum_size = 20; - ctx->sealalg = SEAL_ALG_DES3KD; - - copy_subkey: - code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc); - if (code) - goto fail; - copy_subkey_to_seq: - code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq); - if (code) { - krb5_free_keyblock (context, ctx->enc); - goto fail; - } - break; - - case ENCTYPE_ARCFOUR_HMAC: - /* Microsoft extension */ - ctx->signalg = SGN_ALG_HMAC_MD5 ; - ctx->cksum_size = 8; - ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ; - - goto copy_subkey; - - default: - /* Fill some fields we shouldn't be using on this path - with garbage. */ - ctx->signalg = -10; - ctx->sealalg = -10; - - ctx->proto = 1; - code = krb5int_c_mandatory_cksumtype(context, ctx->subkey->enctype, - &ctx->cksumtype); - if (code) - goto fail; - code = krb5_c_checksum_length(context, ctx->cksumtype, - (size_t *)&ctx->cksum_size); - if (code) - goto fail; - goto copy_subkey; - } -fail: - if (code) { - *minor_status = code; - ret = GSS_S_FAILURE; - } -success: - return (ret); -} - -/* - * new_connection - * - * Do the grunt work of setting up a new context. - */ -static OM_uint32 -new_connection( - OM_uint32 *minor_status, - krb5_gss_cred_id_t cred, - gss_ctx_id_t *context_handle, - gss_name_t target_name, - gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec, - krb5_context context, - int default_mech) -{ - OM_uint32 major_status; - krb5_error_code code; - krb5_creds *k_cred; - krb5_gss_ctx_id_rec *ctx, *ctx_free; - krb5_timestamp now; - gss_buffer_desc token; - - major_status = GSS_S_FAILURE; - token.length = 0; - token.value = NULL; - - /* make sure the cred is usable for init */ - - if ((cred->usage != GSS_C_INITIATE) && - (cred->usage != GSS_C_BOTH)) { - *minor_status = 0; - return(GSS_S_NO_CRED); - } - - /* complain if the input token is non-null */ - - if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) { - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); - } - - /* create the ctx */ - - if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) - == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - - /* fill in the ctx */ - memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); - ctx_free = ctx; - if ((code = krb5_auth_con_init(context, &ctx->auth_context))) - goto fail; - krb5_auth_con_setflags(context, ctx->auth_context, - KRB5_AUTH_CONTEXT_DO_SEQUENCE); - ctx->initiate = 1; - ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | - GSS_C_TRANS_FLAG | GSS_C_PROT_READY_FLAG | - ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | - GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))); - ctx->seed_init = 0; - ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ - ctx->seqstate = 0; - if ((code = krb5_timeofday(context, &now))) - goto fail; - - if (time_req == 0 || time_req == GSS_C_INDEFINITE) { - ctx->endtime = 0; - } else { - ctx->endtime = now + time_req; - } - - if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) - goto fail; - - if ((code = krb5_copy_principal(context, (krb5_principal) target_name, - &ctx->there))) - goto fail; - - code = get_credentials(context, cred, ctx->there, now, - ctx->endtime, &k_cred); - if (code) - goto fail; - - if (default_mech) { - mech_type = (gss_OID) gss_mech_krb5; - } - /* Solaris Kerberos: we allocate the memory for mech_used here - * because we store mech_used as a gss_OID and not a (gss_OID *) - */ - ctx->mech_used.elements = malloc(mech_type->length); - if ( (ctx->mech_used.elements) == NULL ) { - code = ENOMEM; - major_status = GSS_S_FAILURE; - goto fail; - } - ctx->mech_used.length = mech_type->length; - memcpy(ctx->mech_used.elements, mech_type->elements, mech_type->length); - - /* - * Now try to make it static if at all possible.... - */ - /* Solaris Kerberos: our mech_used is part of the ctx structure */ - /* ctx->mech_used = krb5_gss_convert_static_mech_oid(&(ctx->mech_used)); */ - { - /* gsskrb5 v1 */ - krb5_ui_4 seq_temp; - if ((code = make_ap_req_v1(context, ctx, - cred, k_cred, input_chan_bindings, - mech_type, &token))) { - if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || - (code == KG_EMPTY_CCACHE)) - major_status = GSS_S_NO_CRED; - if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) - major_status = GSS_S_CREDENTIALS_EXPIRED; - goto fail; - } - - krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, - (krb5_int32 *)&seq_temp); - ctx->seq_send = seq_temp; - krb5_auth_con_getsendsubkey(context, ctx->auth_context, - &ctx->subkey); - } - - major_status = setup_enc(minor_status, ctx, context); - - if (k_cred) { - krb5_free_creds(context, k_cred); - k_cred = 0; - } - - /* at this point, the context is constructed and valid, - hence, releaseable */ - - /* intern the context handle */ - - if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { - code = G_VALIDATE_FAILED; - goto fail; - } - *context_handle = (gss_ctx_id_t) ctx; - ctx_free = 0; - /* compute time_rec */ - if (time_rec) { - if ((code = krb5_timeofday(context, &now))) - goto fail; - *time_rec = ctx->endtime - now; - } - - /* set the other returns */ - *output_token = token; - - if (ret_flags) - *ret_flags = ctx->gss_flags; - - if (actual_mech_type) - *actual_mech_type = mech_type; - - /* return successfully */ - - *minor_status = 0; - if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) { - ctx->established = 0; - return(GSS_S_CONTINUE_NEEDED); - } else { - ctx->seq_recv = ctx->seq_send; - g_order_init(&(ctx->seqstate), ctx->seq_recv, - (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, - (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto); - ctx->gss_flags |= GSS_C_PROT_READY_FLAG; - ctx->established = 1; - return(GSS_S_COMPLETE); - } - -fail: - if (ctx_free) { - if (ctx_free->auth_context) - krb5_auth_con_free(context, ctx_free->auth_context); - if (ctx_free->here) - krb5_free_principal(context, ctx_free->here); - if (ctx_free->there) - krb5_free_principal(context, ctx_free->there); - if (ctx_free->subkey) - krb5_free_keyblock(context, ctx_free->subkey); - xfree(ctx_free); - } else { - (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, - context_handle, NULL); - } - - *minor_status = code; - return (major_status); -} - -/* - * mutual_auth - * - * Handle the reply from the acceptor, if we're doing mutual auth. - */ -static OM_uint32 -mutual_auth( - OM_uint32 *minor_status, - krb5_gss_cred_id_t cred, - gss_ctx_id_t *context_handle, - gss_name_t target_name, - gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec, - krb5_context context) -{ - OM_uint32 major_status; - unsigned char *ptr; - char *sptr; - krb5_data ap_rep; - krb5_ap_rep_enc_part *ap_rep_data; - krb5_timestamp now; - krb5_gss_ctx_id_rec *ctx; - krb5_error *krb_error; - krb5_error_code code; - - major_status = GSS_S_FAILURE; - - /* validate the context handle */ - /*SUPPRESS 29*/ - if (! kg_validate_ctx_id(*context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) *context_handle; - - /* make sure the context is non-established, and that certain - arguments are unchanged */ - - if ((ctx->established) || - ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) { - code = KG_CONTEXT_ESTABLISHED; - goto fail; - } - - if (! krb5_principal_compare(context, ctx->there, - (krb5_principal) target_name)) { - (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, - context_handle, NULL); - code = 0; - major_status = GSS_S_BAD_NAME; - goto fail; - } - - /* verify the token and leave the AP_REP message in ap_rep */ - - if (input_token == GSS_C_NO_BUFFER) { - (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, - context_handle, NULL); - code = 0; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } - - ptr = (unsigned char *) input_token->value; - - if (g_verify_token_header(&ctx->mech_used, - (uint32_t *)&(ap_rep.length), - &ptr, KG_TOK_CTX_AP_REP, - input_token->length, 1)) { - if (g_verify_token_header(&ctx->mech_used, - (uint32_t *)&(ap_rep.length), - &ptr, KG_TOK_CTX_ERROR, - input_token->length, 1) == 0) { - - /* Handle a KRB_ERROR message from the server */ - - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); - - code = krb5_rd_error(context, &ap_rep, &krb_error); - if (code) - goto fail; - if (krb_error->error) - code = krb_error->error + ERROR_TABLE_BASE_krb5; - else - code = 0; - krb5_free_error(context, krb_error); - goto fail; - } else { - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); - } - } - - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); - - /* decode the ap_rep */ - if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, - &ap_rep_data))) { - /* - * XXX A hack for backwards compatiblity. - * To be removed in 1999 -- proven - */ - krb5_auth_con_setuseruserkey(context, ctx->auth_context, - ctx->subkey); - if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, - &ap_rep_data))) - goto fail; - } - - /* store away the sequence number */ - ctx->seq_recv = ap_rep_data->seq_number; - g_order_init(&(ctx->seqstate), ctx->seq_recv, - (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, - (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto); - - if (ctx->proto == 1 && ap_rep_data->subkey) { - /* Keep acceptor's subkey. */ - ctx->have_acceptor_subkey = 1; - code = krb5_copy_keyblock(context, ap_rep_data->subkey, - &ctx->acceptor_subkey); - if (code) - goto fail; - code = krb5int_c_mandatory_cksumtype(context, - ctx->acceptor_subkey->enctype, - &ctx->acceptor_subkey_cksumtype); - if (code) - goto fail; - } - - /* free the ap_rep_data */ - krb5_free_ap_rep_enc_part(context, ap_rep_data); - - /* set established */ - ctx->established = 1; - - /* set returns */ - - if (time_rec) { - if ((code = krb5_timeofday(context, &now))) - goto fail; - *time_rec = ctx->endtime - now; - } - if (ret_flags) - *ret_flags = ctx->gss_flags; - - if (actual_mech_type) - *actual_mech_type = mech_type; - - /* success */ - - *minor_status = 0; - return GSS_S_COMPLETE; - -fail: - (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, - context_handle, NULL); - - *minor_status = code; - return (major_status); -} - -/* - * krb5_gss_init_sec_context - * This has been broken up into smaller chunks for CFX support. - * MIT KRB5 1.3.2 - */ -OM_uint32 -krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle, - context_handle, target_name, mech_type, - req_flags, time_req, input_chan_bindings, - input_token, actual_mech_type, output_token, - ret_flags, time_rec) - void *ct; - OM_uint32 *minor_status; - gss_cred_id_t claimant_cred_handle; - gss_ctx_id_t *context_handle; - gss_name_t target_name; - gss_OID mech_type; - OM_uint32 req_flags; - OM_uint32 time_req; - gss_channel_bindings_t input_chan_bindings; - gss_buffer_t input_token; - gss_OID *actual_mech_type; - gss_buffer_t output_token; - OM_uint32 *ret_flags; - OM_uint32 *time_rec; -{ - krb5_context context; - krb5_gss_cred_id_t cred = NULL; - int err; - int default_mech = 0; - OM_uint32 major_status; - OM_uint32 tmp_min_stat; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - KRB5_LOG0(KRB5_INFO, "krb5_gss_init_sec_context() start\n"); - - mutex_lock(&krb5_mutex); - context = ct; - - /* set up return values so they can be "freed" successfully */ - - major_status = GSS_S_FAILURE; /* Default major code */ - output_token->length = 0; - output_token->value = NULL; - if (actual_mech_type) - *actual_mech_type = NULL; - - /* verify that the target_name is valid and usable */ - - if (! kg_validate_name(target_name)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - major_status = (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); - goto unlock; - } - - /* verify the credential, or use the default */ - /*SUPPRESS 29*/ - if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { - /* - * Solaris Kerberos: here we are using the Solaris specific - * function get_default_cred() to handle the special case of a - * root principal - */ - major_status = get_default_cred(minor_status, ct, (gss_cred_id_t *)&cred); - if (major_status && GSS_ERROR(major_status)) { - KRB5_LOG(KRB5_ERR, "krb5_gss_init_sec_context() end, error " - "major_status = %d\n", major_status); - goto unlock; - } - } else { - major_status = krb5_gss_validate_cred_no_lock(ct, minor_status, - claimant_cred_handle); - if (GSS_ERROR(major_status)) { - KRB5_LOG(KRB5_ERR, "krb5_gss_init_sec_context() end, error " - "major_status = %d\n", major_status); - goto unlock; - } - cred = (krb5_gss_cred_id_t) claimant_cred_handle; - } - - /* verify the mech_type */ - - err = 0; - if (mech_type == GSS_C_NULL_OID) { - default_mech = 1; - if (cred->rfc_mech) { - mech_type = (gss_OID) gss_mech_krb5; - } else if (cred->prerfc_mech) { - mech_type = (gss_OID) gss_mech_krb5_old; - } else { - err = 1; - } - } else if (g_OID_equal(mech_type, gss_mech_krb5)) { - if (!cred->rfc_mech) - err = 1; - } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) { - if (!cred->prerfc_mech) - err = 1; - } else { - err = 1; - } - - if (err) { - *minor_status = 0; - major_status = GSS_S_BAD_MECH; - goto unlock; - } - - /* is this a new connection or not? */ - - /*SUPPRESS 29*/ - if (*context_handle == GSS_C_NO_CONTEXT) { - major_status = new_connection(minor_status, cred, context_handle, - target_name, mech_type, req_flags, - time_req, input_chan_bindings, - input_token, actual_mech_type, - output_token, ret_flags, time_rec, - context, default_mech); - } else { - major_status = mutual_auth(minor_status, cred, context_handle, - target_name, mech_type, req_flags, - time_req, input_chan_bindings, - input_token, actual_mech_type, - output_token, ret_flags, time_rec, - context); - } - -unlock: - if (claimant_cred_handle == GSS_C_NO_CREDENTIAL && cred != NULL) - krb5_gss_release_cred_no_lock(context, &tmp_min_stat, (gss_cred_id_t *)cred); - - mutex_unlock(&krb5_mutex); - - KRB5_LOG1(KRB5_ERR, "krb5_gss_init_sec_context() end, error " - "major_status = %d, minor_status = %d\n", - major_status, *minor_status); - - return (major_status); -} +/* Solaris Kerberos specific routines end */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/inq_context.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_context.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,13 +22,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" OM_uint32 -krb5_gss_inquire_context(ct, minor_status, context_handle, initiator_name, +krb5_gss_inquire_context(minor_status, context_handle, initiator_name, acceptor_name, lifetime_rec, mech_type, ret_flags, locally_initiated, open) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_name_t *initiator_name; @@ -51,16 +45,6 @@ krb5_timestamp now; krb5_deltat lifetime; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ct; - if (initiator_name) *initiator_name = (gss_name_t) NULL; if (acceptor_name) @@ -69,7 +53,6 @@ /* validate the context handle */ if (! kg_validate_ctx_id(context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } @@ -77,16 +60,15 @@ if (! ctx->established) { *minor_status = KG_CTX_INCOMPLETE; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } init = NULL; accept = NULL; + context = ctx->k5_context; - if (code = krb5_timeofday(context, &now)) { + if ((code = krb5_timeofday(context, &now))) { *minor_status = code; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } @@ -94,28 +76,25 @@ lifetime = 0; if (initiator_name) { - if (code = krb5_copy_principal(context, - ctx->initiate?ctx->here:ctx->there, - &init)) { + if ((code = krb5_copy_principal(context, + ctx->initiate?ctx->here:ctx->there, + &init))) { *minor_status = code; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } if (! kg_save_name((gss_name_t) init)) { krb5_free_principal(context, init); *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } } if (acceptor_name) { - if (code = krb5_copy_principal(context, - ctx->initiate?ctx->there:ctx->here, - &accept)) { + if ((code = krb5_copy_principal(context, + ctx->initiate?ctx->there:ctx->here, + &accept))) { if (init) krb5_free_principal(context, init); *minor_status = code; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } if (! kg_save_name((gss_name_t) accept)) { @@ -125,7 +104,6 @@ krb5_free_principal(context, init); } *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_FAILURE); } } @@ -140,8 +118,7 @@ *lifetime_rec = lifetime; if (mech_type) - *mech_type = &(ctx->mech_used); - + *mech_type = (gss_OID) ctx->mech_used; if (ret_flags) *ret_flags = ctx->gss_flags; @@ -153,6 +130,5 @@ *open = ctx->established; *minor_status = 0; - mutex_unlock(&krb5_mutex); return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -13,7 +8,7 @@ * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -27,11 +22,11 @@ * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * */ /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -41,7 +36,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -53,14 +48,14 @@ /* * Copyright (C) 1998 by the FundsXpress, INC. - * + * * All rights reserved. - * + * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -71,44 +66,18 @@ * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#include -#include - -extern OM_uint32 gss_copy_oid_set(); -extern OM_uint32 gss_create_empty_oid_set(); -extern OM_uint32 gss_add_oid_set_member(); - +#include "gssapiP_krb5.h" +#include "mglueP.h" OM_uint32 -krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, +krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, cred_usage, mechanisms) - void *ctx; - OM_uint32 *minor_status; - gss_cred_id_t cred_handle; - gss_name_t *name; - OM_uint32 *lifetime_ret; - gss_cred_usage_t *cred_usage; - gss_OID_set *mechanisms; -{ - OM_uint32 ret; - - mutex_lock(&krb5_mutex); - ret = krb5_gss_inquire_cred_no_lock(ctx, minor_status, cred_handle, name, - lifetime_ret, cred_usage, mechanisms); - mutex_unlock(&krb5_mutex); - return(ret); -} - -OM_uint32 -krb5_gss_inquire_cred_no_lock(ctx, minor_status, cred_handle, name, - lifetime_ret, cred_usage, mechanisms) - void *ctx; OM_uint32 *minor_status; gss_cred_id_t cred_handle; gss_name_t *name; @@ -122,17 +91,17 @@ krb5_timestamp now; krb5_deltat lifetime; krb5_principal ret_name; - gss_OID_set mechs = GSS_C_NULL_OID_SET; + gss_OID_set mechs; OM_uint32 ret; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif + ret = GSS_S_FAILURE; + ret_name = NULL; - context = ctx; + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } if (name) *name = NULL; if (mechanisms) *mechanisms = NULL; @@ -141,27 +110,35 @@ /*SUPPRESS 29*/ if (cred_handle == GSS_C_NO_CREDENTIAL) { OM_uint32 major; - if (((major = kg_get_defcred(minor_status, &cred_handle)) != NULL) && + + if ((major = kg_get_defcred(minor_status, (gss_cred_id_t *)&cred)) && GSS_ERROR(major)) { + krb5_free_context(context); return(major); } } else { OM_uint32 major; - - major = krb5_gss_validate_cred_no_lock(context, minor_status, - cred_handle); + + major = krb5_gss_validate_cred(minor_status, cred_handle); if (GSS_ERROR(major)) { + krb5_free_context(context); return(major); } + cred = (krb5_gss_cred_id_t) cred_handle; } - cred = (krb5_gss_cred_id_t) cred_handle; - if ((code = krb5_timeofday(context, &now))) { *minor_status = code; - return(GSS_S_FAILURE); + ret = GSS_S_FAILURE; + goto fail; } + code = k5_mutex_lock(&cred->lock); + if (code != 0) { + *minor_status = code; + ret = GSS_S_FAILURE; + goto fail; + } if (cred->tgt_expire > 0) { if ((lifetime = cred->tgt_expire - now) < 0) lifetime = 0; @@ -170,43 +147,50 @@ lifetime = GSS_C_INDEFINITE; if (name) { - if (cred->princ && - (code = krb5_copy_principal(context, cred->princ, &ret_name))) { + if (cred->princ && + (code = krb5_copy_principal(context, cred->princ, &ret_name))) { + k5_mutex_unlock(&cred->lock); *minor_status = code; - return(GSS_S_FAILURE); + ret = GSS_S_FAILURE; + goto fail; } } if (mechanisms) { - if (GSS_ERROR(ret = gss_create_empty_oid_set(minor_status, + if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status, &mechs)) || (cred->prerfc_mech && - GSS_ERROR(ret = gss_add_oid_set_member(minor_status, - (gss_OID) gss_mech_krb5_old, + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + (const gss_OID) gss_mech_krb5_old, &mechs))) || (cred->rfc_mech && - GSS_ERROR(ret = gss_add_oid_set_member(minor_status, - (gss_OID) gss_mech_krb5, + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + (const gss_OID) gss_mech_krb5, &mechs)))) { - krb5_free_principal(context, ret_name); + k5_mutex_unlock(&cred->lock); + if (ret_name) + krb5_free_principal(context, ret_name); /* *minor_status set above */ - return(ret); + goto fail; } } - /* Solaris Kerberos: - * Don't set name to ret_name if cred->princ is NULL. - * If cred->princ is NULL, ret_name is uninitialized and - * name already points to NULL. - */ - if (name && cred->princ) { - if (! kg_save_name((gss_name_t) ret_name)) { + if (name) { + if (ret_name != NULL && ! kg_save_name((gss_name_t) ret_name)) { + k5_mutex_unlock(&cred->lock); + if (cred_handle == GSS_C_NO_CREDENTIAL) + krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred); + (void) gss_release_oid_set(minor_status, &mechs); krb5_free_principal(context, ret_name); *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); return(GSS_S_FAILURE); } - *name = (gss_name_t) ret_name; + if (ret_name != NULL) + *name = (gss_name_t) ret_name; + else + *name = GSS_C_NO_NAME; } if (lifetime_ret) @@ -214,20 +198,32 @@ if (cred_usage) *cred_usage = cred->usage; + k5_mutex_unlock(&cred->lock); if (mechanisms) *mechanisms = mechs; + if (cred_handle == GSS_C_NO_CREDENTIAL) + krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred); + + krb5_free_context(context); *minor_status = 0; return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE); +fail: + if (cred_handle == GSS_C_NO_CREDENTIAL) { + OM_uint32 tmp_min_stat; + + krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred); + } + krb5_free_context(context); + return ret; } /* V2 interface */ OM_uint32 -krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle, +krb5_gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, initiator_lifetime, acceptor_lifetime, cred_usage) - void *ctx; OM_uint32 *minor_status; gss_cred_id_t cred_handle; gss_OID mech_type; @@ -236,35 +232,22 @@ OM_uint32 *acceptor_lifetime; gss_cred_usage_t *cred_usage; { - krb5_context context; krb5_gss_cred_id_t cred; OM_uint32 lifetime; OM_uint32 mstat; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ctx; - /* * We only know how to handle our own creds. */ if ((mech_type != GSS_C_NULL_OID) && !g_OID_equal(gss_mech_krb5_old, mech_type) && - !g_OID_equal(gss_mech_krb5, mech_type) && - !g_OID_equal(gss_mech_krb5_v2, mech_type)) { + !g_OID_equal(gss_mech_krb5, mech_type)) { *minor_status = 0; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CRED); } cred = (krb5_gss_cred_id_t) cred_handle; - mstat = krb5_gss_inquire_cred_no_lock(context, minor_status, + mstat = krb5_gss_inquire_cred(minor_status, cred_handle, name, &lifetime, @@ -282,6 +265,6 @@ acceptor_lifetime) *acceptor_lifetime = lifetime; } - mutex_unlock(&krb5_mutex); return(mstat); } + diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -35,36 +30,24 @@ /* * inq_names.c - Return set of nametypes supported by the KRB5 mechanism. */ -#include +#include "gssapiP_krb5.h" +#include "mglueP.h" -/*ARGSUSED*/ OM_uint32 -krb5_gss_inquire_names_for_mech(ctx, minor_status, mechanism, name_types) - void *ctx; +krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types) OM_uint32 *minor_status; gss_OID mechanism; gss_OID_set *name_types; { OM_uint32 major, minor; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - /* * We only know how to handle our own mechanism. */ if ((mechanism != GSS_C_NULL_OID) && - !g_OID_equal(gss_mech_krb5_v2, mechanism) && !g_OID_equal(gss_mech_krb5, mechanism) && !g_OID_equal(gss_mech_krb5_old, mechanism)) { *minor_status = 0; - mutex_unlock(&krb5_mutex); return(GSS_S_BAD_MECH); } @@ -73,40 +56,38 @@ if (major == GSS_S_COMPLETE) { /* Now add our members. */ if ( - /* The following are GSS specified nametypes */ - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) GSS_C_NT_USER_NAME, - name_types) + ((major = generic_gss_add_oid_set_member(minor_status, + gss_nt_user_name, + name_types) ) == GSS_S_COMPLETE) && - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) GSS_C_NT_MACHINE_UID_NAME, - name_types) + ((major = generic_gss_add_oid_set_member(minor_status, + gss_nt_machine_uid_name, + name_types) ) == GSS_S_COMPLETE) && - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) GSS_C_NT_STRING_UID_NAME, - name_types) + ((major = generic_gss_add_oid_set_member(minor_status, + gss_nt_string_uid_name, + name_types) ) == GSS_S_COMPLETE) && - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, - name_types) + ((major = generic_gss_add_oid_set_member(minor_status, + gss_nt_service_name, + name_types) + ) == GSS_S_COMPLETE) && + ((major = generic_gss_add_oid_set_member(minor_status, + gss_nt_service_name_v2, + name_types) ) == GSS_S_COMPLETE) && - /* The following are kerberos only nametypes */ - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) gss_nt_service_name_v2, - name_types) + ((major = generic_gss_add_oid_set_member(minor_status, + gss_nt_exported_name, + name_types) ) == GSS_S_COMPLETE) && - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) gss_nt_exported_name, - name_types) - ) == GSS_S_COMPLETE) && - ((major = gss_add_oid_set_member(minor_status, - (gss_OID) gss_nt_krb5_name, - name_types) + ((major = generic_gss_add_oid_set_member(minor_status, + (const gss_OID) gss_nt_krb5_name, + name_types) ) == GSS_S_COMPLETE) ) { - major = gss_add_oid_set_member(minor_status, - (gss_OID) gss_nt_krb5_principal, - name_types); + major = generic_gss_add_oid_set_member(minor_status, + (const gss_OID) gss_nt_krb5_principal, + name_types); } /* @@ -117,6 +98,5 @@ (void) gss_release_oid_set(&minor, name_types); } - mutex_unlock(&krb5_mutex); return(major); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c Fri Sep 14 14:36:45 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * XXX: I know where to find this header, but it really is using a - * private interface. I dont want to export the gss_mechanism - * structure, so I hide it in a non-published header. Thats ok, - * we know where to find it. - */ -#include - -#include -#include -#include -/* - * These are the extern declarations, one group per mechanism. They are - * contained in the files named _gssd_extern_srvr.conf. - */ - -static OM_uint32 -krb5_gss_get_context - PROTOTYPE((void**)); - -/* - * This is the declaration of the mechs_array table for Kerberos V5. - * If the gss_mechanism structure changes, so should this array! I - * told you it was a private interface! - */ - -static struct gss_config krb5_mechanism = { - {9, "\052\206\110\206\367\022\001\002\002"}, - 0, /* context, to be filled */ - krb5_gss_acquire_cred, - krb5_gss_release_cred, - krb5_gss_init_sec_context, - krb5_gss_accept_sec_context, -/* EXPORT DELETE START */ /* CRYPT DELETE START */ - krb5_gss_unseal, -/* EXPORT DELETE END */ /* CRYPT DELETE END */ - krb5_gss_process_context_token, - krb5_gss_delete_sec_context, - krb5_gss_context_time, - krb5_gss_display_status, - krb5_gss_indicate_mechs, - krb5_gss_compare_name, - krb5_gss_display_name, - krb5_gss_import_name, - krb5_gss_release_name, - krb5_gss_inquire_cred, - krb5_gss_add_cred, -/* EXPORT DELETE START */ /* CRYPT DELETE START */ - krb5_gss_seal, -/* EXPORT DELETE END */ /* CRYPT DELETE END */ - krb5_gss_export_sec_context, - krb5_gss_import_sec_context, - krb5_gss_inquire_cred_by_mech, - krb5_gss_inquire_names_for_mech, - krb5_gss_inquire_context, - krb5_gss_internal_release_oid, - krb5_gss_wrap_size_limit, - krb5_pname_to_uid, - krb5_gss_userok, - NULL, /* export_name */ -/* EXPORT DELETE START */ -/* CRYPT DELETE START */ -#if 0 -/* CRYPT DELETE END */ - krb5_gss_seal, - krb5_gss_unseal, -/* CRYPT DELETE START */ -#endif -/* CRYPT DELETE END */ -/* EXPORT DELETE END */ - krb5_gss_sign, - krb5_gss_verify, - krb5_gss_store_cred, - }; - -#include - - -OM_uint32 -krb5_gss_get_context(context) -void ** context; -{ - /* Solaris Kerberos: the following is a global variable declared - * and initialized in gssapi_krb5.c */ - /* static krb5_context kg_context = NULL; */ - krb5_error_code errCode = 0; - - if (context == NULL) - return (GSS_S_FAILURE); - if (kg_context) { - *context = kg_context; - return (GSS_S_COMPLETE); - } - - if ((errCode = krb5_init_context(&kg_context))) - goto error; - - if (((errCode = krb5_ser_context_init(kg_context)) != 0) || - ((errCode = krb5_ser_auth_context_init(kg_context)) != 0) || - ((errCode = krb5_ser_ccache_init(kg_context)) != 0) || - ((errCode = krb5_ser_rcache_init(kg_context)) != 0) || - ((errCode = krb5_ser_keytab_init(kg_context)) != 0) || - ((errCode = krb5_ser_context_init(kg_context)) != 0)) { - krb5_free_context(kg_context); - kg_context = 0; - goto error; - } - - *context = kg_context; - return (GSS_S_COMPLETE); - -error: - if (errCode != 0) { - syslog(LOG_ERR, - dgettext(TEXT_DOMAIN, - - "Kerberos mechanism library" - " initialization error: %s."), - error_message((long)errCode)); - } - return (GSS_S_FAILURE); -} - -/* - * entry point for the gss layer, - * called "krb5_gss_initialize()" in MIT 1.2.1 - */ -gss_mechanism -gss_mech_initialize(oid) -const gss_OID oid; -{ - /* ensure that the requested oid matches our oid */ - if (oid == NULL || !g_OID_equal(oid, &krb5_mechanism.mech_type)) - return (NULL); - - if (krb5_gss_get_context(&(krb5_mechanism.context)) != - GSS_S_COMPLETE) - return (NULL); - - return (&krb5_mechanism); -} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,1369 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * $Id: krb5_gss_glue.c 18268 2006-06-29 19:44:34Z tlyu $ + */ + +#include "gssapiP_krb5.h" +#include "mglueP.h" +#include + +/** mechglue wrappers **/ + +static OM_uint32 k5glue_acquire_cred +(void *, OM_uint32*, /* minor_status */ + gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + gss_OID_set, /* desired_mechs */ + gss_cred_usage_t, /* cred_usage */ + gss_cred_id_t*, /* output_cred_handle */ + gss_OID_set*, /* actual_mechs */ + OM_uint32* /* time_rec */ + ); + +static OM_uint32 k5glue_release_cred +(void *, OM_uint32*, /* minor_status */ + gss_cred_id_t* /* cred_handle */ + ); + +static OM_uint32 k5glue_init_sec_context +(void *, OM_uint32*, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t*, /* context_handle */ + gss_name_t, /* target_name */ + gss_OID, /* mech_type */ + OM_uint32, /* req_flags */ + OM_uint32, /* time_req */ + gss_channel_bindings_t, + /* input_chan_bindings */ + gss_buffer_t, /* input_token */ + gss_OID*, /* actual_mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32*, /* ret_flags */ + OM_uint32* /* time_rec */ + ); + +static OM_uint32 k5glue_accept_sec_context +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_cred_id_t, /* verifier_cred_handle */ + gss_buffer_t, /* input_token_buffer */ + gss_channel_bindings_t, + /* input_chan_bindings */ + gss_name_t*, /* src_name */ + gss_OID*, /* mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32*, /* ret_flags */ + OM_uint32*, /* time_rec */ + gss_cred_id_t* /* delegated_cred_handle */ + ); + +static OM_uint32 k5glue_process_context_token +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + ); + +static OM_uint32 k5glue_delete_sec_context +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t /* output_token */ + ); + +static OM_uint32 k5glue_context_time +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32* /* time_rec */ + ); + +static OM_uint32 k5glue_sign +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + +static OM_uint32 k5glue_verify +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + +/* EXPORT DELETE START */ +static OM_uint32 k5glue_seal +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int*, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + +static OM_uint32 k5glue_unseal +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int*, /* conf_state */ + int* /* qop_state */ + ); +/* EXPORT DELETE END */ + +static OM_uint32 k5glue_display_status +(void *, OM_uint32*, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + gss_OID, /* mech_type */ + OM_uint32*, /* message_context */ + gss_buffer_t /* status_string */ + ); + +static OM_uint32 k5glue_indicate_mechs +(void *, OM_uint32*, /* minor_status */ + gss_OID_set* /* mech_set */ + ); + +static OM_uint32 k5glue_compare_name +(void *, OM_uint32*, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int* /* name_equal */ + ); + +static OM_uint32 k5glue_display_name +(void *, OM_uint32*, /* minor_status */ + gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID* /* output_name_type */ + ); + +static OM_uint32 k5glue_import_name +(void *, OM_uint32*, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + gss_OID, /* input_name_type */ + gss_name_t* /* output_name */ + ); + +static OM_uint32 k5glue_release_name +(void *, OM_uint32*, /* minor_status */ + gss_name_t* /* input_name */ + ); + +static OM_uint32 k5glue_inquire_cred +(void *, OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + gss_cred_usage_t*,/* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + +static OM_uint32 k5glue_inquire_context +(void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_name_t*, /* initiator_name */ + gss_name_t*, /* acceptor_name */ + OM_uint32*, /* lifetime_rec */ + gss_OID*, /* mech_type */ + OM_uint32*, /* ret_flags */ + int*, /* locally_initiated */ + int* /* open */ + ); + +#if 0 +/* New V2 entry points */ +static OM_uint32 k5glue_get_mic +(void *, OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_qop_t, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + +static OM_uint32 k5glue_verify_mic +(void *, OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* message_token */ + gss_qop_t * /* qop_state */ + ); + +static OM_uint32 k5glue_wrap +(void *, OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int *, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + +static OM_uint32 k5glue_unwrap +(void *, OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int *, /* conf_state */ + gss_qop_t * /* qop_state */ + ); +#endif + +static OM_uint32 k5glue_wrap_size_limit +(void *, OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + OM_uint32, /* req_output_size */ + OM_uint32 * /* max_input_size */ + ); + +#if 0 +static OM_uint32 k5glue_import_name_object +(void *, OM_uint32 *, /* minor_status */ + void *, /* input_name */ + gss_OID, /* input_name_type */ + gss_name_t * /* output_name */ + ); + +static OM_uint32 k5glue_export_name_object +(void *, OM_uint32 *, /* minor_status */ + gss_name_t, /* input_name */ + gss_OID, /* desired_name_type */ + void * * /* output_name */ + ); +#endif + +static OM_uint32 k5glue_add_cred +(void *, OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* input_cred_handle */ + gss_name_t, /* desired_name */ + gss_OID, /* desired_mech */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 *, /* initiator_time_rec */ + OM_uint32 * /* acceptor_time_rec */ + ); + +static OM_uint32 k5glue_inquire_cred_by_mech +(void *, OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_OID, /* mech_type */ + gss_name_t *, /* name */ + OM_uint32 *, /* initiator_lifetime */ + OM_uint32 *, /* acceptor_lifetime */ + gss_cred_usage_t * /* cred_usage */ + ); + +static OM_uint32 k5glue_export_sec_context +(void *, OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* interprocess_token */ + ); + +static OM_uint32 k5glue_import_sec_context +(void *, OM_uint32 *, /* minor_status */ + gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t * /* context_handle */ + ); + +krb5_error_code k5glue_ser_init(krb5_context); + +static OM_uint32 k5glue_internal_release_oid +(void *, OM_uint32 *, /* minor_status */ + gss_OID * /* oid */ + ); + +static OM_uint32 k5glue_inquire_names_for_mech +(void *, OM_uint32 *, /* minor_status */ + gss_OID, /* mechanism */ + gss_OID_set * /* name_types */ + ); + +#if 0 +static OM_uint32 k5glue_canonicalize_name +(void *, OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + const gss_OID, /* mech_type */ + gss_name_t * /* output_name */ + ); +#endif + +static OM_uint32 k5glue_export_name +(void *, OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t /* exported_name */ + ); + +/* SUNW15resync - Solaris specific */ +static OM_uint32 k5glue_store_cred ( + void *, + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* input_cred */ + gss_cred_usage_t, /* cred_usage */ + const gss_OID, /* desired_mech */ + OM_uint32, /* overwrite_cred */ + OM_uint32, /* default_cred */ + gss_OID_set *, /* elements_stored */ + gss_cred_usage_t * /* cred_usage_stored */ + ); + +static OM_uint32 +k5glue_userok( + void *, /* context */ + OM_uint32 *, /* minor_status */ + const gss_name_t, /* pname */ + const char *, /* local user */ + int * /* user ok? */ + /* */); + +static OM_uint32 +k5glue_pname_to_uid( + void *, /* context */ + OM_uint32 *, /* minor_status */ + const gss_name_t, /* pname */ + uid_t * /* uid */ + /* */); + + + + +#if 0 +static OM_uint32 k5glue_duplicate_name +(void *, OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_name_t * /* dest_name */ + ); +#endif + +#if 0 +static OM_uint32 k5glue_validate_cred +(void *, OM_uint32 *, /* minor_status */ + gss_cred_id_t /* cred */ + ); +#endif + +#if 0 +/* + * SUNW15resync + * Solaris can't use the KRB5_GSS_CONFIG_INIT macro because of the src + * slicing&dicing needs of the "nightly -SD" build. When it goes away, + * we should use it assuming MIT still uses it then. + */ + +/* + * The krb5 mechanism provides two mech OIDs; use this initializer to + * ensure that both dispatch tables contain identical function + * pointers. + */ +#define KRB5_GSS_CONFIG_INIT \ + NULL, \ + ... +#endif + + +static struct gss_config krb5_mechanism = { +#if 0 /* Solaris Kerberos */ + 100, "kerberos_v5", +#endif + { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID }, + NULL, + k5glue_acquire_cred, + k5glue_release_cred, + k5glue_init_sec_context, + k5glue_accept_sec_context, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + k5glue_unseal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + k5glue_process_context_token, + k5glue_delete_sec_context, + k5glue_context_time, + k5glue_display_status, + k5glue_indicate_mechs, + k5glue_compare_name, + k5glue_display_name, + k5glue_import_name, + k5glue_release_name, + k5glue_inquire_cred, + k5glue_add_cred, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + k5glue_seal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + k5glue_export_sec_context, + k5glue_import_sec_context, + k5glue_inquire_cred_by_mech, + k5glue_inquire_names_for_mech, + k5glue_inquire_context, + k5glue_internal_release_oid, + k5glue_wrap_size_limit, + k5glue_pname_to_uid, + k5glue_userok, + k5glue_export_name, +/* EXPORT DELETE START */ +/* CRYPT DELETE START */ +#if 0 +/* CRYPT DELETE END */ + k5glue_seal, + k5glue_unseal, +/* CRYPT DELETE START */ +#endif +/* CRYPT DELETE END */ +/* EXPORT DELETE END */ + k5glue_sign, + k5glue_verify, + k5glue_store_cred +}; + +static struct gss_config krb5_mechanism_old = { +#if 0 /* Solaris Kerberos */ + 200, "kerberos_v5 (pre-RFC OID)", +#endif + { GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID }, + NULL, + k5glue_acquire_cred, + k5glue_release_cred, + k5glue_init_sec_context, + k5glue_accept_sec_context, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + k5glue_unseal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + k5glue_process_context_token, + k5glue_delete_sec_context, + k5glue_context_time, + k5glue_display_status, + k5glue_indicate_mechs, + k5glue_compare_name, + k5glue_display_name, + k5glue_import_name, + k5glue_release_name, + k5glue_inquire_cred, + k5glue_add_cred, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + k5glue_seal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + k5glue_export_sec_context, + k5glue_import_sec_context, + k5glue_inquire_cred_by_mech, + k5glue_inquire_names_for_mech, + k5glue_inquire_context, + k5glue_internal_release_oid, + k5glue_wrap_size_limit, + k5glue_pname_to_uid, + k5glue_userok, + k5glue_export_name, +/* EXPORT DELETE START */ +/* CRYPT DELETE START */ +#if 0 +/* CRYPT DELETE END */ + k5glue_seal, + k5glue_unseal, +/* CRYPT DELETE START */ +#endif +/* CRYPT DELETE END */ +/* EXPORT DELETE END */ + k5glue_sign, + k5glue_verify, + k5glue_store_cred +}; + +static struct gss_config krb5_mechanism_wrong = { +#if 0 /* Solaris Kerberos */ + 300, "kerberos_v5 (wrong OID)", +#endif + { GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID }, + NULL, + k5glue_acquire_cred, + k5glue_release_cred, + k5glue_init_sec_context, + k5glue_accept_sec_context, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + k5glue_unseal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + k5glue_process_context_token, + k5glue_delete_sec_context, + k5glue_context_time, + k5glue_display_status, + k5glue_indicate_mechs, + k5glue_compare_name, + k5glue_display_name, + k5glue_import_name, + k5glue_release_name, + k5glue_inquire_cred, + k5glue_add_cred, +/* EXPORT DELETE START */ /* CRYPT DELETE START */ + k5glue_seal, +/* EXPORT DELETE END */ /* CRYPT DELETE END */ + k5glue_export_sec_context, + k5glue_import_sec_context, + k5glue_inquire_cred_by_mech, + k5glue_inquire_names_for_mech, + k5glue_inquire_context, + k5glue_internal_release_oid, + k5glue_wrap_size_limit, + k5glue_pname_to_uid, + k5glue_userok, + k5glue_export_name, +/* EXPORT DELETE START */ +/* CRYPT DELETE START */ +#if 0 +/* CRYPT DELETE END */ + k5glue_seal, + k5glue_unseal, +/* CRYPT DELETE START */ +#endif +/* CRYPT DELETE END */ +/* EXPORT DELETE END */ + k5glue_sign, + k5glue_verify, + k5glue_store_cred +}; + +static gss_mechanism krb5_mech_configs[] = { + &krb5_mechanism, &krb5_mechanism_old, &krb5_mechanism_wrong, NULL +}; + +#ifdef MS_BUG_TEST +static gss_mechanism krb5_mech_configs_hack[] = { + &krb5_mechanism, &krb5_mechanism_old, NULL +}; +#endif + +#if 1 +#define gssint_get_mech_configs krb5_gss_get_mech_configs +#endif + +gss_mechanism * +gssint_get_mech_configs(void) +{ +#ifdef MS_BUG_TEST + char *envstr = getenv("MS_FORCE_NO_MSOID"); + + if (envstr != NULL && strcmp(envstr, "1") == 0) { + return krb5_mech_configs_hack; + } +#endif + return krb5_mech_configs; +} + +static OM_uint32 +k5glue_accept_sec_context(ctx, minor_status, context_handle, verifier_cred_handle, + input_token, input_chan_bindings, src_name, mech_type, + output_token, ret_flags, time_rec, delegated_cred_handle) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_cred_id_t verifier_cred_handle; + gss_buffer_t input_token; + gss_channel_bindings_t input_chan_bindings; + gss_name_t *src_name; + gss_OID *mech_type; + gss_buffer_t output_token; + OM_uint32 *ret_flags; + OM_uint32 *time_rec; + gss_cred_id_t *delegated_cred_handle; +{ + return(krb5_gss_accept_sec_context(minor_status, + context_handle, + verifier_cred_handle, + input_token, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle)); +} + +static OM_uint32 +k5glue_acquire_cred(ctx, minor_status, desired_name, time_req, desired_mechs, + cred_usage, output_cred_handle, actual_mechs, time_rec) + void *ctx; + OM_uint32 *minor_status; + gss_name_t desired_name; + OM_uint32 time_req; + gss_OID_set desired_mechs; + gss_cred_usage_t cred_usage; + gss_cred_id_t *output_cred_handle; + gss_OID_set *actual_mechs; + OM_uint32 *time_rec; +{ + return(krb5_gss_acquire_cred(minor_status, + desired_name, + time_req, + desired_mechs, + cred_usage, + output_cred_handle, + actual_mechs, + time_rec)); +} + +/* V2 */ +static OM_uint32 +k5glue_add_cred(ctx, minor_status, input_cred_handle, desired_name, desired_mech, + cred_usage, initiator_time_req, acceptor_time_req, + output_cred_handle, actual_mechs, initiator_time_rec, + acceptor_time_rec) + void *ctx; + OM_uint32 *minor_status; + gss_cred_id_t input_cred_handle; + gss_name_t desired_name; + gss_OID desired_mech; + gss_cred_usage_t cred_usage; + OM_uint32 initiator_time_req; + OM_uint32 acceptor_time_req; + gss_cred_id_t *output_cred_handle; + gss_OID_set *actual_mechs; + OM_uint32 *initiator_time_rec; + OM_uint32 *acceptor_time_rec; +{ + return(krb5_gss_add_cred(minor_status, input_cred_handle, desired_name, + desired_mech, cred_usage, initiator_time_req, + acceptor_time_req, output_cred_handle, + actual_mechs, initiator_time_rec, + acceptor_time_rec)); +} + +#if 0 +/* V2 */ +static OM_uint32 +k5glue_add_oid_set_member(ctx, minor_status, member_oid, oid_set) + void *ctx; + OM_uint32 *minor_status; + gss_OID member_oid; + gss_OID_set *oid_set; +{ + return(generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)); +} +#endif + +static OM_uint32 +k5glue_compare_name(ctx, minor_status, name1, name2, name_equal) + void *ctx; + OM_uint32 *minor_status; + gss_name_t name1; + gss_name_t name2; + int *name_equal; +{ + return(krb5_gss_compare_name(minor_status, name1, + name2, name_equal)); +} + +static OM_uint32 +k5glue_context_time(ctx, minor_status, context_handle, time_rec) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + OM_uint32 *time_rec; +{ + return(krb5_gss_context_time(minor_status, context_handle, + time_rec)); +} + +#if 0 +/* V2 */ +static OM_uint32 +k5glue_create_empty_oid_set(ctx, minor_status, oid_set) + void *ctx; + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + return(generic_gss_create_empty_oid_set(minor_status, oid_set)); +} +#endif + +static OM_uint32 +k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_buffer_t output_token; +{ + return(krb5_gss_delete_sec_context(minor_status, + context_handle, output_token)); +} + +static OM_uint32 +k5glue_display_name(ctx, minor_status, input_name, output_name_buffer, output_name_type) + void *ctx; + OM_uint32 *minor_status; + gss_name_t input_name; + gss_buffer_t output_name_buffer; + gss_OID *output_name_type; +{ + return(krb5_gss_display_name(minor_status, input_name, + output_name_buffer, output_name_type)); +} + +static OM_uint32 +k5glue_display_status(ctx, minor_status, status_value, status_type, + mech_type, message_context, status_string) + void *ctx; + OM_uint32 *minor_status; + OM_uint32 status_value; + int status_type; + gss_OID mech_type; + OM_uint32 *message_context; + gss_buffer_t status_string; +{ + return(krb5_gss_display_status(minor_status, status_value, + status_type, mech_type, message_context, + status_string)); +} + +/* V2 */ +static OM_uint32 +k5glue_export_sec_context(ctx, minor_status, context_handle, interprocess_token) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_buffer_t interprocess_token; +{ + return(krb5_gss_export_sec_context(minor_status, + context_handle, + interprocess_token)); +} + +#if 0 +/* V2 */ +static OM_uint32 +k5glue_get_mic(ctx, minor_status, context_handle, qop_req, + message_buffer, message_token) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_qop_t qop_req; + gss_buffer_t message_buffer; + gss_buffer_t message_token; +{ + return(krb5_gss_get_mic(minor_status, context_handle, + qop_req, message_buffer, message_token)); +} +#endif + +static OM_uint32 +k5glue_import_name(ctx, minor_status, input_name_buffer, input_name_type, output_name) + void *ctx; + OM_uint32 *minor_status; + gss_buffer_t input_name_buffer; + gss_OID input_name_type; + gss_name_t *output_name; +{ +#if 0 + OM_uint32 err; + err = gssint_initialize_library(); + if (err) { + *minor_status = err; + return GSS_S_FAILURE; + } +#endif + return(krb5_gss_import_name(minor_status, input_name_buffer, + input_name_type, output_name)); +} + +/* V2 */ +static OM_uint32 +k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle) + void *ctx; + OM_uint32 *minor_status; + gss_buffer_t interprocess_token; + gss_ctx_id_t *context_handle; +{ + return(krb5_gss_import_sec_context(minor_status, + interprocess_token, + context_handle)); +} + +static OM_uint32 +k5glue_indicate_mechs(ctx, minor_status, mech_set) + void *ctx; + OM_uint32 *minor_status; + gss_OID_set *mech_set; +{ + return(krb5_gss_indicate_mechs(minor_status, mech_set)); +} + +static OM_uint32 +k5glue_init_sec_context(ctx, minor_status, claimant_cred_handle, context_handle, + target_name, mech_type, req_flags, time_req, + input_chan_bindings, input_token, actual_mech_type, + output_token, ret_flags, time_rec) + void *ctx; + OM_uint32 *minor_status; + gss_cred_id_t claimant_cred_handle; + gss_ctx_id_t *context_handle; + gss_name_t target_name; + gss_OID mech_type; + OM_uint32 req_flags; + OM_uint32 time_req; + gss_channel_bindings_t input_chan_bindings; + gss_buffer_t input_token; + gss_OID *actual_mech_type; + gss_buffer_t output_token; + OM_uint32 *ret_flags; + OM_uint32 *time_rec; +{ + return(krb5_gss_init_sec_context(minor_status, + claimant_cred_handle, context_handle, + target_name, mech_type, req_flags, + time_req, input_chan_bindings, input_token, + actual_mech_type, output_token, ret_flags, + time_rec)); +} + +static OM_uint32 +k5glue_inquire_context(ctx, minor_status, context_handle, initiator_name, acceptor_name, + lifetime_rec, mech_type, ret_flags, + locally_initiated, open) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_name_t *initiator_name; + gss_name_t *acceptor_name; + OM_uint32 *lifetime_rec; + gss_OID *mech_type; + OM_uint32 *ret_flags; + int *locally_initiated; + int *open; +{ + return(krb5_gss_inquire_context(minor_status, context_handle, + initiator_name, acceptor_name, lifetime_rec, + mech_type, ret_flags, locally_initiated, + open)); +} + +static OM_uint32 +k5glue_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret, + cred_usage, mechanisms) + void *ctx; + OM_uint32 *minor_status; + gss_cred_id_t cred_handle; + gss_name_t *name; + OM_uint32 *lifetime_ret; + gss_cred_usage_t *cred_usage; + gss_OID_set *mechanisms; +{ + return(krb5_gss_inquire_cred(minor_status, cred_handle, + name, lifetime_ret, cred_usage, mechanisms)); +} + +/* V2 */ +static OM_uint32 +k5glue_inquire_cred_by_mech(ctx, minor_status, cred_handle, mech_type, name, + initiator_lifetime, acceptor_lifetime, cred_usage) + void *ctx; + OM_uint32 *minor_status; + gss_cred_id_t cred_handle; + gss_OID mech_type; + gss_name_t *name; + OM_uint32 *initiator_lifetime; + OM_uint32 *acceptor_lifetime; + gss_cred_usage_t *cred_usage; +{ + return(krb5_gss_inquire_cred_by_mech(minor_status, cred_handle, + mech_type, name, initiator_lifetime, + acceptor_lifetime, cred_usage)); +} + +/* V2 */ +static OM_uint32 +k5glue_inquire_names_for_mech(ctx, minor_status, mechanism, name_types) + void *ctx; + OM_uint32 *minor_status; + gss_OID mechanism; + gss_OID_set *name_types; +{ + return(krb5_gss_inquire_names_for_mech(minor_status, + mechanism, + name_types)); +} + +#if 0 +/* V2 */ +static OM_uint32 +k5glue_oid_to_str(ctx, minor_status, oid, oid_str) + void *ctx; + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + return(generic_gss_oid_to_str(minor_status, oid, oid_str)); +} +#endif + +static OM_uint32 +k5glue_process_context_token(ctx, minor_status, context_handle, token_buffer) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t token_buffer; +{ + return(krb5_gss_process_context_token(minor_status, + context_handle, token_buffer)); +} + +static OM_uint32 +k5glue_release_cred(ctx, minor_status, cred_handle) + void *ctx; + OM_uint32 *minor_status; + gss_cred_id_t *cred_handle; +{ + return(krb5_gss_release_cred(minor_status, cred_handle)); +} + +static OM_uint32 +k5glue_release_name(ctx, minor_status, input_name) + void *ctx; + OM_uint32 *minor_status; + gss_name_t *input_name; +{ + return(krb5_gss_release_name(minor_status, input_name)); +} + +#if 0 +static OM_uint32 +k5glue_release_buffer(ctx, minor_status, buffer) + void *ctx; + OM_uint32 *minor_status; + gss_buffer_t buffer; +{ + return(generic_gss_release_buffer(minor_status, + buffer)); +} +#endif + +/* V2 */ +static OM_uint32 +k5glue_internal_release_oid(ctx, minor_status, oid) + void *ctx; + OM_uint32 *minor_status; + gss_OID *oid; +{ + return(krb5_gss_internal_release_oid(minor_status, oid)); +} + +#if 0 +static OM_uint32 +k5glue_release_oid_set(ctx, minor_status, set) + void *ctx; + OM_uint32 * minor_status; + gss_OID_set *set; +{ + return(generic_gss_release_oid_set(minor_status, set)); +} +#endif + +/* EXPORT DELETE START */ +/* V1 only */ +static OM_uint32 +k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, output_message_buffer) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + int qop_req; + gss_buffer_t input_message_buffer; + int *conf_state; + gss_buffer_t output_message_buffer; +{ + return(krb5_gss_seal(minor_status, context_handle, + conf_req_flag, qop_req, input_message_buffer, + conf_state, output_message_buffer)); +} +/* EXPORT DELETE END */ + +static OM_uint32 +k5glue_sign(ctx, minor_status, context_handle, + qop_req, message_buffer, + message_token) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int qop_req; + gss_buffer_t message_buffer; + gss_buffer_t message_token; +{ + return(krb5_gss_sign(minor_status, context_handle, + qop_req, message_buffer, message_token)); +} + +#if 0 +/* V2 */ +static OM_uint32 +k5glue_verify_mic(ctx, minor_status, context_handle, + message_buffer, token_buffer, qop_state) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t message_buffer; + gss_buffer_t token_buffer; + gss_qop_t *qop_state; +{ + return(krb5_gss_verify_mic(minor_status, context_handle, + message_buffer, token_buffer, qop_state)); +} + +/* V2 */ +static OM_uint32 +k5glue_wrap(ctx, minor_status, context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, output_message_buffer) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + gss_qop_t qop_req; + gss_buffer_t input_message_buffer; + int *conf_state; + gss_buffer_t output_message_buffer; +{ + return(krb5_gss_wrap(minor_status, context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, + output_message_buffer)); +} + +/* V2 */ +static OM_uint32 +k5glue_str_to_oid(ctx, minor_status, oid_str, oid) + void *ctx; + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + return(generic_gss_str_to_oid(minor_status, oid_str, oid)); +} + +/* V2 */ +static OM_uint32 +k5glue_test_oid_set_member(ctx, minor_status, member, set, present) + void *ctx; + OM_uint32 *minor_status; + gss_OID member; + gss_OID_set set; + int *present; +{ + return(generic_gss_test_oid_set_member(minor_status, member, set, + present)); +} +#endif + +/* EXPORT DELETE START */ +/* V1 only */ +static OM_uint32 +k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer, + output_message_buffer, conf_state, qop_state) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_message_buffer; + gss_buffer_t output_message_buffer; + int *conf_state; + int *qop_state; +{ + return(krb5_gss_unseal(minor_status, context_handle, + input_message_buffer, output_message_buffer, + conf_state, qop_state)); +} +/* EXPORT DELETE END */ + +#if 0 +/* V2 */ +static OM_uint32 +k5glue_unwrap(ctx, minor_status, context_handle, input_message_buffer, + output_message_buffer, conf_state, qop_state) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_message_buffer; + gss_buffer_t output_message_buffer; + int *conf_state; + gss_qop_t *qop_state; +{ + return(krb5_gss_unwrap(minor_status, context_handle, input_message_buffer, + output_message_buffer, conf_state, qop_state)); +} +#endif + +/* V1 only */ +static OM_uint32 +k5glue_verify(ctx, minor_status, context_handle, message_buffer, + token_buffer, qop_state) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t message_buffer; + gss_buffer_t token_buffer; + int *qop_state; +{ + return(krb5_gss_verify(minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state)); +} + +/* V2 interface */ +static OM_uint32 +k5glue_wrap_size_limit(ctx, minor_status, context_handle, conf_req_flag, + qop_req, req_output_size, max_input_size) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + gss_qop_t qop_req; + OM_uint32 req_output_size; + OM_uint32 *max_input_size; +{ + return(krb5_gss_wrap_size_limit(minor_status, context_handle, + conf_req_flag, qop_req, + req_output_size, max_input_size)); +} + +#if 0 +/* V2 interface */ +static OM_uint32 +k5glue_canonicalize_name(ctx, minor_status, input_name, mech_type, output_name) + void *ctx; + OM_uint32 *minor_status; + const gss_name_t input_name; + const gss_OID mech_type; + gss_name_t *output_name; +{ + return krb5_gss_canonicalize_name(minor_status, input_name, + mech_type, output_name); +} +#endif + +/* V2 interface */ +static OM_uint32 +k5glue_export_name(ctx, minor_status, input_name, exported_name) + void *ctx; + OM_uint32 *minor_status; + const gss_name_t input_name; + gss_buffer_t exported_name; +{ + return krb5_gss_export_name(minor_status, input_name, exported_name); +} + +/* SUNW15resync - this is not in the MIT mech (lib) yet */ +static OM_uint32 +k5glue_store_cred(ctx, minor_status, input_cred, cred_usage, desired_mech, + overwrite_cred, default_cred, elements_stored, + cred_usage_stored) +void *ctx; +OM_uint32 *minor_status; +const gss_cred_id_t input_cred; +gss_cred_usage_t cred_usage; +gss_OID desired_mech; +OM_uint32 overwrite_cred; +OM_uint32 default_cred; +gss_OID_set *elements_stored; +gss_cred_usage_t *cred_usage_stored; +{ + return(krb5_gss_store_cred(minor_status, input_cred, + cred_usage, desired_mech, + overwrite_cred, default_cred, elements_stored, + cred_usage_stored)); +} + +static OM_uint32 +k5glue_userok( + void *ctxt, /* context */ + OM_uint32 *minor, /* minor_status */ + const gss_name_t pname, /* pname */ + const char *user, /* local user */ + int *user_ok /* user ok? */ + /* */) +{ + return(krb5_gss_userok(minor, pname, user, user_ok)); +} + +static OM_uint32 +k5glue_pname_to_uid( + void *ctxt, /* context */ + OM_uint32 *minor, /* minor_status */ + const gss_name_t pname, /* pname */ + uid_t *uidOut /* uid */ + /* */) +{ + return (krb5_pname_to_uid(minor, pname, uidOut)); +} + + + +#if 0 +/* V2 interface */ +static OM_uint32 +k5glue_duplicate_name(ctx, minor_status, input_name, dest_name) + void *ctx; + OM_uint32 *minor_status; + const gss_name_t input_name; + gss_name_t *dest_name; +{ + return krb5_gss_duplicate_name(minor_status, input_name, dest_name); +} +#endif + +OM_uint32 KRB5_CALLCONV +gss_krb5_get_tkt_flags( + OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_flags *ticket_flags) +{ + gss_union_ctx_id_t uctx; + + uctx = (gss_union_ctx_id_t)context_handle; + if (!g_OID_equal(uctx->mech_type, &krb5_mechanism.mech_type) && + !g_OID_equal(uctx->mech_type, &krb5_mechanism_old.mech_type)) + return GSS_S_BAD_MECH; + return gss_krb5int_get_tkt_flags(minor_status, uctx->internal_ctx_id, + ticket_flags); +} + +OM_uint32 KRB5_CALLCONV +gss_krb5_copy_ccache( + OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + krb5_ccache out_ccache) +{ + gss_union_cred_t ucred; + gss_cred_id_t mcred; + + ucred = (gss_union_cred_t)cred_handle; + + mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type); + if (mcred != GSS_C_NO_CREDENTIAL) + return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache); + + mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type); + if (mcred != GSS_C_NO_CREDENTIAL) + return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache); + + return GSS_S_DEFECTIVE_CREDENTIAL; +} + +/* XXX need to delete mechglue ctx too */ +OM_uint32 KRB5_CALLCONV +gss_krb5_export_lucid_sec_context( + OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **kctx) +{ + gss_union_ctx_id_t uctx; + + uctx = (gss_union_ctx_id_t)*context_handle; + if (!g_OID_equal(uctx->mech_type, &krb5_mechanism.mech_type) && + !g_OID_equal(uctx->mech_type, &krb5_mechanism_old.mech_type)) + return GSS_S_BAD_MECH; + return gss_krb5int_export_lucid_sec_context(minor_status, + &uctx->internal_ctx_id, + version, kctx); +} + +OM_uint32 KRB5_CALLCONV +gss_krb5_set_allowable_enctypes( + OM_uint32 *minor_status, + gss_cred_id_t cred, + OM_uint32 num_ktypes, + krb5_enctype *ktypes) +{ + gss_union_cred_t ucred; + gss_cred_id_t mcred; + + ucred = (gss_union_cred_t)cred; + mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type); + if (mcred != GSS_C_NO_CREDENTIAL) + return gss_krb5int_set_allowable_enctypes(minor_status, mcred, + num_ktypes, ktypes); + + mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type); + if (mcred != GSS_C_NO_CREDENTIAL) + return gss_krb5int_set_allowable_enctypes(minor_status, mcred, + num_ktypes, ktypes); + + return GSS_S_DEFECTIVE_CREDENTIAL; +} + +/* + * Glue routine for returning the mechanism-specific credential from a + * external union credential. + */ +/* SUNW15resync - in MIT 1.5, it's in g_glue.c (libgss) but we don't + want to link against libgss so we put it here since we need it in the mech */ +gss_cred_id_t +gssint_get_mechanism_cred(union_cred, mech_type) + gss_union_cred_t union_cred; + gss_OID mech_type; +{ + int i; + + if (union_cred == (gss_union_cred_t) GSS_C_NO_CREDENTIAL) + return GSS_C_NO_CREDENTIAL; + + for (i=0; i < union_cred->count; i++) { + if (g_OID_equal(mech_type, &union_cred->mechs_array[i])) + return union_cred->cred_array[i]; + } + return GSS_C_NO_CREDENTIAL; +} + + + +/* + * entry point for the gss layer, + * called "krb5_gss_initialize()" in MIT 1.2.1 + */ +/* SUNW15resync - this used to be in k5mech.c */ +gss_mechanism +gss_mech_initialize(oid) + const gss_OID oid; +{ + /* ensure that the requested oid matches our oid */ + if (oid == NULL || !g_OID_equal(oid, &krb5_mechanism.mech_type)) { + (void) syslog(LOG_INFO, "krb5mech: gss_mech_initialize: bad oid"); + return (NULL); + } + +#if 0 /* SUNW15resync - no longer needed(?) */ + if (krb5_gss_get_context(&(krb5_mechanism.context)) != + GSS_S_COMPLETE) + return (NULL); +#endif + + return (&krb5_mechanism); +} + diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/lucid_context.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/lucid_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,311 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * lib/gssapi/krb5/lucid_context.c + * + * Copyright 2004 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * lucid_context.c - Externalize a "lucid" security + * context from a krb5_gss_ctx_id_rec structure. + */ +#include "gssapiP_krb5.h" +#include "gssapi_krb5.h" + +/* + * Local routine prototypes + */ +static void +free_external_lucid_ctx_v1( + gss_krb5_lucid_context_v1_t *ctx); + +static void +free_lucid_key_data( + gss_krb5_lucid_key_t *key); + +static krb5_error_code +copy_keyblock_to_lucid_key( + krb5_keyblock *k5key, + gss_krb5_lucid_key_t *lkey); + +static krb5_error_code +make_external_lucid_ctx_v1( + krb5_gss_ctx_id_rec * gctx, + unsigned int version, + void **out_ptr); + + +/* + * Exported routines + */ + +OM_uint32 KRB5_CALLCONV +gss_krb5int_export_lucid_sec_context( + OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **kctx) +{ + krb5_error_code kret = 0; + OM_uint32 retval; + krb5_gss_ctx_id_t ctx; + void *lctx = NULL; + + /* Assume failure */ + retval = GSS_S_FAILURE; + *minor_status = 0; + + if (kctx) + *kctx = NULL; + else { + kret = EINVAL; + goto error_out; + } + + if (!kg_validate_ctx_id(*context_handle)) { + kret = (OM_uint32) G_VALIDATE_FAILED; + retval = GSS_S_NO_CONTEXT; + goto error_out; + } + + ctx = (krb5_gss_ctx_id_t) *context_handle; + if (kret) + goto error_out; + + /* Externalize a structure of the right version */ + switch (version) { + case 1: + kret = make_external_lucid_ctx_v1((krb5_pointer)ctx, + version, &lctx); + break; + default: + kret = (OM_uint32) KG_LUCID_VERSION; + break; + } + + if (kret) + goto error_out; + + /* Success! Record the context and return the buffer */ + if (! kg_save_lucidctx_id((void *)lctx)) { + kret = G_VALIDATE_FAILED; + goto error_out; + } + + *kctx = lctx; + *minor_status = 0; + retval = GSS_S_COMPLETE; + + /* Clean up the context state (it is an error for + * someone to attempt to use this context again) + */ + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *context_handle = GSS_C_NO_CONTEXT; + + return (retval); + +error_out: + if (*minor_status == 0) + *minor_status = (OM_uint32) kret; + return(retval); +} + +/* + * Frees the storage associated with an + * exported lucid context structure. + */ +OM_uint32 KRB5_CALLCONV +gss_krb5_free_lucid_sec_context( + OM_uint32 *minor_status, + void *kctx) +{ + OM_uint32 retval; + krb5_error_code kret = 0; + int version; + + /* Assume failure */ + retval = GSS_S_FAILURE; + *minor_status = 0; + + if (!kctx) { + kret = EINVAL; + goto error_out; + } + + /* Verify pointer is valid lucid context */ + if (! kg_validate_lucidctx_id(kctx)) { + kret = G_VALIDATE_FAILED; + goto error_out; + } + + /* Determine version and call correct free routine */ + version = ((gss_krb5_lucid_context_version_t *)kctx)->version; + switch (version) { + case 1: + free_external_lucid_ctx_v1((gss_krb5_lucid_context_v1_t*) kctx); + break; + default: + kret = EINVAL; + break; + } + + if (kret) + goto error_out; + + /* Success! */ + (void)kg_delete_lucidctx_id(kctx); + *minor_status = 0; + retval = GSS_S_COMPLETE; + + return (retval); + +error_out: + if (*minor_status == 0) + *minor_status = (OM_uint32) kret; + return(retval); +} + +/* + * Local routines + */ + +static krb5_error_code +make_external_lucid_ctx_v1( + krb5_gss_ctx_id_rec * gctx, + unsigned int version, + void **out_ptr) +{ + gss_krb5_lucid_context_v1_t *lctx = NULL; + unsigned int bufsize = sizeof(gss_krb5_lucid_context_v1_t); + krb5_error_code retval; + + /* Allocate the structure */ + if ((lctx = xmalloc(bufsize)) == NULL) { + retval = ENOMEM; + goto error_out; + } + + memset(lctx, 0, bufsize); + + lctx->version = 1; + lctx->initiate = gctx->initiate ? 1 : 0; + lctx->endtime = gctx->endtime; + lctx->send_seq = gctx->seq_send; + lctx->recv_seq = gctx->seq_recv; + lctx->protocol = gctx->proto; + /* gctx->proto == 0 ==> rfc1964-style key information + gctx->proto == 1 ==> cfx-style (draft-ietf-krb-wg-gssapi-cfx-07) keys */ + if (gctx->proto == 0) { + lctx->rfc1964_kd.sign_alg = gctx->signalg; + lctx->rfc1964_kd.seal_alg = gctx->sealalg; + /* Copy key */ + if ((retval = copy_keyblock_to_lucid_key(gctx->subkey, + &lctx->rfc1964_kd.ctx_key))) + goto error_out; + } + else if (gctx->proto == 1) { + /* Copy keys */ + /* (subkey is always present, either a copy of the kerberos + session key or a subkey) */ + if ((retval = copy_keyblock_to_lucid_key(gctx->subkey, + &lctx->cfx_kd.ctx_key))) + goto error_out; + if (gctx->have_acceptor_subkey) { + if ((retval = copy_keyblock_to_lucid_key(gctx->enc, + &lctx->cfx_kd.acceptor_subkey))) + goto error_out; + lctx->cfx_kd.have_acceptor_subkey = 1; + } + } + else { + return EINVAL; /* XXX better error code? */ + } + + /* Success! */ + *out_ptr = lctx; + return 0; + +error_out: + if (lctx) { + free_external_lucid_ctx_v1(lctx); + } + return retval; + +} + +/* Copy the contents of a krb5_keyblock to a gss_krb5_lucid_key_t structure */ +static krb5_error_code +copy_keyblock_to_lucid_key( + krb5_keyblock *k5key, + gss_krb5_lucid_key_t *lkey) +{ + if (!k5key || !k5key->contents || k5key->length == 0) + return EINVAL; + + memset(lkey, 0, sizeof(gss_krb5_lucid_key_t)); + + /* Allocate storage for the key data */ + if ((lkey->data = xmalloc(k5key->length)) == NULL) { + return ENOMEM; + } + memcpy(lkey->data, k5key->contents, k5key->length); + lkey->length = k5key->length; + lkey->type = k5key->enctype; + + return 0; +} + + +/* Free any storage associated with a gss_krb5_lucid_key_t structure */ +static void +free_lucid_key_data( + gss_krb5_lucid_key_t *key) +{ + if (key) { + if (key->data && key->length) { + memset(key->data, 0, key->length); + xfree(key->data); + memset(key, 0, sizeof(gss_krb5_lucid_key_t)); + } + } +} +/* Free any storage associated with a gss_krb5_lucid_context_v1 structure */ +static void +free_external_lucid_ctx_v1( + gss_krb5_lucid_context_v1_t *ctx) +{ + if (ctx) { + if (ctx->protocol == 0) { + free_lucid_key_data(&ctx->rfc1964_kd.ctx_key); + } + if (ctx->protocol == 1) { + free_lucid_key_data(&ctx->cfx_kd.ctx_key); + if (ctx->cfx_kd.have_acceptor_subkey) + free_lucid_key_data(&ctx->cfx_kd.acceptor_subkey); + } + xfree(ctx); + ctx = NULL; + } +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/oid_ops.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/oid_ops.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,504 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * lib/gssapi/generic/oid_ops.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs + */ + +#include "mglueP.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include + +OM_uint32 +generic_gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + if (minor_status) + *minor_status = 0; + + if (*oid == GSS_C_NO_OID) + return(GSS_S_COMPLETE); + + /* + * The V2 API says the following! + * + * gss_release_oid[()] will recognize any of the GSSAPI's own OID values, + * and will silently ignore attempts to free these OIDs; for other OIDs + * it will call the C free() routine for both the OID data and the + * descriptor. This allows applications to freely mix their own heap- + * allocated OID values with OIDs returned by GSS-API. + */ + + /* + * We use the official OID definitions instead of the unofficial OID + * defintions. But we continue to support the unofficial OID + * gss_nt_service_name just in case if some gss applications use + * the old OID. + */ + + if ((*oid != GSS_C_NT_USER_NAME) && + (*oid != GSS_C_NT_MACHINE_UID_NAME) && + (*oid != GSS_C_NT_STRING_UID_NAME) && + (*oid != GSS_C_NT_HOSTBASED_SERVICE) && + (*oid != GSS_C_NT_ANONYMOUS) && + (*oid != GSS_C_NT_EXPORT_NAME) && + (*oid != gss_nt_service_name)) { + free((*oid)->elements); + free(*oid); + } + *oid = GSS_C_NO_OID; + return(GSS_S_COMPLETE); +} + +OM_uint32 +generic_gss_copy_oid(minor_status, oid, new_oid) + OM_uint32 *minor_status; + gss_OID_desc * const oid; + gss_OID *new_oid; +{ + gss_OID p; + + *minor_status = 0; + + p = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!p) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + p->length = oid->length; + p->elements = malloc(p->length); + if (!p->elements) { + free(p); + return GSS_S_FAILURE; + } + memcpy(p->elements, oid->elements, p->length); + *new_oid = p; + return(GSS_S_COMPLETE); +} + + +OM_uint32 +generic_gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + *minor_status = 0; + + if ((*oid_set = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)))) { + memset(*oid_set, 0, sizeof(gss_OID_set_desc)); + return(GSS_S_COMPLETE); + } + else { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } +} + +OM_uint32 +generic_gss_add_oid_set_member(minor_status, member_oid, oid_set) + OM_uint32 *minor_status; + gss_OID_desc * const member_oid; + gss_OID_set *oid_set; +{ + gss_OID elist; + gss_OID lastel; + + *minor_status = 0; + + if (member_oid == NULL || member_oid->length == 0 || + member_oid->elements == NULL) + return (GSS_S_CALL_INACCESSIBLE_READ); + + elist = (*oid_set)->elements; + /* Get an enlarged copy of the array */ + if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * + sizeof(gss_OID_desc)))) { + /* Copy in the old junk */ + if (elist) + memcpy((*oid_set)->elements, + elist, + ((*oid_set)->count * sizeof(gss_OID_desc))); + + /* Duplicate the input element */ + lastel = &(*oid_set)->elements[(*oid_set)->count]; + if ((lastel->elements = + (void *) malloc((size_t) member_oid->length))) { + /* Success - copy elements */ + memcpy(lastel->elements, member_oid->elements, + (size_t) member_oid->length); + /* Set length */ + lastel->length = member_oid->length; + + /* Update count */ + (*oid_set)->count++; + if (elist) + free(elist); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else + free((*oid_set)->elements); + } + /* Failure - restore old contents of list */ + (*oid_set)->elements = elist; + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_test_oid_set_member(minor_status, member, set, present) + OM_uint32 *minor_status; + gss_OID_desc * const member; + gss_OID_set set; + int *present; +{ + OM_uint32 i; + int result; + + *minor_status = 0; + + if (member == NULL || set == NULL) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if (present == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + result = 0; + for (i=0; icount; i++) { + if ((set->elements[i].length == member->length) && + !memcmp(set->elements[i].elements, + member->elements, + (size_t) member->length)) { + result = 1; + break; + } + } + *present = result; + return(GSS_S_COMPLETE); +} + +/* + * OID<->string routines. These are uuuuugly. + */ +OM_uint32 +generic_gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID_desc * const oid; + gss_buffer_t oid_str; +{ + char numstr[128]; + OM_uint32 number; + int numshift; + OM_uint32 string_length; + OM_uint32 i; + unsigned char *cp; + char *bp; + + *minor_status = 0; + + if (oid == NULL || oid->length == 0 || oid->elements == NULL) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if (oid_str == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + /* Decoded according to krb5/gssapi_krb5.c */ + + /* First determine the size of the string */ + string_length = 0; + number = 0; + numshift = 0; + cp = (unsigned char *) oid->elements; + number = (unsigned long) cp[0]; + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number/40); + string_length += strlen(numstr); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number%40); + string_length += strlen(numstr); + for (i=1; ilength; i++) { + if ((OM_uint32) (numshift+7) < (sizeof (OM_uint32)*8)) {/* XXX */ + number = (number << 7) | (cp[i] & 0x7f); + numshift += 7; + } + else { + return(GSS_S_FAILURE); + } + if ((cp[i] & 0x80) == 0) { + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number); + string_length += strlen(numstr); + number = 0; + numshift = 0; + } + } + /* + * If we get here, we've calculated the length of "n n n ... n ". Add 4 + * here for "{ " and "}\0". + */ + string_length += 4; + if ((bp = (char *) malloc(string_length))) { + strcpy(bp, "{ "); + number = (OM_uint32) cp[0]; + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number/40); + strcat(bp, numstr); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number%40); + strcat(bp, numstr); + number = 0; + cp = (unsigned char *) oid->elements; + for (i=1; ilength; i++) { + number = (number << 7) | (cp[i] & 0x7f); + if ((cp[i] & 0x80) == 0) { + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number); + strcat(bp, numstr); + number = 0; + } + } + strcat(bp, "}"); + oid_str->length = strlen(bp)+1; + oid_str->value = (void *) bp; + return(GSS_S_COMPLETE); + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + unsigned char *cp, *bp, *startp; + int brace; + long numbuf; + long onumbuf; + OM_uint32 nbytes; + int index; + unsigned char *op; + + *minor_status = 0; + + if (GSS_EMPTY_BUFFER(oid_str)) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if (oid == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + brace = 0; + bp = oid_str->value; + cp = bp; + /* Skip over leading space */ + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (*bp == '{') { + brace = 1; + bp++; + } + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + startp = bp; + nbytes = 0; + + /* + * The first two numbers are chewed up by the first octet. + */ + if (sscanf((char *)bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (sscanf((char *)bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && + (isspace(*bp) || *bp == '.')) + bp++; + nbytes++; + while (isdigit(*bp)) { + if (sscanf((char *)bp, "%ld", &numbuf) != 1) { + return(GSS_S_FAILURE); + } + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && + (isspace(*bp) || *bp == '.')) + bp++; + } + if (brace && (*bp != '}')) { + return(GSS_S_FAILURE); + } + + /* + * Phew! We've come this far, so the syntax is good. + */ + if ((*oid = (gss_OID) malloc(sizeof(gss_OID_desc)))) { + if (((*oid)->elements = (void *) malloc(nbytes))) { + (*oid)->length = nbytes; + op = (unsigned char *) (*oid)->elements; + bp = startp; + (void) sscanf((char *)bp, "%ld", &numbuf); + while (isdigit(*bp)) + bp++; + while (isspace(*bp) || *bp == '.') + bp++; + onumbuf = 40*numbuf; + (void) sscanf((char *)bp, "%ld", &numbuf); + onumbuf += numbuf; + *op = (unsigned char) onumbuf; + op++; + while (isdigit(*bp)) + bp++; + while (isspace(*bp) || *bp == '.') + bp++; + while (isdigit(*bp)) { + (void) sscanf((char *)bp, "%ld", &numbuf); + nbytes = 0; + /* Have to fill in the bytes msb-first */ + onumbuf = numbuf; + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + numbuf = onumbuf; + op += nbytes; + index = -1; + while (numbuf) { + op[index] = (unsigned char) numbuf & 0x7f; + if (index != -1) + op[index] |= 0x80; + index--; + numbuf >>= 7; + } + while (isdigit(*bp)) + bp++; + while (isspace(*bp) || *bp == '.') + bp++; + } + return(GSS_S_COMPLETE); + } + else { + free(*oid); + *oid = GSS_C_NO_OID; + } + } + return(GSS_S_FAILURE); +} + +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +OM_uint32 +gssint_copy_oid_set( + OM_uint32 *minor_status, + const gss_OID_set_desc * const oidset, + gss_OID_set *new_oidset + ) +{ + gss_OID_set_desc *copy; + OM_uint32 minor = 0; + OM_uint32 major = GSS_S_COMPLETE; + OM_uint32 index; + + if (minor_status) + *minor_status = 0; + + if (oidset == NULL) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if (new_oidset == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + *new_oidset = NULL; + + if ((copy = (gss_OID_set_desc *) calloc(1, sizeof (*copy))) == NULL) { + major = GSS_S_FAILURE; + goto done; + } + + if ((copy->elements = (gss_OID_desc *) + calloc(oidset->count, sizeof (*copy->elements))) == NULL) { + major = GSS_S_FAILURE; + goto done; + } + copy->count = oidset->count; + + for (index = 0; index < copy->count; index++) { + gss_OID_desc *out = ©->elements[index]; + gss_OID_desc *in = &oidset->elements[index]; + + if ((out->elements = (void *) malloc(in->length)) == NULL) { + major = GSS_S_FAILURE; + goto done; + } + (void) memcpy(out->elements, in->elements, in->length); + out->length = in->length; + } + + *new_oidset = copy; +done: + if (major != GSS_S_COMPLETE) { + (void) gss_release_oid_set(&minor, ©); + } + + return (major); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/pname_to_uid.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/pname_to_uid.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/pname_to_uid.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -33,29 +33,32 @@ * GSS_S_FAILURE is returned on failure. */ OM_uint32 -krb5_pname_to_uid(ctxt, minor, pname, uidOut) -void * ctxt; +krb5_pname_to_uid(minor, pname, uidOut) OM_uint32 *minor; const gss_name_t pname; uid_t *uidOut; { - krb5_context context = (krb5_context)ctxt; + krb5_context context; char lname[256]; struct passwd *pw; krb5_error_code stat; - mutex_lock(&krb5_mutex); if (! kg_validate_name(pname)) { - mutex_unlock(&krb5_mutex); *minor = (OM_uint32) G_VALIDATE_FAILED; return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } + stat = krb5_init_context(&context); + if (stat) { + *minor = stat; + return GSS_S_FAILURE; + } + stat = krb5_aname_to_localname(context, (krb5_principal) pname, sizeof (lname), lname); - mutex_unlock(&krb5_mutex); - + krb5_free_context(context); + context = NULL; if (stat) return (GSS_S_FAILURE); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,63 +22,45 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: process_context_token.c,v 1.10 1996/07/22 20:34:23 marc Exp $ + * $Id: process_context_token.c 16171 2004-03-15 17:45:01Z raeburn $ */ OM_uint32 -krb5_gss_process_context_token(ct, minor_status, context_handle, +krb5_gss_process_context_token(minor_status, context_handle, token_buffer) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t token_buffer; { - krb5_context context; krb5_gss_ctx_id_rec *ctx; OM_uint32 majerr; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ct; - /* validate the context handle */ if (! kg_validate_ctx_id(context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } - ctx = (krb5_gss_ctx_id_rec *) context_handle; + ctx = (krb5_gss_ctx_id_t) context_handle; if (! ctx->established) { *minor_status = KG_CTX_INCOMPLETE; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } /* "unseal" the token */ - if (GSS_ERROR(majerr = kg_unseal(context, minor_status, (gss_ctx_id_t)ctx, + if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle, token_buffer, GSS_C_NO_BUFFER, NULL, NULL, - KG_TOK_DEL_CTX))) { - mutex_unlock(&krb5_mutex); + KG_TOK_DEL_CTX))) return(majerr); - } /* that's it. delete the context */ - majerr = krb5_gss_delete_sec_context_no_lock(context, minor_status, - &context_handle, GSS_C_NO_BUFFER); - mutex_unlock(&krb5_mutex); - return(majerr); + return(krb5_gss_delete_sec_context(minor_status, &context_handle, + GSS_C_NO_BUFFER)); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/rel_buffer.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_buffer.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_buffer.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,15 +1,32 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + /* - * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * glue routine for gss_release_buffer */ -#include +#include "gssapiP_generic.h" #include #ifdef HAVE_STDLIB_H @@ -30,8 +47,7 @@ if (buffer == GSS_C_NO_BUFFER) return(GSS_S_COMPLETE); - if ((buffer->length) && - (buffer->value)) { + if (buffer->value) { free(buffer->value); buffer->length = 0; buffer->value = NULL; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/rel_cred.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,55 +22,44 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#include "gssapiP_krb5.h" -OM_uint32 -krb5_gss_release_cred(ctx, minor_status, cred_handle) - void *ctx; +OM_uint32 +krb5_gss_release_cred(minor_status, cred_handle) OM_uint32 *minor_status; gss_cred_id_t *cred_handle; { - OM_uint32 status; - - mutex_lock(&krb5_mutex); - status = krb5_gss_release_cred_no_lock(ctx, minor_status, cred_handle); - mutex_unlock(&krb5_mutex); - return(status); -} - -OM_uint32 -krb5_gss_release_cred_no_lock(ctx, minor_status, cred_handle) - void *ctx; - OM_uint32 *minor_status; - gss_cred_id_t *cred_handle; -{ - krb5_context context = ctx; + krb5_context context; krb5_gss_cred_id_t cred; krb5_error_code code1, code2, code3; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif + code1 = krb5_gss_init_context(&context); + if (code1) { + *minor_status = code1; + return GSS_S_FAILURE; + } - if (*cred_handle == GSS_C_NO_CREDENTIAL) - { - /* Solaris Kerberos: the followin function does nothing */ - return(kg_release_defcred(minor_status)); + if (*cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + krb5_free_context(context); + return(GSS_S_COMPLETE); } if (! kg_delete_cred_id(*cred_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_NO_CRED); } cred = (krb5_gss_cred_id_t)*cred_handle; + k5_mutex_destroy(&cred->lock); + /* ignore error destroying mutex */ + + if (cred->ccache) { /* + * Solaris Kerberos * If the ccache is a MEMORY ccache then this credential handle * should be the only way to get to it, at least until the advent * of a GSS_Duplicate_cred() (which is needed and may well be @@ -101,7 +85,12 @@ code3 = 0; if (cred->princ) krb5_free_principal(context, cred->princ); + + if (cred->req_enctypes) + free(cred->req_enctypes); + xfree(cred); + krb5_free_context(context); *cred_handle = NULL; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/rel_name.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,13 +1,8 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +12,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -27,46 +22,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" OM_uint32 -krb5_gss_release_name(ctx, minor_status, input_name) - void *ctx; +krb5_gss_release_name(minor_status, input_name) OM_uint32 *minor_status; gss_name_t *input_name; { - OM_uint32 rc; - - mutex_lock(&krb5_mutex); - rc = krb5_gss_release_name_no_lock(ctx, minor_status, input_name); - mutex_unlock(&krb5_mutex); - return (rc); -} + krb5_context context; + krb5_error_code code; -OM_uint32 -krb5_gss_release_name_no_lock(ctx, minor_status, input_name) - void *ctx; - OM_uint32 *minor_status; - gss_name_t *input_name; -{ - krb5_context context = ctx; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } if (! kg_validate_name(*input_name)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; + krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } (void)kg_delete_name(*input_name); krb5_free_principal(context, (krb5_principal) *input_name); + krb5_free_context(context); *input_name = (gss_name_t) NULL; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -23,7 +18,10 @@ * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * @@ -32,7 +30,12 @@ /* * rel_oid.c - Release an OID. */ -#include +#include "gssapiP_krb5.h" +#include "mglueP.h" + +OM_uint32 krb5_gss_internal_release_oid (OM_uint32 *, /* minor_status */ + gss_OID * /* oid */ + ); OM_uint32 krb5_gss_release_oid(minor_status, oid) @@ -48,9 +51,9 @@ * descriptor. This allows applications to freely mix their own heap- * allocated OID values with OIDs returned by GSS-API. */ - if (krb5_gss_internal_release_oid(NULL, minor_status, oid) != GSS_S_COMPLETE) { + if (krb5_gss_internal_release_oid(minor_status, oid) != GSS_S_COMPLETE) { /* Pawn it off on the generic routine */ - return(gss_release_oid(minor_status, oid)); + return(generic_gss_release_oid(minor_status, oid)); } else { *oid = GSS_C_NO_OID; @@ -59,10 +62,8 @@ } } -/*ARGSUSED*/ OM_uint32 -krb5_gss_internal_release_oid(ct, minor_status, oid) - void *ct; +krb5_gss_internal_release_oid(minor_status, oid) OM_uint32 *minor_status; gss_OID *oid; { @@ -71,9 +72,9 @@ * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize. */ - if ((*oid != gss_mech_krb5_v2) && - (*oid != gss_mech_krb5) && + if ((*oid != gss_mech_krb5) && (*oid != gss_mech_krb5_old) && + (*oid != gss_mech_krb5_wrong) && (*oid != gss_nt_krb5_name) && (*oid != gss_nt_krb5_principal)) { /* We don't know about this OID */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid_set.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid_set.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid_set.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,15 +1,32 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + /* - * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * glue routine for gss_release_oid_set */ -#include +#include "gssapiP_generic.h" #include #ifdef HAVE_STDLIB_H @@ -39,6 +56,6 @@ free(*set); *set = GSS_C_NULL_OID_SET; - + return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/set_allowable_enctypes.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/set_allowable_enctypes.c Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,135 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * lib/gssapi/krb5/set_allowable_enctypes.c + * + * Copyright 2004 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * krb5_gss_set_allowable_enctypes() + */ + +/* + * gss_krb5_set_allowable_enctypes + * + * This function may be called by a context initiator after calling + * gss_acquire_cred(), but before calling gss_init_sec_context(), + * to restrict the set of enctypes which will be negotiated during + * context establishment to those in the provided array. + * + * 'cred_handle' must be a valid credential handle obtained via + * gss_acquire_cred(). It may not be GSS_C_NO_CREDENTIAL. + * gss_acquire_cred() may be called with GSS_C_NO_CREDENTIAL + * to get a handle to the default credential. + * + * The purpose of this function is to limit the keys that may + * be exported via gss_krb5_export_lucid_sec_context(); thus it + * should limit the enctypes of all keys that will be needed + * after the security context has been established. + * (i.e. context establishment may use a session key with a + * stronger enctype than in the provided array, however a + * subkey must be established within the enctype limits + * established by this function.) + * + */ + +#include "gssapiP_krb5.h" +#ifdef HAVE_STRING_H +#include +#else +#include +#endif +#include "gssapi_krb5.h" + +OM_uint32 KRB5_CALLCONV +gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + OM_uint32 num_ktypes, + krb5_enctype *ktypes) +{ + int i; + krb5_enctype * new_ktypes; + OM_uint32 major_status; + krb5_gss_cred_id_t cred; + krb5_error_code kerr = 0; + OM_uint32 temp_status; + + /* Assume a failure */ + *minor_status = 0; + major_status = GSS_S_FAILURE; + + /* verify and valildate cred handle */ + if (cred_handle == GSS_C_NO_CREDENTIAL) { + kerr = KRB5_NOCREDS_SUPPLIED; + goto error_out; + } + major_status = krb5_gss_validate_cred(&temp_status, cred_handle); + if (GSS_ERROR(major_status)) { + kerr = temp_status; + goto error_out; + } + cred = (krb5_gss_cred_id_t) cred_handle; + + if (ktypes) { + for (i = 0; i < num_ktypes && ktypes[i]; i++) { + if (!krb5_c_valid_enctype(ktypes[i])) { + kerr = KRB5_PROG_ETYPE_NOSUPP; + goto error_out; + } + } + } else { + kerr = k5_mutex_lock(&cred->lock); + if (kerr) + goto error_out; + if (cred->req_enctypes) + free(cred->req_enctypes); + cred->req_enctypes = NULL; + k5_mutex_unlock(&cred->lock); + return GSS_S_COMPLETE; + } + + /* Copy the requested ktypes into the cred structure */ + if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * (i + 1)))) { + memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i); + new_ktypes[i] = 0; /* "null-terminate" the list */ + } + else { + kerr = ENOMEM; + goto error_out; + } + kerr = k5_mutex_lock(&cred->lock); + if (kerr) { + free(new_ktypes); + goto error_out; + } + if (cred->req_enctypes) + free(cred->req_enctypes); + cred->req_enctypes = new_ktypes; + k5_mutex_unlock(&cred->lock); + + /* Success! */ + return GSS_S_COMPLETE; + +error_out: + *minor_status = kerr; + return(major_status); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,28 +1,99 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #pragma ident "%Z%%M% %I% %E% SMI" -#include +/* + * lib/gssapi/krb5/set_ccache.c + * + * Copyright 1999, 2003 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Set ccache name used by gssapi, and optionally obtain old ccache + * name. Caller should not free returned name. + */ -GSS_DLLIMP OM_uint32 KRB5_CALLCONV +#include +#include "gssapiP_krb5.h" +#include "gss_libinit.h" + +OM_uint32 KRB5_CALLCONV gss_krb5_ccache_name(minor_status, name, out_name) OM_uint32 *minor_status; const char *name; const char **out_name; { - krb5_context context; - krb5_error_code retval; - OM_uint32 foo_stat; + char *old_name = NULL; + OM_uint32 err = 0; + OM_uint32 minor = 0; + char *gss_out_name; + + err = gssint_initialize_library(); + if (err) { + *minor_status = err; + return GSS_S_FAILURE; + } + + gss_out_name = k5_getspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME); - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return (GSS_S_FAILURE); + if (out_name) { + const char *tmp_name = NULL; + + if (!err) { + kg_get_ccache_name (&err, &tmp_name); + } + if (!err) { + old_name = gss_out_name; + gss_out_name = (char *)tmp_name; + } + } + /* If out_name was NULL, we keep the same gss_out_name value, and + don't free up any storage (leave old_name NULL). */ - if (out_name) - *out_name = krb5_cc_default_name(context); + if (!err) + kg_set_ccache_name (&err, name); + + minor = k5_setspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, gss_out_name); + if (minor) { + /* Um. Now what? */ + if (err == 0) { + err = minor; + } + free(gss_out_name); + gss_out_name = NULL; + } - retval = krb5_cc_set_default_name(context, name); - if (retval) { - *minor_status = retval; - return GSS_S_FAILURE; - } - kg_release_defcred(&foo_stat); - return GSS_S_COMPLETE; + if (!err) { + if (out_name) { + *out_name = gss_out_name; + } + } + + if (old_name != NULL) { + free (old_name); + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/store_cred.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/store_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/store_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -87,33 +87,9 @@ } OM_uint32 -krb5_gss_store_cred(ct, minor_status, input_cred, cred_usage, desired_mech, - overwrite_cred, default_cred, elements_stored, - cred_usage_stored) -void *ct; -OM_uint32 *minor_status; -const gss_cred_id_t input_cred; -gss_cred_usage_t cred_usage; -gss_OID desired_mech; -OM_uint32 overwrite_cred; -OM_uint32 default_cred; -gss_OID_set *elements_stored; -gss_cred_usage_t *cred_usage_stored; -{ - OM_uint32 ret; - mutex_lock(&krb5_mutex); - ret = krb5_gss_store_cred_no_lock(ct, minor_status, input_cred, - cred_usage, desired_mech, overwrite_cred, default_cred, - elements_stored, cred_usage_stored); - mutex_unlock(&krb5_mutex); - return (ret); -} - -OM_uint32 -krb5_gss_store_cred_no_lock(ct, minor_status, input_cred, cred_usage, +krb5_gss_store_cred(minor_status, input_cred, cred_usage, desired_mech, overwrite_cred, default_cred, elements_stored, cred_usage_stored) -void *ct; OM_uint32 *minor_status; const gss_cred_id_t input_cred; gss_cred_usage_t cred_usage; @@ -124,7 +100,7 @@ gss_cred_usage_t *cred_usage_stored; { OM_uint32 maj, maj2, min; - krb5_context ctx = (krb5_context)ct; + krb5_context ctx = NULL; krb5_gss_cred_id_t cred = (krb5_gss_cred_id_t)input_cred; krb5_gss_cred_id_t cur_cred = (krb5_gss_cred_id_t)GSS_C_NO_CREDENTIAL; gss_OID_set desired_mechs = GSS_C_NULL_OID_SET; @@ -162,8 +138,14 @@ if (cred_usage == GSS_C_BOTH) cred_usage = GSS_C_INITIATE; + min = krb5_gss_init_context(&ctx); + if (min) { + *minor_status = min; + return (GSS_S_FAILURE); + } + /* * Find out the name, lifetime and cred usage of the input cred */ - maj = krb5_gss_inquire_cred_no_lock(ctx, minor_status, input_cred, + maj = krb5_gss_inquire_cred(minor_status, input_cred, &in_name, &in_time_rec, &in_usage, NULL); if (GSS_ERROR(maj)) goto cleanup; @@ -205,7 +187,7 @@ * then we must be careful not to overwrite an existing * unexpired credential. */ - maj2 = krb5_gss_acquire_cred_no_lock(ctx, &min, + maj2 = krb5_gss_acquire_cred(&min, (default_cred) ? GSS_C_NO_NAME : in_name, 0, desired_mechs, cred_usage, (gss_cred_id_t *)&cur_cred, NULL, &cur_time_rec); @@ -245,10 +227,13 @@ if (desired_mechs != GSS_C_NULL_OID_SET) (void) gss_release_oid_set(&min, &desired_mechs); if (cur_cred != (krb5_gss_cred_id_t)GSS_C_NO_CREDENTIAL) - (void) krb5_gss_release_cred_no_lock(ctx, &min, + (void) krb5_gss_release_cred(&min, (gss_cred_id_t *)&cur_cred); if (in_name != GSS_C_NO_NAME) - (void) krb5_gss_release_name_no_lock(ctx, &min, &in_name); + (void) krb5_gss_release_name(&min, &in_name); + + if (ctx) + krb5_free_context(ctx); return (maj); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/util_buffer.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/util_buffer.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/util_buffer.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,11 +1,6 @@ #pragma ident "%Z%%M% %I% %E% SMI" /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -28,10 +23,10 @@ */ /* - * $Id: util_buffer.c,v 1.6 1996/07/22 20:33:19 marc Exp $ + * $Id: util_buffer.c 11001 1998-10-30 02:56:35Z marc $ */ -#include +#include "gssapiP_generic.h" #include /* return nonzero on success, 0 on failure diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/util_cksum.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/util_cksum.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/util_cksum.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,10 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -21,15 +27,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * $Id: util_cksum.c,v 1.14.6.1 2000/04/22 03:01:36 raeburn Exp $ - */ - -#include +#include "gssapiP_krb5.h" +#ifdef HAVE_MEMORY_H #include +#endif /* Checksumming the channel bindings always uses plain MD5. */ -/*ARGSUSED*/ krb5_error_code kg_checksum_channel_bindings(context, cb, cksum, bigend) krb5_context context; @@ -37,14 +40,17 @@ krb5_checksum *cksum; int bigend; { - int len; - char *buf, *ptr; + size_t len; + char *buf = 0; + char *ptr; size_t sumlen; krb5_data plaind; krb5_error_code code; + void *temp; - /* initialize the the cksum and allocate the contents buffer */ - if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + /* initialize the the cksum */ + code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen); + if (code) return(code); cksum->checksum_type = CKSUMTYPE_RSA_MD5; @@ -86,15 +92,46 @@ plaind.length = len; plaind.data = buf; - if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, - &plaind, cksum)) { - xfree(cksum->contents); - xfree(buf); - return(code); +#if 0 + /* + * SUNW15resync + * MIT 1.5-6 seems/is wrong here in 2 ways + * - why free then alloc contents again? + * - calling krb5_free_checksum_contents results in cksum->length + * getting set to 0 which causes ftp to fail + * so lets stick w/oldey-but-goodey code. + */ + code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, + &plaind, cksum); + if (code) + goto cleanup; + + if ((temp = xmalloc(cksum->length)) == NULL) { + krb5_free_checksum_contents(context, cksum); + code = ENOMEM; + goto cleanup; } + memcpy(temp, cksum->contents, cksum->length); + krb5_free_checksum_contents(context, cksum); + cksum->contents = (krb5_octet *)temp; + /* SUNW15resync - need to reset cksum->length here */ + /* success */ + cleanup: + if (buf) + xfree(buf); +#endif /* 0 */ - xfree(buf); - return(0); + if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, + &plaind, cksum)) { + xfree(cksum->contents); /* SUNW15resync -just in case not already free */ + xfree(buf); + return(code); + } + + /* success */ + + xfree(buf); + return code; } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/util_localhost.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/util_localhost.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/util_localhost.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -7,7 +7,7 @@ /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -17,7 +17,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -28,20 +28,16 @@ */ /* - * $Id: util_localhost.c,v 1.1 1996/04/12 00:39:38 marc Exp $ + * $Id: util_localhost.c 7797 1996-04-12 00:40:24Z marc $ */ /* This file could be OS specific */ -/* - * Solaris Kerberos: the MAXHOSTNAMELEN is defined in not - * in , and gethostname requires - */ -#include -#include -#include +#include -#include +#include "gssapiP_generic.h" +#include /* SUNW15resync */ +#include /* SUNW15resync */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/gss_mechs/mech_krb5/mech/utl_nohash_validate.c --- a/usr/src/lib/gss_mechs/mech_krb5/mech/utl_nohash_validate.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/utl_nohash_validate.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,5 @@ #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1990,1994 by the Massachusetts Institute of Technology. * All Rights Reserved. @@ -15,7 +16,10 @@ * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * @@ -25,7 +29,7 @@ * stub functions for those without the hash library. */ -#include +#include "gssapiP_generic.h" #ifdef HAVE_SYS_TYPES_H #include @@ -56,6 +60,12 @@ { return 1; } +int g_save_lucidctx_id(vdb, lctx) + void **vdb; + void *lctx; +{ + return 1; +} /* validate */ @@ -77,6 +87,12 @@ { return 1; } +int g_validate_lucidctx_id(vdb, lctx) + void **vdb; + void *lctx; +{ + return 1; +} /* delete */ @@ -98,4 +114,10 @@ { return 1; } +int g_delete_lucidctx_id(vdb, lctx) + void **vdb; + void *lctx; +{ + return 1; +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/krb5/kadm5/clnt/client_init.c --- a/usr/src/lib/krb5/kadm5/clnt/client_init.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/krb5/kadm5/clnt/client_init.c Fri Sep 14 15:01:24 2007 -0700 @@ -773,8 +773,7 @@ } else { input_name.value = service_name; input_name.length = strlen((char *)input_name.value) + 1; - gssstat = krb5_gss_import_name(handle->context, - &minor_stat, + gssstat = krb5_gss_import_name(&minor_stat, &input_name, (gss_OID)GSS_C_NT_HOSTBASED_SERVICE, (gss_name_t *)&creds.server); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/libgss/g_acquire_cred.c --- a/usr/src/lib/libgss/g_acquire_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/libgss/g_acquire_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -36,6 +36,7 @@ #include #include #include + /* local functions */ static gss_OID_set create_actual_mechs(const gss_OID, int); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/libgss/g_canon_name.c --- a/usr/src/lib/libgss/g_canon_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/libgss/g_canon_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -93,7 +92,7 @@ out_union->external_name = 0; /* Allocate the buffer for the user specified representation */ - if (__gss_create_copy_buffer(in_union->external_name, + if (gssint_create_copy_buffer(in_union->external_name, &out_union->external_name, 1)) goto allocation_failure; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/libgss/g_dup_name.c --- a/usr/src/lib/libgss/g_dup_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/libgss/g_dup_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -82,7 +81,7 @@ dest_union->external_name = 0; /* Now copy the external representaion */ - if (__gss_create_copy_buffer(src_union->external_name, + if (gssint_create_copy_buffer(src_union->external_name, &dest_union->external_name, 0)) goto allocation_failure; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/libgss/g_glue.c --- a/usr/src/lib/libgss/g_glue.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/libgss/g_glue.c Fri Sep 14 15:01:24 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -546,7 +545,7 @@ * Both space for the structure and the data is allocated. */ OM_uint32 -__gss_create_copy_buffer(srcBuf, destBuf, addNullChar) +gssint_create_copy_buffer(srcBuf, destBuf, addNullChar) const gss_buffer_t srcBuf; gss_buffer_t *destBuf; int addNullChar; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/lib/libgss/g_imp_name.c --- a/usr/src/lib/libgss/g_imp_name.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/lib/libgss/g_imp_name.c Fri Sep 14 15:01:24 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -94,7 +93,7 @@ * rule is when the name of GSS_C_NT_EXPORT_NAME type. If that is * the case, then we make it MN in this call. */ - major_status = __gss_create_copy_buffer(input_name_buffer, + major_status = gssint_create_copy_buffer(input_name_buffer, &union_name->external_name, 0); if (major_status != GSS_S_COMPLETE) { free(union_name); diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/include/mechglueP.h --- a/usr/src/uts/common/gssapi/include/mechglueP.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/include/mechglueP.h Fri Sep 14 15:01:24 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,33 +19,47 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * This header contains the private mechglue definitions. - */ - -#ifndef _MECHGLUEP_H -#define _MECHGLUEP_H - #pragma ident "%Z%%M% %I% %E% SMI" -#include -#include -#include +/* + * This header contains the private mechglue definitions. + * + */ + +#ifndef _GSS_MECHGLUEP_H +#define _GSS_MECHGLUEP_H -#ifdef __cplusplus -extern "C" { +#if 0 /* SUNW15resync - disable for sake of non-krb5 mechs */ +#include "autoconf.h" +#endif + +/* SUNW15resync */ +#ifndef GSS_DLLIMP +#define GSS_DLLIMP #endif -/* - * derived types for passing context and credential handles - * between gssd and kernel - */ -typedef unsigned int gssd_ctx_id_t; -typedef unsigned int gssd_cred_id_t; +#include /* SUNW15resync - mechglue.h in mit 1.5 */ +/* #include "gssapiP_generic.h" */ + +#ifdef _KERNEL +#include +#endif + +#ifndef g_OID_copy /* SUNW15resync */ +#define g_OID_copy(o1, o2) \ +do { \ + memcpy((o1)->elements, (o2)->elements, (o2)->length); \ + (o1)->length = (o2)->length; \ +} while (0) +#endif + +#define GSS_EMPTY_BUFFER(buf) ((buf) == NULL ||\ + (buf)->value == NULL || (buf)->length == 0) + /* * Array of context IDs typed by mechanism OID */ @@ -74,9 +87,9 @@ * Structure for holding list of mechanism-specific name types */ typedef struct gss_mech_spec_name_t { - gss_OID name_type; - gss_OID mech; - struct gss_mech_spec_name_t *next, *prev; + gss_OID name_type; + gss_OID mech; + struct gss_mech_spec_name_t *next, *prev; } gss_mech_spec_name_desc, *gss_mech_spec_name; /* @@ -96,11 +109,11 @@ typedef struct gss_union_cred_t { int count; gss_OID mechs_array; - gss_cred_id_t *cred_array; + gss_cred_id_t *cred_array; gss_union_cred_auxinfo auxinfo; } gss_union_cred_desc, *gss_union_cred_t; - +/* Solaris Kerberos */ typedef OM_uint32 (*gss_acquire_cred_with_password_sfct)( void *, /* context */ OM_uint32 *, /* minor_status */ @@ -114,23 +127,34 @@ OM_uint32 * /* time_rec */ /* */); + + +/********************************************************/ +/* The Mechanism Dispatch Table -- a mechanism needs to */ +/* define one of these and provide a function to return */ +/* it to initialize the GSSAPI library */ + /* * This is the definition of the mechs_array struct, which is used to * define the mechs array table. This table is used to indirectly * access mechanism specific versions of the gssapi routines through * the routines in the glue module (gssd_mech_glue.c) * - * This contains all of the functions defined in gssapi.h except for + * This contants all of the functions defined in gssapi.h except for * gss_release_buffer() and gss_release_oid_set(), which I am - * assuming, for now, to be equal across mechanisms. + * assuming, for now, to be equal across mechanisms. */ - + typedef struct gss_config { - gss_OID_desc mech_type; - void * context; +#if 0 /* Solaris Kerberos */ + OM_uint32 priority; + char * mechNameStr; +#endif + gss_OID_desc mech_type; + void * context; #ifdef _KERNEL - struct gss_config *next; - bool_t uses_kmod; + struct gss_config *next; + bool_t uses_kmod; #endif #ifndef _KERNEL @@ -495,6 +519,8 @@ #endif } *gss_mechanism; + + #ifndef _KERNEL /* This structure MUST NOT be used by any code outside libgss */ typedef struct gss_config_ext { @@ -502,6 +528,7 @@ } *gss_mechanism_ext; #endif /* _KERNEL */ + /* * In the user space we use a wrapper structure to encompass the * mechanism entry points. The wrapper contain the mechanism @@ -509,7 +536,6 @@ * layer. In the kernel we use only the gss_config strucutre because * the kernal does not cantain any of the extra gss-api specific data. */ -#ifndef _KERNEL typedef struct gss_mech_config { char *kmodName; /* kernel module name */ char *uLibName; /* user library name */ @@ -518,29 +544,30 @@ void *dl_handle; /* RTLD object handle for the mech */ gss_OID mech_type; /* mechanism oid */ gss_mechanism mech; /* mechanism initialization struct */ - gss_mechanism_ext mech_ext; /* extensions */ +#ifndef _KERNEL + gss_mechanism_ext mech_ext; /* Solaris extensions */ +#endif /* _KERNEL */ struct gss_mech_config *next; /* next element in the list */ } *gss_mech_info; -#endif + +/********************************************************/ +/* Internal mechglue routines */ -#ifndef _KERNEL -/* - * Internal mechglue routines - */ - +/* SUNW15resync - Solaris versions - replace w/mit ones? */ gss_mechanism __gss_get_mechanism(const gss_OID); +#ifndef _KERNEL gss_mechanism_ext __gss_get_mechanism_ext(const gss_OID); +#endif /* _KERNEL */ char *__gss_get_kmodName(const gss_OID); char *__gss_get_modOptions(const gss_OID); OM_uint32 __gss_import_internal_name(OM_uint32 *, const gss_OID, - gss_union_name_t, gss_name_t *); + gss_union_name_t, gss_name_t *); OM_uint32 __gss_export_internal_name(OM_uint32 *, const gss_OID, const gss_name_t, gss_buffer_t); OM_uint32 __gss_display_internal_name(OM_uint32 *, const gss_OID, const gss_name_t, gss_buffer_t, gss_OID *); OM_uint32 __gss_release_internal_name(OM_uint32 *, const gss_OID, gss_name_t *); - OM_uint32 __gss_convert_name_to_union_name( OM_uint32 *, /* minor_status */ gss_mechanism, /* mech */ @@ -548,68 +575,132 @@ gss_name_t * /* external_name */ ); -gss_cred_id_t __gss_get_mechanism_cred( + gss_cred_id_t __gss_get_mechanism_cred( const gss_union_cred_t, /* union_cred */ const gss_OID /* mech_type */ ); -OM_uint32 __gss_create_copy_buffer( + + + + +int gssint_mechglue_init(void); +void gssint_mechglue_fini(void); + +gss_mechanism gssint_get_mechanism (gss_OID); +OM_uint32 gssint_get_mech_type (gss_OID, gss_buffer_t); +char *gssint_get_kmodName(const gss_OID); +char *gssint_get_modOptions(const gss_OID); +OM_uint32 gssint_import_internal_name (OM_uint32 *, gss_OID, gss_union_name_t, + gss_name_t *); +OM_uint32 gssint_export_internal_name(OM_uint32 *, const gss_OID, + const gss_name_t, gss_buffer_t); +OM_uint32 gssint_display_internal_name (OM_uint32 *, gss_OID, gss_name_t, + gss_buffer_t, gss_OID *); +OM_uint32 gssint_release_internal_name (OM_uint32 *, gss_OID, gss_name_t *); + +OM_uint32 gssint_convert_name_to_union_name + (OM_uint32 *, /* minor_status */ + gss_mechanism, /* mech */ + gss_name_t, /* internal_name */ + gss_name_t * /* external_name */ + ); +gss_cred_id_t gssint_get_mechanism_cred + (gss_union_cred_t, /* union_cred */ + gss_OID /* mech_type */ + ); + +OM_uint32 gssint_create_copy_buffer( const gss_buffer_t, /* src buffer */ gss_buffer_t *, /* destination buffer */ int /* NULL terminate buffer ? */ ); -OM_uint32 generic_gss_release_oid( - OM_uint32 *, /* minor_status */ - gss_OID * /* oid */ -); -OM_uint32 generic_gss_copy_oid( - OM_uint32 *, /* minor_status */ - const gss_OID, /* oid */ - gss_OID * /* new_oid */ -); - -OM_uint32 generic_gss_create_empty_oid_set( - OM_uint32 *, /* minor_status */ - gss_OID_set * /* oid_set */ +OM_uint32 gssint_copy_oid_set( + OM_uint32 *, /* minor_status */ + const gss_OID_set_desc *, /* oid set */ + gss_OID_set * /* new oid set */ ); -OM_uint32 generic_gss_add_oid_set_member( - OM_uint32 *, /* minor_status */ - const gss_OID, /* member_oid */ - gss_OID_set * /* oid_set */ -); - -OM_uint32 generic_gss_test_oid_set_member( - OM_uint32 *, /* minor_status */ - const gss_OID, /* member */ - const gss_OID_set, /* set */ - int * /* present */ -); - -OM_uint32 generic_gss_oid_to_str( - OM_uint32 *, /* minor_status */ - const gss_OID, /* oid */ - gss_buffer_t /* oid_str */ -); - -OM_uint32 generic_gss_str_to_oid( - OM_uint32 *, /* minor_status */ - const gss_buffer_t, /* oid_str */ - gss_OID * /* oid */ -); - +/* SUNW15resync - for old Solaris version in libgss */ OM_uint32 gss_copy_oid_set( OM_uint32 *, /* minor_status */ const gss_OID_set_desc *, /* oid set */ gss_OID_set * /* new oid set */ ); -#endif + +gss_OID gss_find_mechanism_from_name_type (gss_OID); /* name_type */ + +OM_uint32 gss_add_mech_name_type + (OM_uint32 *, /* minor_status */ + gss_OID, /* name_type */ + gss_OID /* mech */ + ); + +/* + * Sun extensions to GSS-API v2 + */ + +OM_uint32 +gssint_mech_to_oid( + const char *mech, /* mechanism string name */ + gss_OID *oid /* mechanism oid */ +); + +const char * +gssint_oid_to_mech( + const gss_OID oid /* mechanism oid */ +); + +OM_uint32 +gssint_get_mechanisms( + char *mechArray[], /* array to populate with mechs */ + int arrayLen /* length of passed in array */ +); + +OM_uint32 +gss_store_cred( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* input_cred_handle */ + gss_cred_usage_t, /* cred_usage */ + const gss_OID, /* desired_mech */ + OM_uint32, /* overwrite_cred */ + OM_uint32, /* default_cred */ + gss_OID_set *, /* elements_stored */ + gss_cred_usage_t * /* cred_usage_stored */ +); + +int +gssint_get_der_length( + unsigned char **, /* buf */ + unsigned int, /* buf_len */ + unsigned int * /* bytes */ +); + +unsigned int +gssint_der_length_size(unsigned int /* len */); + +int +gssint_put_der_length( + unsigned int, /* length */ + unsigned char **, /* buf */ + unsigned int /* max_len */ +); + + + +/* Solaris kernel and gssd support */ + +/* + * derived types for passing context and credential handles + * between gssd and kernel + */ +typedef unsigned int gssd_ctx_id_t; +typedef unsigned int gssd_cred_id_t; #ifdef _KERNEL -#include #ifndef _KRB5_H /* These macros are defined for Kerberos in krb5.h, and have priority */ @@ -693,7 +784,15 @@ /* EXPORT DELETE END */ +#define KGSS_INIT_CONTEXT(ctx) krb5_init_context(ctx) +#define KGSS_RELEASE_OID(minor_st, oid) krb5_gss_release_oid(minor_st, oid) +extern OM_uint32 kgss_release_oid(OM_uint32 *, gss_OID *); + #else /* !_KERNEL */ + +#define KGSS_INIT_CONTEXT(ctx) krb5_gss_init_context(ctx) +#define KGSS_RELEASE_OID(minor_st, oid) gss_release_oid(minor_st, oid) + #define KCTX_TO_CTX(ctx) (KCTX_TO_KGSS_CTX(ctx)->gssd_ctx) #define MALLOC(n) malloc(n) #define FREE(x, n) free(x) @@ -722,8 +821,57 @@ KCTX_TO_CTXV(ctx)) #endif /* _KERNEL */ -#ifdef __cplusplus -} -#endif +/* SUNW15resync - moved from gssapiP_generic.h for sake of non-krb5 mechs */ +OM_uint32 generic_gss_release_buffer +(OM_uint32*, /* minor_status */ + gss_buffer_t /* buffer */ + ); + +OM_uint32 generic_gss_release_oid_set +(OM_uint32*, /* minor_status */ + gss_OID_set* /* set */ + ); + +OM_uint32 generic_gss_release_oid +(OM_uint32*, /* minor_status */ + gss_OID* /* set */ + ); + +OM_uint32 generic_gss_copy_oid +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* oid */ /* SUNW15resync */ + gss_OID * /* new_oid */ + ); + +OM_uint32 generic_gss_create_empty_oid_set +(OM_uint32 *, /* minor_status */ + gss_OID_set * /* oid_set */ + ); -#endif /* _MECHGLUEP_H */ +OM_uint32 generic_gss_add_oid_set_member +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* member_oid */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_test_oid_set_member +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* member */ + gss_OID_set, /* set */ + int * /* present */ + ); + +OM_uint32 generic_gss_oid_to_str +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* oid */ + gss_buffer_t /* oid_str */ + ); + +OM_uint32 generic_gss_str_to_oid +(OM_uint32 *, /* minor_status */ + gss_buffer_t, /* oid_str */ + gss_OID * /* oid */ + ); + + +#endif /* _GSS_MECHGLUEP_H */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/include/mglueP.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/gssapi/include/mglueP.h Fri Sep 14 15:01:24 2007 -0700 @@ -0,0 +1,17 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * SUNW15resync + * This file (mglueP.h) is the MIT name for the mech glue + * header file, but the Solaris one is mechglueP.h. We keep this file + * so MIT files don't need to be changed to include the Solaris one. + */ + +#include "mechglueP.h" + + diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h Fri Sep 14 15:01:24 2007 -0700 @@ -1,3 +1,10 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -20,57 +27,46 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef _GSSAPIP_GENERIC_H_ #define _GSSAPIP_GENERIC_H_ -#pragma ident "%Z%%M% %I% %E% SMI" - /* - * $Id: gssapiP_generic.h,v 1.24 1998/10/30 02:54:06 marc Exp $ + * $Id: gssapiP_generic.h 18131 2006-06-14 22:27:54Z tlyu $ */ -#ifdef __cplusplus -extern "C" { +#if defined(_WIN32) +#include "k5-int.h" +#else +#include "autoconf.h" +#ifndef _KERNEL +#ifdef HAVE_STDLIB_H +#include +#endif /* !_KERNEL */ +#endif #endif -#if !defined(PROTOTYPE) -#define PROTOTYPE(x) x -#endif +#include "k5-thread.h" + +#include "gssapi_generic.h" -#if (defined(_MSDOS) || defined(_WIN32) || defined(macintosh)) -#include +#include "gssapi_err_generic.h" +#ifndef _KERNEL +#include #else -#ifdef HAVE_STDLIB_H -#ifndef _KERNEL -#include +#include #endif /* !_KERNEL */ -#endif /* HAVE_STDLIB_H */ -#endif -#include -#include -#include -#include "gssapi_generic.h" -#include "gssapi_err_generic.h" -#ifdef _KERNEL -#include -#else -#include -#endif +#include "k5-platform.h" +typedef UINT64_TYPE gssint_uint64; + +#include "gssapi/gssapi_ext.h" /** helper macros **/ -typedef uint64_t gssint_uint64; - -#if 0 /* this is defined in usr/src/uts/common/gssapi/gssapi_ext.h */ -#define g_OID_equal(o1,o2) \ - (((o1)->length == (o2)->length) && \ - (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) +#if 0 /* SUNW15resync - on Solaris g_OID_equal is in gssapi_ext.h */ +#define g_OID_equal(o1, o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements, (o2)->elements, (o1)->length) == 0)) #endif /* this code knows that an int on the wire is 32 bits. The type of @@ -102,7 +98,7 @@ (ptr) += 2; #define TWRITE_STR(ptr, str, len) \ - (void) memcpy((ptr), (char *) (str), (len)); \ + (void) memcpy((ptr), (char *) (str), (len)); \ (ptr) += (len); #define TREAD_STR(ptr, str, len) \ @@ -135,39 +131,80 @@ /** helper functions **/ -typedef struct _g_set *g_set; - -int g_set_init (g_set *s); -int g_set_destroy (g_set *s); -int g_set_entry_add (g_set *s, void *key, void *value); -int g_set_entry_delete (g_set *s, void *key); -int g_set_entry_get (g_set *s, void *key, void **value); +/* hide names from applications, especially glib applications */ +#define g_set_init gssint_g_set_init +#define g_set_destroy gssint_g_set_destroy +#define g_set_entry_add gssint_g_set_entry_add +#define g_set_entry_delete gssint_g_set_entry_delete +#define g_set_entry_get gssint_g_set_entry_get +#define g_save_name gssint_g_save_name +#define g_save_cred_id gssint_g_save_cred_id +#define g_save_ctx_id gssint_g_save_ctx_id +#define g_save_lucidctx_id gssint_g_save_lucidctx_id +#define g_validate_name gssint_g_validate_name +#define g_validate_cred_id gssint_g_validate_cred_id +#define g_validate_ctx_id gssint_g_validate_ctx_id +#define g_validate_lucidctx_id gssint_g_validate_lucidctx_id +#define g_delete_name gssint_g_delete_name +#define g_delete_cred_id gssint_g_delete_cred_id +#define g_delete_ctx_id gssint_g_delete_ctx_id +#define g_delete_lucidctx_id gssint_g_delete_lucidctx_id +#define g_make_string_buffer gssint_g_make_string_buffer +#define g_token_size gssint_g_token_size +#define g_make_token_header gssint_g_make_token_header +#define g_verify_token_header gssint_g_verify_token_header +#define g_display_major_status gssint_g_display_major_status +#define g_display_com_err_status gssint_g_display_com_err_status +#define g_order_init gssint_g_order_init +#define g_order_check gssint_g_order_check +#define g_order_free gssint_g_order_free +#define g_queue_size gssint_g_queue_size +#define g_queue_externalize gssint_g_queue_externalize +#define g_queue_internalize gssint_g_queue_internalize +#define g_canonicalize_host gssint_g_canonicalize_host +#define g_local_host_name gssint_g_local_host_name +#define g_strdup gssint_g_strdup -int g_save_name (void **vdb, gss_name_t name); -int g_save_cred_id (void **vdb, gss_cred_id_t cred); -int g_save_ctx_id (void **vdb, gss_ctx_id_t ctx); +typedef struct _g_set_elt *g_set_elt; +typedef struct { + k5_mutex_t mutex; + void *data; +} g_set; +#define G_SET_INIT { K5_MUTEX_PARTIAL_INITIALIZER, 0 } + +int g_set_init (g_set_elt *s); +int g_set_destroy (g_set_elt *s); +int g_set_entry_add (g_set_elt *s, void *key, void *value); +int g_set_entry_delete (g_set_elt *s, void *key); +int g_set_entry_get (g_set_elt *s, void *key, void **value); -int g_validate_name (void **vdb, gss_name_t name); -int g_validate_cred_id (void **vdb, gss_cred_id_t cred); -int g_validate_ctx_id (void **vdb, gss_ctx_id_t ctx); +int g_save_name (g_set *vdb, gss_name_t name); +int g_save_cred_id (g_set *vdb, gss_cred_id_t cred); +int g_save_ctx_id (g_set *vdb, gss_ctx_id_t ctx); +int g_save_lucidctx_id (g_set *vdb, void *lctx); -int g_delete_name (void **vdb, gss_name_t name); -int g_delete_cred_id (void **vdb, gss_cred_id_t cred); -int g_delete_ctx_id (void **vdb, gss_ctx_id_t ctx); +int g_validate_name (g_set *vdb, gss_name_t name); +int g_validate_cred_id (g_set *vdb, gss_cred_id_t cred); +int g_validate_ctx_id (g_set *vdb, gss_ctx_id_t ctx); +int g_validate_lucidctx_id (g_set *vdb, void *lctx); + +int g_delete_name (g_set *vdb, gss_name_t name); +int g_delete_cred_id (g_set *vdb, gss_cred_id_t cred); +int g_delete_ctx_id (g_set *vdb, gss_ctx_id_t ctx); +int g_delete_lucidctx_id (g_set *vdb, void *lctx); int g_make_string_buffer (const char *str, gss_buffer_t buffer); -int g_copy_OID_set (const gss_OID_set_desc * const in, gss_OID_set *out); +unsigned int g_token_size (const gss_OID_desc * mech, unsigned int body_size); -int g_token_size (gss_OID mech, unsigned int body_size); - -void g_make_token_header (gss_OID mech, int body_size, +void g_make_token_header (const gss_OID_desc * mech, unsigned int body_size, unsigned char **buf, int tok_type); -gss_int32 g_verify_token_header (gss_OID mech, unsigned int *body_size, - unsigned char **buf, int tok_type, - unsigned int toksize_in, - int wrapper_required); +gss_int32 g_verify_token_header (const gss_OID_desc * mech, + unsigned int *body_size, + unsigned char **buf, int tok_type, + unsigned int toksize_in, + int wrapper_required); OM_uint32 g_display_major_status (OM_uint32 *minor_status, OM_uint32 status_value, @@ -179,7 +216,7 @@ gss_buffer_t status_string); gss_int32 g_order_init (void **queue, gssint_uint64 seqnum, - int do_replay, int do_sequence, int wide); + int do_replay, int do_sequence, int wide); gss_int32 g_order_check (void **queue, gssint_uint64 seqnum); @@ -191,12 +228,61 @@ gss_uint32 g_queue_internalize(void **vqueue, unsigned char **buf, size_t *lenremain); -char *g_local_host_name (void); - char *g_strdup (char *str); -#ifdef __cplusplus -} -#endif +/** declarations of internal name mechanism functions **/ + +#if 0 /* SUNW15resync - mved to mglueP.h for sake of non-krb5 mechs */ +OM_uint32 generic_gss_release_buffer +(OM_uint32*, /* minor_status */ + gss_buffer_t /* buffer */ + ); + +OM_uint32 generic_gss_release_oid_set +(OM_uint32*, /* minor_status */ + gss_OID_set* /* set */ + ); + +OM_uint32 generic_gss_release_oid +(OM_uint32*, /* minor_status */ + gss_OID* /* set */ + ); + +OM_uint32 generic_gss_copy_oid +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* oid */ /* SUNW15resync */ + gss_OID * /* new_oid */ + ); + +OM_uint32 generic_gss_create_empty_oid_set +(OM_uint32 *, /* minor_status */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_add_oid_set_member +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* member_oid */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_test_oid_set_member +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* member */ + gss_OID_set, /* set */ + int * /* present */ + ); + +OM_uint32 generic_gss_oid_to_str +(OM_uint32 *, /* minor_status */ + gss_OID_desc * const, /* oid */ + gss_buffer_t /* oid_str */ + ); + +OM_uint32 generic_gss_str_to_oid +(OM_uint32 *, /* minor_status */ + gss_buffer_t, /* oid_str */ + gss_OID * /* oid */ + ); +#endif /* 0 */ #endif /* _GSSAPIP_GENERIC_H_ */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,10 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 2000 by the Massachusetts Institute of Technology. * All Rights Reserved. @@ -47,70 +49,49 @@ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. - * */ -#ifndef _GSSAPIP_KRB5_H -#define _GSSAPIP_KRB5_H - -#pragma ident "%Z%%M% %I% %E% SMI" +#ifndef _GSSAPIP_KRB5_H_ +#define _GSSAPIP_KRB5_H_ -/* - * $Id: gssapiP_krb5.h,v 1.40.6.2 2000/05/31 17:17:38 raeburn Exp $ - */ +#include -#include -#include -#ifndef _KERNEL +#ifdef HAVE_MEMORY_H #include #endif -/* - * Solaris defines the minor() and major() macros for device numbers. - * Undefine them here so we don't cause confusion for the minor - * and major error numbers. - */ -#ifdef major -#undef major +/* work around sunos braindamage */ +#ifdef major +#undef major #endif -#ifdef minor -#undef minor +#ifdef minor +#undef minor #endif #include "gssapiP_generic.h" -#ifndef _KERNEL -#ifdef DEBUG_ON - -#define dprintf(a) printf(a) -#define dprintf1(a, b) printf(a, b) - -#else - -#define dprintf(a) -#define dprintf1(a, b) -#define DUMMY_STATIC - -#endif /* DEBUG_ON */ - -#else /* _KERNEL */ - -#define dprintf(a) KRB5_LOG0(KRB5_INFO, a) -#define dprintf1(a, b) KRB5_LOG(KRB5_INFO, a, b) -#define DUMMY_STATIC static - -#endif /* _KERNEL */ - /* The include of gssapi_krb5.h will dtrt with the above #defines in * effect. */ +#include "gssapi_krb5.h" +#include "gssapi_err_krb5.h" -#include -#include -#include +/* for debugging */ +#undef CFX_EXERCISE /** constants **/ +#define GSS_MECH_KRB5_OID_LENGTH 9 +#define GSS_MECH_KRB5_OID "\052\206\110\206\367\022\001\002\002" + +#define GSS_MECH_KRB5_OLD_OID_LENGTH 5 +#define GSS_MECH_KRB5_OLD_OID "\053\005\001\005\002" + +/* Incorrect krb5 mech OID emitted by MS. */ +#define GSS_MECH_KRB5_WRONG_OID_LENGTH 9 +#define GSS_MECH_KRB5_WRONG_OID "\052\206\110\202\367\022\001\002\002" + + #define CKSUMTYPE_KG_CB 0x8003 #define KG_TOK_CTX_AP_REQ 0x0100 @@ -140,14 +121,14 @@ SGN_ALG_MD2_5 = 0x0001, SGN_ALG_DES_MAC = 0x0002, SGN_ALG_3 = 0x0003, /* not published */ - SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */ + SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; */ SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004 }; enum seal_alg { SEAL_ALG_NONE = 0xffff, SEAL_ALG_DES = 0x0000, SEAL_ALG_1 = 0x0001, /* not published */ - SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */ + SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */ SEAL_ALG_DES3KD = 0x0002 }; @@ -159,8 +140,8 @@ /* for draft-ietf-krb-wg-gssapi-cfx-01 */ #define KG_USAGE_ACCEPTOR_SEAL 22 #define KG_USAGE_ACCEPTOR_SIGN 23 -#define KG_USAGE_INITIATOR_SEAL 24 -#define KG_USAGE_INITIATOR_SIGN 25 +#define KG_USAGE_INITIATOR_SEAL 24 +#define KG_USAGE_INITIATOR_SIGN 25 enum qop { GSS_KRB5_INTEG_C_QOP_MD5 = 0x0001, /* *partial* MD5 = "MD2.5" */ @@ -178,11 +159,13 @@ typedef krb5_principal krb5_gss_name_t; typedef struct _krb5_gss_cred_id_rec { + /* protect against simultaneous accesses */ + k5_mutex_t lock; + /* name/type of credential */ gss_cred_usage_t usage; krb5_principal princ; /* this is not interned as a gss_name_t */ - const gss_OID_set_desc *actual_mechs; - int prerfc_mech; /* these are a cache of the set above */ + int prerfc_mech; int rfc_mech; /* keytab (accept) data */ @@ -192,6 +175,7 @@ /* ccache (init) data */ krb5_ccache ccache; krb5_timestamp tgt_expire; + krb5_enctype *req_enctypes; /* limit negotiated enctypes to this list */ } krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; typedef struct _krb5_gss_ctx_id_rec { @@ -200,9 +184,6 @@ unsigned int big_endian : 1; unsigned int have_acceptor_subkey : 1; unsigned int seed_init : 1; /* XXX tested but never actually set */ -#ifdef CFX_EXERCISE - unsigned int testing_unknown_tokid : 1; /* for testing only */ -#endif OM_uint32 gss_flags; unsigned char seed[16]; krb5_principal here; @@ -221,202 +202,141 @@ gssint_uint64 seq_send; gssint_uint64 seq_recv; void *seqstate; + krb5_context k5_context; krb5_auth_context auth_context; - /* - * SOLARIS KERBEROS: - * MIT uses a 'gss_OID_desc *' here, we do not use the pointer. - */ - gss_OID_desc mech_used; + gss_OID_desc *mech_used; /* Protocol spec revision - 0 => RFC 1964 with 3DES and RC4 enhancements - 1 => draft-ietf-krb-wg-gssapi-cfx-01 - No others defined so far. */ + 0 => RFC 1964 with 3DES and RC4 enhancements + 1 => draft-ietf-krb-wg-gssapi-cfx-01 + No others defined so far. */ int proto; krb5_cksumtype cksumtype; /* for "main" subkey */ krb5_keyblock *acceptor_subkey; /* CFX only */ krb5_cksumtype acceptor_subkey_cksumtype; + int cred_rcache; /* did we get rcache from creds? */ } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; -extern void *kg_vdb; +extern g_set kg_vdb; -extern krb5_context kg_context; -#ifdef _KERNEL -extern kmutex_t krb5_mutex; -#else -extern mutex_t krb5_mutex; -#endif +extern k5_mutex_t gssint_krb5_keytab_lock; /* helper macros */ #define kg_save_name(name) g_save_name(&kg_vdb,name) #define kg_save_cred_id(cred) g_save_cred_id(&kg_vdb,cred) #define kg_save_ctx_id(ctx) g_save_ctx_id(&kg_vdb,ctx) +#define kg_save_lucidctx_id(lctx) g_save_lucidctx_id(&kg_vdb,lctx) #define kg_validate_name(name) g_validate_name(&kg_vdb,name) #define kg_validate_cred_id(cred) g_validate_cred_id(&kg_vdb,cred) #define kg_validate_ctx_id(ctx) g_validate_ctx_id(&kg_vdb,ctx) +#define kg_validate_lucidctx_id(lctx) g_validate_lucidctx_id(&kg_vdb,lctx) #define kg_delete_name(name) g_delete_name(&kg_vdb,name) #define kg_delete_cred_id(cred) g_delete_cred_id(&kg_vdb,cred) #define kg_delete_ctx_id(ctx) g_delete_ctx_id(&kg_vdb,ctx) +#define kg_delete_lucidctx_id(lctx) g_delete_lucidctx_id(&kg_vdb,lctx) /** helper functions **/ -OM_uint32 kg_get_defcred ( - OM_uint32 *minor_status, - gss_cred_id_t *cred); +OM_uint32 kg_get_defcred + (OM_uint32 *minor_status, + gss_cred_id_t *cred); -OM_uint32 kg_release_defcred (OM_uint32 *minor_status); - -krb5_error_code kg_checksum_channel_bindings ( - krb5_context context, gss_channel_bindings_t cb, - krb5_checksum *cksum, - int bigend); +krb5_error_code kg_checksum_channel_bindings + (krb5_context context, gss_channel_bindings_t cb, + krb5_checksum *cksum, + int bigend); -krb5_error_code kg_make_seq_num ( - krb5_context context, - krb5_keyblock *key, - int direction, - krb5_ui_4 seqnum, - unsigned char *cksum, - unsigned char *buf); +krb5_error_code kg_make_seq_num (krb5_context context, + krb5_keyblock *key, + int direction, krb5_ui_4 seqnum, unsigned char *cksum, + unsigned char *buf); -krb5_error_code kg_get_seq_num ( - krb5_context context, - krb5_keyblock *key, - unsigned char *cksum, - unsigned char *buf, - int *direction, - krb5_ui_4 *seqnum); +krb5_error_code kg_get_seq_num (krb5_context context, + krb5_keyblock *key, + unsigned char *cksum, unsigned char *buf, int *direction, + krb5_ui_4 *seqnum); -krb5_error_code kg_make_seed ( - krb5_context context, - krb5_keyblock *key, - unsigned char *seed); +krb5_error_code kg_make_seed (krb5_context context, + krb5_keyblock *key, + unsigned char *seed); int kg_confounder_size (krb5_context context, krb5_keyblock *key); krb5_error_code kg_make_confounder (krb5_context context, krb5_keyblock *key, unsigned char *buf); -int kg_encrypt_size ( - krb5_context context, - krb5_keyblock *key, - int n); - -krb5_error_code kg_encrypt ( - krb5_context context, - krb5_keyblock *key, - int usage, - krb5_pointer iv, - krb5_pointer in, - krb5_pointer out, - int length); - +krb5_error_code kg_encrypt (krb5_context context, + krb5_keyblock *key, int usage, + krb5_pointer iv, + krb5_pointer in, + krb5_pointer out, + unsigned int length); krb5_error_code kg_arcfour_docrypt (krb5_context, - const krb5_keyblock *longterm_key , int ms_usage, - const unsigned char *kd_data, size_t kd_data_len, - const unsigned char *input_buf, size_t input_len, - unsigned char *output_buf); + const krb5_keyblock *longterm_key , int ms_usage, + const unsigned char *kd_data, size_t kd_data_len, + const unsigned char *input_buf, size_t input_len, + unsigned char *output_buf); krb5_error_code kg_decrypt (krb5_context context, - krb5_keyblock *key, - int usage, - krb5_pointer iv, - krb5_pointer in, - krb5_pointer out, - int length); + krb5_keyblock *key, int usage, + krb5_pointer iv, + krb5_pointer in, + krb5_pointer out, + unsigned int length); -OM_uint32 kg_seal ( - krb5_context context, - OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - int conf_req_flag, - int qop_req, - gss_buffer_t input_message_buffer, - int *conf_state, - gss_buffer_t output_message_buffer, - int toktype); +OM_uint32 kg_seal (OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer, + int toktype); -OM_uint32 kg_unseal ( - krb5_context context, - OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - gss_buffer_t input_token_buffer, - gss_buffer_t message_buffer, - int *conf_state, - int *qop_state, - int toktype); +OM_uint32 kg_unseal (OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_token_buffer, + gss_buffer_t message_buffer, + int *conf_state, + int *qop_state, + int toktype); -OM_uint32 kg_seal_size ( - krb5_context context, - OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 output_size, - OM_uint32 *input_size); +OM_uint32 kg_seal_size (OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 output_size, + OM_uint32 *input_size); -krb5_error_code kg_ctx_size ( - krb5_context kcontext, - krb5_pointer arg, - size_t *sizep); +krb5_error_code kg_ctx_size (krb5_context kcontext, + krb5_pointer arg, + size_t *sizep); -krb5_error_code kg_ctx_externalize ( - krb5_context kcontext, - krb5_pointer arg, - krb5_octet **buffer, - size_t *lenremain); +krb5_error_code kg_ctx_externalize (krb5_context kcontext, + krb5_pointer arg, + krb5_octet **buffer, + size_t *lenremain); -krb5_error_code kg_ctx_internalize ( - krb5_context kcontext, - krb5_pointer *argp, - krb5_octet **buffer, - size_t *lenremain); +krb5_error_code kg_ctx_internalize (krb5_context kcontext, + krb5_pointer *argp, + krb5_octet **buffer, + size_t *lenremain); -OM_uint32 kg_get_context ( - OM_uint32 *minor_status, - krb5_context *context); +OM_uint32 kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status); -OM_uint32 kg_sync_ccache_name (OM_uint32 *minor_status); - -OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, +OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name); -OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status, +OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status, const char *name); -struct kg2_option { - int option_id; /* set by caller */ - int length; /* filled in by parser */ - unsigned char *data; /* filled in by parser. points inside - passed-in token, so nothing needs to - be freed */ -}; - -OM_uint32 -kg2_parse_token (OM_uint32 *minor_status, - unsigned char *ptr, - int length, - krb5_ui_4 *flags, - int *nctypes, /* OUT */ - krb5_cksumtype **ctypes, /* OUT */ - int noptions, - struct kg2_option *options, /* INOUT */ - krb5_data *kmsg, - krb5_data *mic); - -void kg2_intersect_ctypes (int *nc1, - krb5_cksumtype *c1, - int nc2, - const krb5_cksumtype *c2); - /** declarations of internal name mechanism functions **/ -OM_uint32 krb5_gss_acquire_cred ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_acquire_cred +(OM_uint32*, /* minor_status */ gss_name_t, /* desired_name */ OM_uint32, /* time_req */ gss_OID_set, /* desired_mechs */ @@ -426,57 +346,13 @@ OM_uint32* /* time_rec */ ); -OM_uint32 krb5_gss_acquire_cred_no_lock ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ - gss_name_t, /* desired_name */ - OM_uint32, /* time_req */ - gss_OID_set, /* desired_mechs */ - gss_cred_usage_t, /* cred_usage */ - gss_cred_id_t*, /* output_cred_handle */ - gss_OID_set*, /* actual_mechs */ - OM_uint32* /* time_rec */ - ); - -OM_uint32 krb5_gss_release_cred ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ - gss_cred_id_t* /* cred_handle */ - ); - -OM_uint32 krb5_gss_release_cred_no_lock ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_release_cred +(OM_uint32*, /* minor_status */ gss_cred_id_t* /* cred_handle */ ); -OM_uint32 krb5_gss_store_cred ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ - const gss_cred_id_t, /* input_cred */ - gss_cred_usage_t, /* cred_usage */ - const gss_OID, /* desired_mech */ - OM_uint32, /* overwrite_cred */ - OM_uint32, /* default_cred */ - gss_OID_set *, /* elements_stored */ - gss_cred_usage_t * /* cred_usage_stored */ - ); - -OM_uint32 krb5_gss_store_cred_no_lock ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ - const gss_cred_id_t, /* input_cred */ - gss_cred_usage_t, /* cred_usage */ - const gss_OID, /* desired_mech */ - OM_uint32, /* overwrite_cred */ - OM_uint32, /* default_cred */ - gss_OID_set *, /* elements_stored */ - gss_cred_usage_t * /* cred_usage_stored */ - ); - -OM_uint32 krb5_gss_init_sec_context ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_init_sec_context +(OM_uint32*, /* minor_status */ gss_cred_id_t, /* claimant_cred_handle */ gss_ctx_id_t*, /* context_handle */ gss_name_t, /* target_name */ @@ -492,9 +368,8 @@ OM_uint32* /* time_rec */ ); -OM_uint32 krb5_gss_accept_sec_context ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_accept_sec_context +(OM_uint32*, /* minor_status */ gss_ctx_id_t*, /* context_handle */ gss_cred_id_t, /* verifier_cred_handle */ gss_buffer_t, /* input_token_buffer */ @@ -508,68 +383,52 @@ gss_cred_id_t* /* delegated_cred_handle */ ); -OM_uint32 krb5_gss_process_context_token ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_process_context_token +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t /* token_buffer */ ); -OM_uint32 krb5_gss_delete_sec_context ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_delete_sec_context +(OM_uint32*, /* minor_status */ gss_ctx_id_t*, /* context_handle */ gss_buffer_t /* output_token */ #ifdef _KERNEL - /* */, OM_uint32 /* context verifier */ + /* */, OM_uint32 /* context verifier */ #endif - ); + ); -OM_uint32 krb5_gss_delete_sec_context_no_lock ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ - gss_ctx_id_t*, /* context_handle */ - gss_buffer_t /* output_token */ -#ifdef _KERNEL - /* */, OM_uint32 /* context verifier */ -#endif - ); - -OM_uint32 krb5_gss_context_time ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_context_time +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ OM_uint32* /* time_rec */ ); -OM_uint32 krb5_gss_sign ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_sign +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* qop_req */ gss_buffer_t, /* message_buffer */ gss_buffer_t /* message_token */ #ifdef _KERNEL - /* */, OM_uint32 /* context verifier */ + /* */, OM_uint32 /* context verifier */ #endif ); -OM_uint32 krb5_gss_verify ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_verify +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* message_buffer */ gss_buffer_t, /* token_buffer */ int* /* qop_state */ #ifdef _KERNEL - /* */, OM_uint32 /* context verifier */ + /* */, OM_uint32 /* context verifier */ #endif ); /* EXPORT DELETE START */ -OM_uint32 krb5_gss_seal ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_seal +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ int, /* qop_req */ @@ -577,27 +436,25 @@ int*, /* conf_state */ gss_buffer_t /* output_message_buffer */ #ifdef _KERNEL - /* */, OM_uint32 /* context verifier */ + /* */, OM_uint32 /* context verifier */ #endif ); -OM_uint32 krb5_gss_unseal ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_unseal +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* input_message_buffer */ gss_buffer_t, /* output_message_buffer */ int*, /* conf_state */ int* /* qop_state */ #ifdef _KERNEL - /* */, OM_uint32 /* context verifier */ + /* */, OM_uint32 /* context verifier */ #endif ); /* EXPORT DELETE END */ -OM_uint32 krb5_gss_display_status ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_display_status +(OM_uint32*, /* minor_status */ OM_uint32, /* status_value */ int, /* status_type */ gss_OID, /* mech_type */ @@ -605,51 +462,39 @@ gss_buffer_t /* status_string */ ); -OM_uint32 krb5_gss_indicate_mechs ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_indicate_mechs +(OM_uint32*, /* minor_status */ gss_OID_set* /* mech_set */ ); -OM_uint32 krb5_gss_compare_name ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_compare_name +(OM_uint32*, /* minor_status */ gss_name_t, /* name1 */ gss_name_t, /* name2 */ int* /* name_equal */ ); -OM_uint32 krb5_gss_display_name ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_display_name +(OM_uint32*, /* minor_status */ gss_name_t, /* input_name */ gss_buffer_t, /* output_name_buffer */ gss_OID* /* output_name_type */ ); -OM_uint32 krb5_gss_import_name ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_import_name +(OM_uint32*, /* minor_status */ gss_buffer_t, /* input_name_buffer */ gss_OID, /* input_name_type */ gss_name_t* /* output_name */ ); -OM_uint32 krb5_gss_release_name ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_release_name +(OM_uint32*, /* minor_status */ gss_name_t* /* input_name */ ); -OM_uint32 krb5_gss_release_name_no_lock ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ - gss_name_t* /* input_name */ - ); - -OM_uint32 krb5_gss_inquire_cred ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_inquire_cred +(OM_uint32 *, /* minor_status */ gss_cred_id_t, /* cred_handle */ gss_name_t *, /* name */ OM_uint32 *, /* lifetime */ @@ -657,19 +502,8 @@ gss_OID_set * /* mechanisms */ ); -OM_uint32 krb5_gss_inquire_cred_no_lock ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ - gss_cred_id_t, /* cred_handle */ - gss_name_t *, /* name */ - OM_uint32 *, /* lifetime */ - gss_cred_usage_t*,/* cred_usage */ - gss_OID_set * /* mechanisms */ - ); - -OM_uint32 krb5_gss_inquire_context ( - void *, /* krb5 context */ - OM_uint32*, /* minor_status */ +OM_uint32 krb5_gss_inquire_context +(OM_uint32*, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_name_t*, /* initiator_name */ gss_name_t*, /* acceptor_name */ @@ -681,27 +515,24 @@ ); /* New V2 entry points */ -OM_uint32 krb5_gss_get_mic ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_get_mic +(OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_qop_t, /* qop_req */ gss_buffer_t, /* message_buffer */ gss_buffer_t /* message_token */ ); -OM_uint32 krb5_gss_verify_mic ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_verify_mic +(OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* message_buffer */ gss_buffer_t, /* message_token */ gss_qop_t * /* qop_state */ ); -OM_uint32 krb5_gss_wrap ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_wrap +(OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ gss_qop_t, /* qop_req */ @@ -710,9 +541,8 @@ gss_buffer_t /* output_message_buffer */ ); -OM_uint32 krb5_gss_unwrap ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_unwrap +(OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ gss_buffer_t, /* input_message_buffer */ gss_buffer_t, /* output_message_buffer */ @@ -720,9 +550,8 @@ gss_qop_t * /* qop_state */ ); -OM_uint32 krb5_gss_wrap_size_limit ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_wrap_size_limit +(OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ gss_qop_t, /* qop_req */ @@ -730,9 +559,22 @@ OM_uint32 * /* max_input_size */ ); -OM_uint32 krb5_gss_add_cred ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_import_name_object +(OM_uint32 *, /* minor_status */ + void *, /* input_name */ + gss_OID, /* input_name_type */ + gss_name_t * /* output_name */ + ); + +OM_uint32 krb5_gss_export_name_object +(OM_uint32 *, /* minor_status */ + gss_name_t, /* input_name */ + gss_OID, /* desired_name_type */ + void * * /* output_name */ + ); + +OM_uint32 krb5_gss_add_cred +(OM_uint32 *, /* minor_status */ gss_cred_id_t, /* input_cred_handle */ gss_name_t, /* desired_name */ gss_OID, /* desired_mech */ @@ -745,9 +587,8 @@ OM_uint32 * /* acceptor_time_rec */ ); -OM_uint32 krb5_gss_inquire_cred_by_mech ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_inquire_cred_by_mech +(OM_uint32 *, /* minor_status */ gss_cred_id_t, /* cred_handle */ gss_OID, /* mech_type */ gss_name_t *, /* name */ @@ -756,104 +597,149 @@ gss_cred_usage_t * /* cred_usage */ ); -OM_uint32 krb5_gss_export_sec_context ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_export_sec_context +(OM_uint32 *, /* minor_status */ gss_ctx_id_t *, /* context_handle */ gss_buffer_t /* interprocess_token */ ); -OM_uint32 krb5_gss_import_sec_context( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ - gss_buffer_t, /* interprocess_token */ - gss_ctx_id_t * /* context_handle */ - ); +OM_uint32 krb5_gss_import_sec_context +(OM_uint32 *, /* minor_status */ + gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t * /* context_handle */ + /* Note no _KERNEL context verifier */ + ); -OM_uint32 krb5_gss_internal_release_oid ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +krb5_error_code krb5_gss_ser_init(krb5_context); + +OM_uint32 krb5_gss_release_oid +(OM_uint32 *, /* minor_status */ gss_OID * /* oid */ ); -OM_uint32 krb5_gss_inquire_names_for_mech ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ +OM_uint32 krb5_gss_internal_release_oid +(OM_uint32 *, /* minor_status */ + gss_OID * /* oid */ + ); + +OM_uint32 krb5_gss_inquire_names_for_mech +(OM_uint32 *, /* minor_status */ gss_OID, /* mechanism */ gss_OID_set * /* name_types */ ); +/* SUNW15resync - XXX nullify? */ +OM_uint32 krb5_gss_canonicalize_name +(OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + const gss_OID, /* mech_type */ + gss_name_t * /* output_name */ + ); + +OM_uint32 krb5_gss_export_name +(OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t /* exported_name */ + ); + +OM_uint32 krb5_gss_duplicate_name +(OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_name_t * /* dest_name */ + ); + +OM_uint32 krb5_gss_validate_cred +(OM_uint32 *, /* minor_status */ + gss_cred_id_t /* cred */ + ); + +OM_uint32 +krb5_gss_validate_cred_1(OM_uint32 * /* minor_status */, + gss_cred_id_t /* cred_handle */, + krb5_context /* context */); + +gss_OID krb5_gss_convert_static_mech_oid(gss_OID oid); + +krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context, + krb5_gss_ctx_id_rec *, + const gss_buffer_desc *, + gss_buffer_t, + int, int); + +OM_uint32 gss_krb5int_unseal_token_v3(krb5_context context, + OM_uint32 *minor_status, + krb5_gss_ctx_id_rec *ctx, + unsigned char *ptr, int bodysize, + gss_buffer_t message_buffer, + int *conf_state, int *qop_state, + int toktype); + +/* + * SUNW15resync + * Solaris specific interfaces start + */ + +OM_uint32 krb5_gss_store_cred ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* input_cred */ + gss_cred_usage_t, /* cred_usage */ + const gss_OID, /* desired_mech */ + OM_uint32, /* overwrite_cred */ + OM_uint32, /* default_cred */ + gss_OID_set *, /* elements_stored */ + gss_cred_usage_t * /* cred_usage_stored */ + ); + OM_uint32 krb5_pname_to_uid( - void *, /* krb5 context */ OM_uint32 *, /* minor status */ const gss_name_t, /* pname */ uid_t * /* uidOUt */ ); OM_uint32 krb5_gss_userok( - void *, /* krb5 context */ OM_uint32 *, /* minor status */ const gss_name_t, /* remote user principal name */ const char *, /* local unix user name */ int * /* remote user ok to login w/out pw? */ ); -/* Solaris Kerberos: use gss_canonicalize_name() from /usr/src/lib/libgss - * or define a wrapper in mechglue + +/* + * SUNW15resync + * Solaris specific interfaces end */ -#if 0 -OM_uint32 krb5_gss_canonicalize_name - (OM_uint32 *, /* minor_status */ - const gss_name_t, /* input_name */ - const gss_OID, /* mech_type */ - gss_name_t * /* output_name */ - ); -#endif - -OM_uint32 krb5_gss_export_name ( - OM_uint32 *, /* minor_status */ - const gss_name_t, /* input_name */ - gss_buffer_t /* exported_name */ - ); + -OM_uint32 krb5_gss_duplicate_name ( - OM_uint32 *, /* minor_status */ - const gss_name_t, /* input_name */ - gss_name_t * /* dest_name */ - ); +/* + * These take unglued krb5-mech-specific contexts. + */ -OM_uint32 krb5_gss_validate_cred ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ - gss_cred_id_t /* cred */ - ); +OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags + (OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_flags *ticket_flags); -OM_uint32 krb5_gss_validate_cred_no_lock ( - void *, /* krb5 context */ - OM_uint32 *, /* minor_status */ - gss_cred_id_t /* cred */ - ); +OM_uint32 KRB5_CALLCONV gss_krb5int_copy_ccache + (OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + krb5_ccache out_ccache); -gss_OID_desc krb5_gss_convert_static_mech_oid ( - gss_OID oid - ); +OM_uint32 KRB5_CALLCONV +gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, + gss_cred_id_t cred, + OM_uint32 num_ktypes, + krb5_enctype *ktypes); -krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context, - krb5_gss_ctx_id_rec *, - const gss_buffer_desc *, - gss_buffer_t, - int, int - ); +OM_uint32 KRB5_CALLCONV +gss_krb5int_export_lucid_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **kctx); + -OM_uint32 -gss_krb5int_unseal_token_v3(krb5_context, - OM_uint32 *, - krb5_gss_ctx_id_rec *, - unsigned char *, - int bodysize, - gss_buffer_t message_buffer, - int *conf_state, - int *qop_state, - int toktype); +extern k5_mutex_t kg_kdc_flag_mutex; +krb5_error_code krb5_gss_init_context (krb5_context *ctxp); -#endif /* _GSSAPIP_KRB5_H */ +krb5_error_code krb5_gss_use_kdc_context(void); + +#endif /* _GSSAPIP_KRB5_H_ */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_err_krb5.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_err_krb5.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_err_krb5.h Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -26,6 +26,7 @@ #define KG_BAD_SEQ (39756043L) #define KG_EMPTY_CCACHE (39756044L) #define KG_NO_CTYPES (39756045L) +#define KG_LUCID_VERSION (39756046L) #define ERROR_TABLE_BASE_k5g (39756032L) /* for compatibility with older versions... */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h Fri Sep 14 15:01:24 2007 -0700 @@ -1,11 +1,13 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -15,7 +17,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -28,41 +30,70 @@ #ifndef _GSSAPI_KRB5_H_ #define _GSSAPI_KRB5_H_ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include #include #include -#include +#include + +/* SUNW15resync */ +#ifndef GSS_DLLIMP +#define GSS_DLLIMP +#endif /* C++ friendlyness */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -#if !defined(PROTOTYPE) -#define PROTOTYPE(x) x -#endif +/* Reserved static storage for GSS_oids. See rfc 1964 for more details. */ + +/* 2.1.1. Kerberos Principal Name Form: */ +GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME; +/* This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5_name(1)}. The recommended symbolic name for this type + * is "GSS_KRB5_NT_PRINCIPAL_NAME". */ + +/* 2.1.2. Host-Based Service Name Form */ +#define GSS_KRB5_NT_HOSTBASED_SERVICE_NAME GSS_C_NT_HOSTBASED_SERVICE +/* This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4)}. The previously recommended symbolic + * name for this type is "GSS_KRB5_NT_HOSTBASED_SERVICE_NAME". The + * currently preferred symbolic name for this type is + * "GSS_C_NT_HOSTBASED_SERVICE". */ + +/* 2.2.1. User Name Form */ +#define GSS_KRB5_NT_USER_NAME GSS_C_NT_USER_NAME +/* This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) user_name(1)}. The recommended symbolic name for this + * type is "GSS_KRB5_NT_USER_NAME". */ -extern const gss_OID_desc * const gss_mech_krb5; -extern const gss_OID_desc * const gss_mech_krb5_old; -extern const gss_OID_desc * const gss_mech_krb5_v2; -extern const gss_OID_set_desc * const gss_mech_set_krb5; -extern const gss_OID_set_desc * const gss_mech_set_krb5_old; -extern const gss_OID_set_desc * const gss_mech_set_krb5_both; -extern const gss_OID_set_desc * const gss_mech_set_krb5_v2; -extern const gss_OID_set_desc * const gss_mech_set_krb5_v1v2; +/* 2.2.2. Machine UID Form */ +#define GSS_KRB5_NT_MACHINE_UID_NAME GSS_C_NT_MACHINE_UID_NAME +/* This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) machine_uid_name(2)}. The recommended symbolic name for + * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". */ -extern const gss_OID_desc * const gss_nt_krb5_name; -extern const gss_OID_desc * const gss_nt_krb5_principal; +/* 2.2.3. String UID Form */ +#define GSS_KRB5_NT_STRING_UID_NAME GSS_C_NT_STRING_UID_NAME +/* This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) string_uid_name(3)}. The recommended symbolic name for + * this type is "GSS_KRB5_NT_STRING_UID_NAME". */ -/* Added name type definitions - declared in gen_oids.c */ -extern gss_OID gss_nt_user_name; -extern gss_OID gss_nt_machine_uid_name; -extern gss_OID gss_nt_string_uid_name; -extern gss_OID gss_nt_service_name; +GSS_DLLIMP extern const gss_OID_desc * const gss_mech_krb5; +GSS_DLLIMP extern const gss_OID_desc * const gss_mech_krb5_old; +GSS_DLLIMP extern const gss_OID_desc * const gss_mech_krb5_wrong; +GSS_DLLIMP extern const gss_OID_set_desc * const gss_mech_set_krb5; +GSS_DLLIMP extern const gss_OID_set_desc * const gss_mech_set_krb5_old; +GSS_DLLIMP extern const gss_OID_set_desc * const gss_mech_set_krb5_both; -extern const gss_OID_desc krb5_gss_oid_array[]; +GSS_DLLIMP extern const gss_OID_desc * const gss_nt_krb5_name; +GSS_DLLIMP extern const gss_OID_desc * const gss_nt_krb5_principal; + +GSS_DLLIMP extern const gss_OID_desc krb5_gss_oid_array[]; #define gss_krb5_nt_general_name gss_nt_krb5_name #define gss_krb5_nt_principal gss_nt_krb5_principal @@ -71,13 +102,95 @@ #define gss_krb5_nt_machine_uid_name gss_nt_machine_uid_name #define gss_krb5_nt_string_uid_name gss_nt_string_uid_name -OM_uint32 KRB5_CALLCONV gss_krb5_get_tkt_flags + +#if defined(_WIN32) +typedef unsigned __int64 gss_uint64; +#else /*windows*/ + +#ifdef _KERNEL +#include +#else /* _KERNEL */ +#include +#endif /* _KERNEL */ + +typedef uint64_t gss_uint64; +#endif + + +typedef struct gss_krb5_lucid_key { + OM_uint32 type; /* key encryption type */ + OM_uint32 length; /* length of key data */ + void * data; /* actual key data */ +} gss_krb5_lucid_key_t; + +typedef struct gss_krb5_rfc1964_keydata { + OM_uint32 sign_alg; /* signing algorthm */ + OM_uint32 seal_alg; /* seal/encrypt algorthm */ + gss_krb5_lucid_key_t ctx_key; + /* Context key + (Kerberos session key or subkey) */ +} gss_krb5_rfc1964_keydata_t; + +typedef struct gss_krb5_cfx_keydata { + OM_uint32 have_acceptor_subkey; + /* 1 if there is an acceptor_subkey + present, 0 otherwise */ + gss_krb5_lucid_key_t ctx_key; + /* Context key + (Kerberos session key or subkey) */ + gss_krb5_lucid_key_t acceptor_subkey; + /* acceptor-asserted subkey or + 0's if no acceptor subkey */ +} gss_krb5_cfx_keydata_t; + +typedef struct gss_krb5_lucid_context_v1 { + OM_uint32 version; /* Structure version number (1) + MUST be at beginning of struct! */ + OM_uint32 initiate; /* Are we the initiator? */ + OM_uint32 endtime; /* expiration time of context */ + gss_uint64 send_seq; /* sender sequence number */ + gss_uint64 recv_seq; /* receive sequence number */ + OM_uint32 protocol; /* 0: rfc1964, + 1: draft-ietf-krb-wg-gssapi-cfx-07 */ + /* + * if (protocol == 0) rfc1964_kd should be used + * and cfx_kd contents are invalid and should be zero + * if (protocol == 1) cfx_kd should be used + * and rfc1964_kd contents are invalid and should be zero + */ + gss_krb5_rfc1964_keydata_t rfc1964_kd; + gss_krb5_cfx_keydata_t cfx_kd; +} gss_krb5_lucid_context_v1_t; + +/* + * Mask for determining the returned structure version. + * See example below for usage. + */ +typedef struct gss_krb5_lucid_context_version { + OM_uint32 version; /* Structure version number */ +} gss_krb5_lucid_context_version_t; + + + + +/* Alias for Heimdal compat. */ +#define gsskrb5_register_acceptor_identity krb5_gss_register_acceptor_identity + +OM_uint32 KRB5_CALLCONV krb5_gss_register_acceptor_identity(const char *); + + /* + * SUNW15resync + * The name has changed (_krb5_ to _krb5int_) in MIT's + * get_tkt_flags.c but did not change here + * ...a bug I assume so we change it here. + */ +OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags (OM_uint32 *minor_status, gss_ctx_id_t context_handle, krb5_flags *ticket_flags); OM_uint32 KRB5_CALLCONV gss_krb5_copy_ccache - (void *ctx, OM_uint32 *minor_status, + (OM_uint32 *minor_status, gss_cred_id_t cred_handle, krb5_ccache out_ccache); @@ -85,6 +198,98 @@ (OM_uint32 *minor_status, const char *name, const char **out_name); +/* + * gss_krb5_set_allowable_enctypes + * + * This function may be called by a context initiator after calling + * gss_acquire_cred(), but before calling gss_init_sec_context(), + * to restrict the set of enctypes which will be negotiated during + * context establishment to those in the provided array. + * + * 'cred' must be a valid credential handle obtained via + * gss_acquire_cred(). It may not be GSS_C_NO_CREDENTIAL. + * gss_acquire_cred() may have been called to get a handle to + * the default credential. + * + * The purpose of this function is to limit the keys that may + * be exported via gss_krb5_export_lucid_sec_context(); thus it + * should limit the enctypes of all keys that will be needed + * after the security context has been established. + * (i.e. context establishment may use a session key with a + * stronger enctype than in the provided array, however a + * subkey must be established within the enctype limits + * established by this function.) + * + */ +OM_uint32 KRB5_CALLCONV +gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, + gss_cred_id_t cred, + OM_uint32 num_ktypes, + krb5_enctype *ktypes); + +/* + * Returns a non-opaque (lucid) version of the internal context + * information. + * + * Note that context_handle must not be used again by the caller + * after this call. The GSS implementation is free to release any + * resources associated with the original context. It is up to the + * GSS implementation whether it returns pointers to existing data, + * or copies of the data. The caller should treat the returned + * lucid context as read-only. + * + * The caller must call gss_krb5_free_lucid_context() to free + * the context and allocated resources when it is finished with it. + * + * 'version' is an integer indicating the highest version of lucid + * context understood by the caller. The highest version + * understood by both the caller and the GSS implementation must + * be returned. The caller can determine which version of the + * structure was actually returned by examining the version field + * of the returned structure. gss_krb5_lucid_context_version_t + * may be used as a mask to examine the returned structure version. + * + * If there are no common versions, an error should be returned. + * (XXX Need error definition(s)) + * + * For example: + * void *return_ctx; + * gss_krb5_lucid_context_v1_t *ctx; + * OM_uint32 min_stat, maj_stat; + * OM_uint32 vers; + * gss_ctx_id_t *ctx_handle; + * + * maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, + * ctx_handle, 1, &return_ctx); + * // Verify success + * + * vers = ((gss_krb5_lucid_context_version_t *)return_ctx)->version; + * switch (vers) { + * case 1: + * ctx = (gss_krb5_lucid_context_v1_t *) return_ctx; + * break; + * default: + * // Error, unknown version returned + * break; + * } + * + */ + +OM_uint32 KRB5_CALLCONV +gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **kctx); + +/* + * Frees the allocated storage associated with an + * exported struct gss_krb5_lucid_context. + */ +OM_uint32 KRB5_CALLCONV +gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, + void *kctx); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h Fri Sep 14 15:01:24 2007 -0700 @@ -6,44 +6,44 @@ /* * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006 by the Massachusetts Institute of Technology, * Cambridge, MA, USA. All Rights Reserved. - * - * This software is being provided to you, the LICENSEE, by the - * Massachusetts Institute of Technology (M.I.T.) under the following - * license. By obtaining, using and/or copying this software, you agree - * that you have read, understood, and will comply with these terms and - * conditions: - * + * + * This software is being provided to you, the LICENSEE, by the + * Massachusetts Institute of Technology (M.I.T.) under the following + * license. By obtaining, using and/or copying this software, you agree + * that you have read, understood, and will comply with these terms and + * conditions: + * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute - * this software and its documentation for any purpose and without fee or - * royalty is hereby granted, provided that you agree to comply with the - * following copyright notice and statements, including the disclaimer, and - * that the same appear on ALL copies of the software and documentation, - * including modifications that you make for internal use or for + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute + * this software and its documentation for any purpose and without fee or + * royalty is hereby granted, provided that you agree to comply with the + * following copyright notice and statements, including the disclaimer, and + * that the same appear on ALL copies of the software and documentation, + * including modifications that you make for internal use or for * distribution: - * - * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS - * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not - * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF - * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF - * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY - * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. - * - * The name of the Massachusetts Institute of Technology or M.I.T. may NOT - * be used in advertising or publicity pertaining to distribution of the - * software. Title to copyright in this software and any associated - * documentation shall at all times remain with M.I.T., and USER agrees to + * + * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS + * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not + * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF + * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF + * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY + * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + * + * The name of the Massachusetts Institute of Technology or M.I.T. may NOT + * be used in advertising or publicity pertaining to distribution of the + * software. Title to copyright in this software and any associated + * documentation shall at all times remain with M.I.T., and USER agrees to * preserve same. * * Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. + */ - /* * Copyright (C) 1998 by the FundsXpress, INC. * @@ -2039,7 +2039,8 @@ /* crypto stuff */ const struct krb5_hash_provider *md5_hash_provider; const struct krb5_enc_provider *arcfour_enc_provider; - krb5_error_code (* krb5_hmac) (krb5_context context, const struct krb5_hash_provider *hash, + krb5_error_code (* krb5_hmac) (krb5_context, + const struct krb5_hash_provider *hash, const krb5_keyblock *key, unsigned int icount, const krb5_data *input, krb5_data *output); @@ -2290,6 +2291,7 @@ * Use krb5_getuid() to select the mechanism to obtain the uid. */ extern uid_t krb5_getuid(); + /* * Referral definitions, debugging hooks, and subfunctions. */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h Fri Sep 14 15:01:24 2007 -0700 @@ -430,4 +430,18 @@ return ((UINT64_TYPE)load_32_le(p+4) << 32) | load_32_le(p); } + +/* Make the interfaces to getpwnam and getpwuid consistent. + Model the wrappers on the POSIX thread-safe versions, but + use the unsafe system versions if the safe ones don't exist + or we can't figure out their interfaces. */ +/* SUNW15resync - just have Solaris relevant ones */ + +#define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ + (*(OUT) = getpwnam_r(NAME,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0) + +#define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ + (*(OUT) = getpwuid_r(UID,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0) + + #endif /* K5_PLATFORM_H */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h --- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h Fri Sep 14 15:01:24 2007 -0700 @@ -37,9 +37,35 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#ifndef _KERNEL /* SUNW14resync, mimic k5-int.h ? */ +#ifdef _KERNEL + +#include + +typedef kmutex_t k5_mutex_t; + +#define K5_MUTEX_PARTIAL_INITIALIZER {0} + +/* ARGSUSED */ +static void k5_mutex_assert_locked(k5_mutex_t *m) { } + +static int +k5_mutex_lock(k5_mutex_t *m) +{ + mutex_enter(m); + return (0); +} + +static int +k5_mutex_unlock(k5_mutex_t *m) +{ + mutex_exit(m); + return(0); +} + + +#else /* _KERNEL */ + #include "autoconf.h" -#endif #ifndef KRB5_CALLCONV # define KRB5_CALLCONV @@ -789,4 +815,7 @@ #define k5_mutex_unlock krb5int_mutex_unlock #endif +#endif /* _KERNEL */ + + #endif /* multiple inclusion? */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c --- a/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c Fri Sep 14 15:01:24 2007 -0700 @@ -20,13 +20,57 @@ #include #include -OM_uint32 krb5_gss_get_context(void ** context); +/** mechglue wrappers **/ + +static OM_uint32 k5glue_delete_sec_context + (void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t, /* output_token */ + OM_uint32); + +static OM_uint32 k5glue_sign + (void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* message_token */ + OM_uint32); + +static OM_uint32 k5glue_verify + (void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int*, /* qop_state */ + OM_uint32); -extern krb5_error_code krb5_ser_context_init - (krb5_context); +/* EXPORT DELETE START */ +static OM_uint32 k5glue_seal + (void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int*, /* conf_state */ + gss_buffer_t, /* output_message_buffer */ + OM_uint32); -extern krb5_error_code krb5_ser_auth_context_init - (krb5_context); +static OM_uint32 k5glue_unseal + (void *, OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int*, /* conf_state */ + int*, /* qop_state */ + OM_uint32); +/* EXPORT DELETE END */ + +static OM_uint32 k5glue_import_sec_context + (void *, OM_uint32 *, /* minor_status */ + gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t *); /* context_handle */ + + static struct gss_config krb5_mechanism = {{9, "\052\206\110\206\367\022\001\002\002"}, @@ -34,31 +78,30 @@ NULL, /* next */ TRUE, /* uses_kmod */ /* EXPORT DELETE START */ /* CRYPT DELETE START */ - krb5_gss_unseal, + k5glue_unseal, /* EXPORT DELETE END */ /* CRYPT DELETE END */ - krb5_gss_delete_sec_context, + k5glue_delete_sec_context, /* EXPORT DELETE START */ /* CRYPT DELETE START */ - krb5_gss_seal, + k5glue_seal, /* EXPORT DELETE END */ /* CRYPT DELETE END */ - krb5_gss_import_sec_context, + k5glue_import_sec_context, /* EXPORT DELETE START */ /* CRYPT DELETE START */ #if 0 /* CRYPT DELETE END */ - krb5_gss_seal, - krb5_gss_unseal, + k5glue_seal, + k5glue_unseal, /* CRYPT DELETE START */ #endif /* CRYPT DELETE END */ /* EXPORT DELETE END */ - krb5_gss_sign, - krb5_gss_verify, -}; + k5glue_sign, + k5glue_verify, + }; static gss_mechanism gss_mech_initialize() { - (void) krb5_gss_get_context(&(krb5_mechanism.context)); return (&krb5_mechanism); } @@ -134,38 +177,110 @@ return (mod_info(&modlinkage, modinfop)); } -OM_uint32 -krb5_gss_get_context(context) -void ** context; +/* ARGSUSED */ +static OM_uint32 +k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token, + gssd_ctx_verifier) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t *context_handle; + gss_buffer_t output_token; + OM_uint32 gssd_ctx_verifier; { - OM_uint32 major_status = 0; + return(krb5_gss_delete_sec_context(minor_status, + context_handle, output_token, + gssd_ctx_verifier)); +} - mutex_lock(&krb5_mutex); - if (context == NULL) - { - major_status = GSS_S_FAILURE; - goto unlock; - } - if (kg_context) { - *context = kg_context; - major_status = GSS_S_COMPLETE; - goto unlock; - } +/* V2 */ +/* ARGSUSED */ +static OM_uint32 +k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle) + void *ctx; + OM_uint32 *minor_status; + gss_buffer_t interprocess_token; + gss_ctx_id_t *context_handle; +{ + return(krb5_gss_import_sec_context(minor_status, + interprocess_token, + context_handle)); +} + +/* EXPORT DELETE START */ +/* V1 only */ +/* ARGSUSED */ +static OM_uint32 +k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, output_message_buffer, gssd_ctx_verifier) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + int qop_req; + gss_buffer_t input_message_buffer; + int *conf_state; + gss_buffer_t output_message_buffer; + OM_uint32 gssd_ctx_verifier; +{ + return(krb5_gss_seal(minor_status, context_handle, + conf_req_flag, qop_req, input_message_buffer, + conf_state, output_message_buffer, gssd_ctx_verifier)); +} +/* EXPORT DELETE END */ - if (krb5_init_context(&kg_context)) - { - major_status = GSS_S_FAILURE; - goto unlock; - } - if (krb5_ser_auth_context_init(kg_context)) - { - kg_context = 0; - major_status = GSS_S_FAILURE; - goto unlock; - } +/* ARGSUSED */ +static OM_uint32 +k5glue_sign(ctx, minor_status, context_handle, + qop_req, message_buffer, + message_token, gssd_ctx_verifier) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int qop_req; + gss_buffer_t message_buffer; + gss_buffer_t message_token; + OM_uint32 gssd_ctx_verifier; +{ + return(krb5_gss_sign(minor_status, context_handle, + qop_req, message_buffer, message_token, gssd_ctx_verifier)); +} - *context = kg_context; -unlock: - mutex_unlock(&krb5_mutex); - return (major_status); +/* EXPORT DELETE START */ +/* ARGSUSED */ +static OM_uint32 +k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer, + output_message_buffer, conf_state, qop_state, gssd_ctx_verifier) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_message_buffer; + gss_buffer_t output_message_buffer; + int *conf_state; + int *qop_state; + OM_uint32 gssd_ctx_verifier; +{ + return(krb5_gss_unseal(minor_status, context_handle, + input_message_buffer, output_message_buffer, + conf_state, qop_state, gssd_ctx_verifier)); } +/* EXPORT DELETE END */ + +/* V1 only */ +/* ARGSUSED */ +static OM_uint32 +k5glue_verify(ctx, minor_status, context_handle, message_buffer, + token_buffer, qop_state, gssd_ctx_verifier) + void *ctx; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t message_buffer; + gss_buffer_t token_buffer; + int *qop_state; + OM_uint32 gssd_ctx_verifier; +{ + return(krb5_gss_verify(minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state, gssd_ctx_verifier)); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -27,71 +27,104 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" +#include "mglueP.h" /* SUNW15resync - for KGSS_ macros */ /* - * $Id: delete_sec_context.c,v 1.15 1998/10/30 02:54:17 marc Exp $ + * $Id: delete_sec_context.c 16465 2004-06-16 02:37:23Z tlyu $ */ + +#ifdef _KERNEL +/* SUNW15resync - todo - unify these kernel rel oid funcs with user spc ones */ + +OM_uint32 +krb5_gss_internal_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + /* + * This function only knows how to release internal OIDs. It will + * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize. + */ + + if ((*oid != gss_mech_krb5) && + (*oid != gss_mech_krb5_old) && + (*oid != gss_mech_krb5_wrong) && + (*oid != gss_nt_krb5_name) && + (*oid != gss_nt_krb5_principal)) { + /* We don't know about this OID */ + return(GSS_S_CONTINUE_NEEDED); + } + else { + *oid = GSS_C_NO_OID; + *minor_status = 0; + return(GSS_S_COMPLETE); + } +} + OM_uint32 -krb5_gss_delete_sec_context(ct, - minor_status, - context_handle, - output_token -#ifdef _KERNEL - , gssd_ctx_verifier -#endif - ) - void *ct; - OM_uint32 *minor_status; - gss_ctx_id_t *context_handle; - gss_buffer_t output_token; -#ifdef _KERNEL - OM_uint32 gssd_ctx_verifier; +generic_gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + if (minor_status) + *minor_status = 0; + + if (*oid == GSS_C_NO_OID) + return(GSS_S_COMPLETE); + + + if ((*oid != GSS_C_NT_USER_NAME) && + (*oid != GSS_C_NT_MACHINE_UID_NAME) && + (*oid != GSS_C_NT_STRING_UID_NAME) && + (*oid != GSS_C_NT_HOSTBASED_SERVICE) && + (*oid != GSS_C_NT_ANONYMOUS) && + (*oid != GSS_C_NT_EXPORT_NAME) && + (*oid != gss_nt_service_name)) { + FREE((*oid)->elements, (*oid)->length); + FREE(*oid, sizeof(gss_OID_desc)); + } + *oid = GSS_C_NO_OID; + return(GSS_S_COMPLETE); +} + +OM_uint32 +krb5_gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + + if (krb5_gss_internal_release_oid(minor_status, oid) != GSS_S_COMPLETE) { + /* Pawn it off on the generic routine */ + return(generic_gss_release_oid(minor_status, oid)); + } + else { + *oid = GSS_C_NO_OID; + *minor_status = 0; + return(GSS_S_COMPLETE); + } +} #endif -{ - OM_uint32 major_status = GSS_S_FAILURE; - - mutex_lock(&krb5_mutex); - - major_status = krb5_gss_delete_sec_context_no_lock(ct, minor_status, - context_handle, output_token -#ifdef _KERNEL - , gssd_ctx_verifier -#endif - ); - mutex_unlock(&krb5_mutex); - return(major_status); - -} /*ARGSUSED*/ OM_uint32 -krb5_gss_delete_sec_context_no_lock(ct, - minor_status, - context_handle, - output_token +krb5_gss_delete_sec_context(minor_status, + context_handle, + output_token #ifdef _KERNEL - , gssd_ctx_verifier + , gssd_ctx_verifier #endif - ) - void *ct; + ) OM_uint32 *minor_status; gss_ctx_id_t *context_handle; gss_buffer_t output_token; #ifdef _KERNEL - OM_uint32 gssd_ctx_verifier; + OM_uint32 gssd_ctx_verifier; #endif { - krb5_context context = ct; + krb5_context context; krb5_gss_ctx_id_rec *ctx; - OM_uint32 major_status = GSS_S_FAILURE; - - /* Solaris Kerberos: we use the global kg_context for MT safe */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif if (output_token) { output_token->length = 0; @@ -101,28 +134,30 @@ /*SUPPRESS 29*/ if (*context_handle == GSS_C_NO_CONTEXT) { *minor_status = 0; - major_status = GSS_S_COMPLETE; - goto out; + return(GSS_S_COMPLETE); } /*SUPPRESS 29*/ /* validate the context handle */ if (! kg_validate_ctx_id(*context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - major_status = GSS_S_NO_CONTEXT; - goto out; + return(GSS_S_NO_CONTEXT); } + ctx = (krb5_gss_ctx_id_t) *context_handle; + context = ctx->k5_context; + /* construct a delete context token if necessary */ if (output_token) { + OM_uint32 major; gss_buffer_desc empty; empty.length = 0; empty.value = NULL; - if ((major_status = kg_seal(context, minor_status, *context_handle, 0, + if ((major = kg_seal(minor_status, *context_handle, 0, GSS_C_QOP_DEFAULT, &empty, NULL, output_token, KG_TOK_DEL_CTX))) - goto out; + return(major); } /* invalidate the context handle */ @@ -131,8 +166,6 @@ /* free all the context state */ - ctx = (krb5_gss_ctx_id_rec *) *context_handle; - if (ctx->seqstate) g_order_free(&(ctx->seqstate)); @@ -149,25 +182,23 @@ if (ctx->subkey) krb5_free_keyblock(context, ctx->subkey); if (ctx->acceptor_subkey) - krb5_free_keyblock(context, ctx->acceptor_subkey); + krb5_free_keyblock(context, ctx->acceptor_subkey); -/* We never import the auth_context into the kernel */ + /* We never import the auth_context into the kernel */ #ifndef _KERNEL if (ctx->auth_context) { - (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL); + if (ctx->cred_rcache) + (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL); + krb5_auth_con_free(context, ctx->auth_context); } #endif - /* Solaris Kerberos: the mech_used element of this structure - * is the actual gss_OID_desc type in gssapiP_krb5.h, and not - * a gss_OID_desc * type, in particular, the gss_release_oid - * is not needed, as the oid is memset to zero below, then freed. - */ - if (ctx->mech_used.length) { - xfree_wrap(ctx->mech_used.elements, ctx->mech_used.length); - /* gss_release_oid(minor_status, &(ctx->mech_used)); */ - } + if (ctx->mech_used) + (void) KGSS_RELEASE_OID(minor_status, &ctx->mech_used); + + if (ctx->k5_context) + krb5_free_context(ctx->k5_context); /* Zero out context */ (void) memset(ctx, 0, sizeof(*ctx)); @@ -178,7 +209,5 @@ *context_handle = GSS_C_NO_CONTEXT; *minor_status = 0; - major_status = GSS_S_COMPLETE; -out: - return(major_status); + return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,17 +1,10 @@ /* - * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" -/* - * Solaris Kerberos: This is identical to MIT Release 1.2.1 except for - * changes to the call kg_get_context to get the context in release and - * getcred. In order to be MT safe, we keep a global variable kg_context - * and do not keep a defcred for default credentials. - */ - /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -61,21 +54,24 @@ */ /* - * $Id: gssapi_krb5.c,v 1.18 1999/03/26 03:51:42 tytso Exp $ + * $Id: gssapi_krb5.c 18131 2006-06-14 22:27:54Z tlyu $ */ -#include -#include + +/* For declaration of krb5_ser_context_init */ +#include "k5-int.h" +#include "gssapiP_krb5.h" /* + * Solaris Kerberos * Kernel kgssd module debugging aid. The global variable "krb5_log" is a bit - * mask which allows various types of log messages to be printed out. + * mask which allows various types of log messages to be printed out. * * The log levels are defined in: * usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h * - * Note, KRB5_LOG_LVL can be assigned via the make invocation. See KRB5_DEFS in - * the various Makefiles. + * Note, KRB5_LOG_LVL can be assigned via the make invocation. + * See KRB5_DEFS in the various Makefiles. */ #ifdef KRB5_LOG_LVL @@ -94,15 +90,12 @@ * The OID of the draft krb5 mechanism, assigned by IETF, is: * iso(1) org(3) dod(5) internet(1) security(5) * kerberosv5(2) = 1.3.5.1.5.2 - * The OID of the krb5_user_name type is: - * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) - * generic(1) user_name(1) = 1.2.840.113554.1.2.1.1 * The OID of the krb5_name type is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) * krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1 * The OID of the krb5_principal type is: - * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) - * krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2 + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2 * The OID of the proposed standard krb5 mechanism is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) * krb5(2) = 1.2.840.113554.1.2.2 @@ -112,13 +105,6 @@ * */ -/* gss_mech_krb5 = 1.2.840.113554.1.2.2 - * gss_mech_krb5_old = 1.3.5.1.5.2 - * gss_mech_krb5_v2 = 1.2.840.113554.1.2.3 - * gss_nt_krb5_name = 1.2.840.113554.1.2.2.1 - * gss_nt_krb5_principal = 1.2.840.113554.1.2.2.2 - */ - /* * Encoding rules: The first two values are encoded in one byte as 40 * * value1 + value2. Subsequent values are encoded base 128, most @@ -126,59 +112,40 @@ * except the last in each value's encoding. */ -/* Global lock for krb5 mechanism */ -#ifdef _KERNEL -kmutex_t krb5_mutex; -#else -mutex_t krb5_mutex; -#endif - -/* krb5 mechanism oids */ - const gss_OID_desc krb5_gss_oid_array[] = { /* this is the official, rfc-specified OID */ - {9, "\052\206\110\206\367\022\001\002\002"}, - /* this is the unofficial, wrong OID */ - {5, "\053\005\001\005\002"}, + {GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID}, + /* this pre-RFC mech OID */ + {GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID}, + /* this is the unofficial, incorrect mech OID emitted by MS */ + {GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID}, /* this is the v2 assigned OID */ {9, "\052\206\110\206\367\022\001\002\003"}, /* these two are name type OID's */ + + /* 2.1.1. Kerberos Principal Name Form: (rfc 1964) + * This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5_name(1)}. The recommended symbolic name for this type + * is "GSS_KRB5_NT_PRINCIPAL_NAME". */ {10, "\052\206\110\206\367\022\001\002\002\001"}, - /* XXX this value isn't defined in an RFC */ + + /* gss_nt_krb5_principal. Object identifier for a krb5_principal. Do not use. */ {10, "\052\206\110\206\367\022\001\002\002\002"}, - /* - * Solaris Kerberos: the following element is the GSS_KRB5_NT_USER_NAME OID - * (1.2.840.113554.1.2.1.1, see RFC 1964) which is used for backward - * compatibility with earlier Solaris kerberos releases. - */ - {10, "\052\206\110\206\367\022\001\002\001\001"}, { 0, 0 } }; -const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0; -const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1; -const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2; - -/* - * Solaris Kerberos: gss_nt_krb5_name points to the GSS_KRB5_NT_USER_NAME OID - * for backwards compat with earlier Solaris Kerberos releases. In MIT this - * points to the GSS_KRB5_NT_PRINCIPAL_NAME OID (1.2.840.113554.1.2.2.1). - */ - -const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+5; - -/* - * XXX gss_nt_krb5_principal points to an OID value that is specific to MIT - * which is not described in any RFC at this point. Be cautious about using - * this. - */ - -const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4; +const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0; +const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1; +const gss_OID_desc * const gss_mech_krb5_wrong = krb5_gss_oid_array+2; +const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+4; +const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+5; +const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+4; static const gss_OID_set_desc oidsets[] = { {1, (gss_OID) krb5_gss_oid_array+0}, {1, (gss_OID) krb5_gss_oid_array+1}, - {2, (gss_OID) krb5_gss_oid_array+0}, + {3, (gss_OID) krb5_gss_oid_array+0}, {1, (gss_OID) krb5_gss_oid_array+2}, {3, (gss_OID) krb5_gss_oid_array+0}, }; @@ -186,107 +153,132 @@ const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0; const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1; const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2; -const gss_OID_set_desc * const gss_mech_set_krb5_v2 = oidsets+3; -const gss_OID_set_desc * const gss_mech_set_krb5_v1v2 = oidsets+4; -void *kg_vdb = NULL; +g_set kg_vdb = G_SET_INIT; /** default credential support */ -/* default credentials */ +#ifndef _KERNEL /* - * Solaris Kerberos: - * We no longer store the defcred in a global variable since this will - * prevent us from assuming different user ids by gss daemon. - * This also makes gss_release_defcred a no-op. + * init_sec_context() will explicitly re-acquire default credentials, + * so handling the expiration/invalidation condition here isn't needed. */ -#if 0 -static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL; -#endif - -krb5_context kg_context = NULL; - -/* XXX what happens when the default credentials expire or are invalidated? */ - -#ifndef _KERNEL - -/* Note, the krb5_mutex lock must be held prior to calling this function */ OM_uint32 kg_get_defcred(minor_status, cred) OM_uint32 *minor_status; gss_cred_id_t *cred; { -OM_uint32 major; - - KRB5_LOG0(KRB5_INFO, "kg_get_defcred() start\n"); - - if (!kg_context && GSS_ERROR(kg_get_context(minor_status,&kg_context))){ - KRB5_LOG(KRB5_ERR, "kg_get_defcred() end, error, kg_get_context() " - "minor_status=%d\n", *minor_status); - return GSS_S_FAILURE; + OM_uint32 major; + + if ((major = krb5_gss_acquire_cred(minor_status, + (gss_name_t) NULL, GSS_C_INDEFINITE, + GSS_C_NULL_OID_SET, GSS_C_INITIATE, + cred, NULL, NULL)) && GSS_ERROR(major)) { + return(major); } - - major = krb5_gss_acquire_cred_no_lock(kg_context,minor_status, - (gss_name_t) NULL, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_INITIATE, - cred, NULL, NULL); - if (major && GSS_ERROR(major)) { - *cred = GSS_C_NO_CREDENTIAL; - KRB5_LOG(KRB5_ERR, "kg_get_defcred() end, error major=%d\n", major); - return(major); - } - *minor_status = 0; - KRB5_LOG0(KRB5_INFO, "kg_get_defcred() end\n"); return(GSS_S_COMPLETE); } OM_uint32 -kg_release_defcred(minor_status) - OM_uint32 *minor_status; +kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status) { - *minor_status = 0; - return(GSS_S_COMPLETE); + OM_uint32 err = 0; + + /* + * Sync up the context ccache name with the GSSAPI ccache name. + * If kg_ccache_name is NULL -- normal unless someone has called + * gss_krb5_ccache_name() -- then the system default ccache will + * be picked up and used by resetting the context default ccache. + * This is needed for platforms which support multiple ccaches. + */ + + if (!err) { + /* if NULL, resets the context default ccache */ + err = krb5_cc_set_default_name(context, + (char *) k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME)); + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; } OM_uint32 -kg_get_context(minor_status, context) - OM_uint32 *minor_status; - krb5_context *context; +kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name) { - /* - * Solaris Kerberos: the following is a global variable declared - * above and initialized here below - */ - /* static krb5_context kg_context = NULL; */ - krb5_error_code code; + const char *name = NULL; + OM_uint32 err = 0; + char *kg_ccache_name; + + kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME); + + if (kg_ccache_name != NULL) { + name = strdup(kg_ccache_name); + if (name == NULL) + err = errno; + } else { + krb5_context context = NULL; - KRB5_LOG0(KRB5_INFO, "kg_get_context() start\n"); + /* Reset the context default ccache (see text above), and then + retrieve it. */ + err = krb5_gss_init_context(&context); + if (!err) + err = krb5_cc_set_default_name (context, NULL); + if (!err) { + name = krb5_cc_default_name(context); + if (name) { + name = strdup(name); + if (name == NULL) + err = errno; + } + } + if (context) + krb5_free_context(context); + } - if (!kg_context) { - if ((code = krb5_init_context(&kg_context))) - goto fail; - if ((code = krb5_ser_context_init(kg_context))) - goto fail; - if ((code = krb5_ser_auth_context_init(kg_context))) - goto fail; - if ((code = krb5_ser_ccache_init(kg_context))) - goto fail; - if ((code = krb5_ser_rcache_init(kg_context))) - goto fail; - if ((code = krb5_ser_keytab_init(kg_context))) - goto fail; - if ((code = krb5_ser_auth_context_init(kg_context))) - goto fail; - } - *context = kg_context; - *minor_status = 0; - KRB5_LOG0(KRB5_INFO, "kg_get_context() end\n"); - return GSS_S_COMPLETE; - -fail: - *minor_status = (OM_uint32) code; - KRB5_LOG(KRB5_ERR, "kg_get_context() end, error code=%d\n", code); - return GSS_S_FAILURE; + if (!err) { + if (out_name) { + *out_name = name; + } + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; +} + +OM_uint32 +kg_set_ccache_name (OM_uint32 *minor_status, const char *name) +{ + char *new_name = NULL; + char *swap = NULL; + char *kg_ccache_name; + krb5_error_code kerr; + + if (name) { + new_name = malloc(strlen(name) + 1); + if (new_name == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + strcpy(new_name, name); + } + + kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME); + swap = kg_ccache_name; + kg_ccache_name = new_name; + new_name = swap; + kerr = k5_setspecific(K5_KEY_GSS_KRB5_CCACHE_NAME, kg_ccache_name); + if (kerr != 0) { + /* Can't store, so free up the storage. */ + free(kg_ccache_name); + /* ??? free(new_name); */ + *minor_status = kerr; + return GSS_S_FAILURE; + } + + free (new_name); + *minor_status = 0; + return GSS_S_COMPLETE; } #endif diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -8,7 +8,7 @@ /* * lib/gssapi/krb5/import_sec_context.c * - * Copyright 1995 by the Massachusetts Institute of Technology. + * Copyright 1995,2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -35,21 +35,22 @@ /* * import_sec_context.c - Internalize the security context. */ -#include -#include -#include +#include "gssapiP_krb5.h" +/* for serialization initialization functions */ +#include "k5-int.h" +#include "mglueP.h" /* SUNW15resync - for KGSS_ macros */ + +#ifdef _KERNEL +extern OM_uint32 kgss_release_oid(OM_uint32 *, gss_OID *); +#endif + /* * Fix up the OID of the mechanism so that uses the static version of * the OID if possible. - * - * Solaris Kerberos: this is not necessary. Our mech_used is allocated - * as part of the context structure. This function attempts to point to - * the corresponding gss_OID in the array krb5_gss_oid_array. */ -#if 0 -gss_OID_desc krb5_gss_convert_static_mech_oid(oid) - gss_OID FAR oid; +gss_OID krb5_gss_convert_static_mech_oid(oid) + gss_OID oid; { const gss_OID_desc *p; OM_uint32 minor_status; @@ -57,17 +58,34 @@ for (p = krb5_gss_oid_array; p->length; p++) { if ((oid->length == p->length) && (memcmp(oid->elements, p->elements, p->length) == 0)) { - gss_release_oid(&minor_status, &oid); - return *p; + (void) KGSS_RELEASE_OID(&minor_status, &oid); + return (gss_OID) p; } } - return *oid; + return oid; } + +krb5_error_code +krb5_gss_ser_init (krb5_context context) +{ + krb5_error_code code; + static krb5_error_code (KRB5_CALLCONV *const fns[])(krb5_context) = { + krb5_ser_auth_context_init, +#ifndef _KERNEL + krb5_ser_context_init, + krb5_ser_ccache_init, krb5_ser_rcache_init, krb5_ser_keytab_init, #endif + }; + int i; + + for (i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) + if ((code = (fns[i])(context)) != 0) + return code; + return 0; +} OM_uint32 -krb5_gss_import_sec_context(ct, minor_status, interprocess_token, context_handle) - void *ct; +krb5_gss_import_sec_context(minor_status, interprocess_token, context_handle) OM_uint32 *minor_status; gss_buffer_t interprocess_token; gss_ctx_id_t *context_handle; @@ -78,16 +96,22 @@ krb5_gss_ctx_id_t ctx; krb5_octet *ibp; - /* Solaris Kerberos: we use the global kg_context for MT safe */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif + /* This is a bit screwy. We create a krb5 context because we need + one when calling the serialization code. However, one of the + objects we're unpacking is a krb5 context, so when we finish, + we can throw this one away. */ + kret = KGSS_INIT_CONTEXT(&context); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } - KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() start\n"); - - mutex_lock(&krb5_mutex); - context = ct; + kret = krb5_gss_ser_init(context); + if (kret) { + krb5_free_context(context); + *minor_status = kret; + return GSS_S_FAILURE; + } /* Assume a tragic failure */ ctx = (krb5_gss_ctx_id_t) NULL; @@ -96,56 +120,39 @@ /* Internalize the context */ ibp = (krb5_octet *) interprocess_token->value; blen = (size_t) interprocess_token->length; - if ((kret = kg_ctx_internalize(context, - (krb5_pointer *) &ctx, - &ibp, &blen))) { + kret = kg_ctx_internalize(context, (krb5_pointer *) &ctx, &ibp, &blen); + /* + * SUNW15resync + * + * krb5_free_context(context); + * Previous versions of MIT(1.2ish)/Solaris did not serialize the + * k5_context but MIT 1.5 does. But we don't need all the userspace + * junk in the kernel so we continue to not serialize it. + * So we keep this context live here (see it's use in kg_ctx_internalize) + * and it will get freed by delete_sec_context. + */ + if (kret) { + krb5_free_context(context); *minor_status = (OM_uint32) kret; - mutex_unlock(&krb5_mutex); - - KRB5_LOG(KRB5_ERR, "krb5_gss_import_sec_context() end," - "kg_ctx_internalize() error kret = %d\n", kret); - - if (kret == ENOMEM) - return(GSS_S_FAILURE); - else - return(GSS_S_DEFECTIVE_TOKEN); + return(GSS_S_FAILURE); } /* intern the context handle */ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { - (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, + (void)krb5_gss_delete_sec_context(minor_status, (gss_ctx_id_t *) &ctx, NULL #ifdef _KERNEL - ,0 /* gssd_ctx_verifier */ + ,0 /* gssd_ctx_verifier */ #endif ); *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); - - KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end," - "kg_save_ctx_id() error\n"); - return(GSS_S_FAILURE); } - if (! kg_validate_ctx_id((gss_ctx_id_t) ctx)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); - KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end," - "kg_validate_ctx_id() error\n"); - - return(GSS_S_FAILURE); - } - - /* Solaris Kerberos: our mech_used is part of the ctx structure */ - /* ctx->mech_used = krb5_gss_convert_static_mech_oid(&(ctx->mech_used)); */ - + ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used); + *context_handle = (gss_ctx_id_t) ctx; *minor_status = 0; - mutex_unlock(&krb5_mutex); - - KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() end\n"); - return (GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c Fri Sep 14 15:01:24 2007 -0700 @@ -57,7 +57,7 @@ #include static krb5_error_code -make_seal_token_v1 PROTOTYPE((krb5_context context, +make_seal_token_v1 (krb5_context context, krb5_keyblock *enc, krb5_keyblock *seq, gssint_uint64 *seqnum, @@ -70,7 +70,7 @@ int encrypt, int toktype, int bigend, - gss_OID oid)); + gss_OID oid); static krb5_error_code make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, @@ -398,9 +398,8 @@ and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ OM_uint32 -kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, +kg_seal(minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, toktype) - krb5_context context; OM_uint32 *minor_status; gss_ctx_id_t context_handle; int conf_req_flag; @@ -413,6 +412,7 @@ krb5_gss_ctx_id_rec *ctx; krb5_error_code code; krb5_timestamp now; + krb5_context context; KRB5_LOG0(KRB5_INFO, "kg_seal() start"); @@ -446,6 +446,7 @@ return(GSS_S_NO_CONTEXT); } + context = ctx->k5_context; if ((code = krb5_timeofday(context, &now))) { *minor_status = code; KRB5_LOG(KRB5_ERR, "kg_seal() end, krb5_timeofday() error code=%d\n", code); @@ -460,7 +461,7 @@ input_message_buffer, output_message_buffer, ctx->signalg, ctx->cksum_size, ctx->sealalg, conf_req_flag, toktype, ctx->big_endian, - &ctx->mech_used); + ctx->mech_used); break; case 1: code = gss_krb5int_make_seal_token_v3(context, ctx, diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c Fri Sep 14 15:01:24 2007 -0700 @@ -91,6 +91,9 @@ int key_usage; unsigned char acceptor_flag; const gss_buffer_desc *message2 = message; +#ifdef CFX_EXERCISE + size_t rrc; +#endif size_t ec; unsigned short tok_id; krb5_checksum sum; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c Fri Sep 14 15:01:24 2007 -0700 @@ -394,7 +394,7 @@ } if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, - (g_OID_equal(&ctx->mech_used, gss_mech_krb5_old) ? + (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? ctx->seq->contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { xfree_wrap(md5cksum.contents, md5cksum.length); @@ -638,9 +638,8 @@ conf_state is only valid if SEAL. */ OM_uint32 -kg_unseal(context, minor_status, context_handle, input_token_buffer, +kg_unseal(minor_status, context_handle, input_token_buffer, message_buffer, conf_state, qop_state, toktype) - krb5_context context; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t input_token_buffer; @@ -696,7 +695,7 @@ } else toktype2 = toktype; - err = g_verify_token_header(&ctx->mech_used, + err = g_verify_token_header(ctx->mech_used, (uint32_t *)&bodysize, &ptr, toktype2, input_token_buffer->length, !ctx->proto); @@ -708,12 +707,12 @@ if (ctx->proto == 0) { - err = kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, + err = kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize, message_buffer, conf_state, qop_state, toktype); } else { - err = gss_krb5int_unseal_token_v3(context, minor_status, ctx, + err = gss_krb5int_unseal_token_v3(ctx->k5_context, minor_status, ctx, ptr, bodysize, message_buffer, conf_state, qop_state, toktype); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/seal.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/seal.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/seal.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,7 +1,7 @@ /* EXPORT DELETE START */ /* - * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,21 +29,21 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: seal.c,v 1.11 1996/07/22 20:34:29 marc Exp $ + * $Id: seal.c 16171 2004-03-15 17:45:01Z raeburn $ */ + /*ARGSUSED*/ OM_uint32 -krb5_gss_seal(ctx, minor_status, context_handle, conf_req_flag, +krb5_gss_seal(minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer #ifdef _KERNEL - , gssd_ctx_verifier + , gssd_ctx_verifier #endif -) - void *ctx; + ) OM_uint32 *minor_status; gss_ctx_id_t context_handle; int conf_req_flag; @@ -52,56 +52,29 @@ int *conf_state; gss_buffer_t output_message_buffer; #ifdef _KERNEL - OM_uint32 gssd_ctx_verifier; + OM_uint32 gssd_ctx_verifier; #endif { - krb5_context context; - OM_uint32 status; - #ifdef KRB5_NO_PRIVACY - /* - * conf_req_flag must be zero; - * encryption is disallowed - * for global version - */ - if (conf_req_flag) - return (GSS_S_FAILURE); -#endif - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); + /* + * conf_req_flag must be zero; + * encryption is disallowed + * for global version + */ + if (conf_req_flag) + return (GSS_S_FAILURE); #endif - - mutex_lock(&krb5_mutex); - context = ctx; - status = kg_seal(context, minor_status, context_handle, conf_req_flag, + + return(kg_seal(minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, - output_message_buffer, KG_TOK_SEAL_MSG); - mutex_unlock(&krb5_mutex); -#ifdef KRB5_NO_PRIVACY - /* - * Can't be paranoid enough; - * if someone plugs in their version of kg_seal - * that does encryption we want to - * disallow that too. - */ - if (conf_state && *conf_state) - return (GSS_S_FAILURE); - -#endif - return(status); + output_message_buffer, KG_TOK_SEAL_MSG)); } /* V2 interface */ -/*ARGSUSED*/ OM_uint32 -krb5_gss_wrap(ctx, minor_status, context_handle, conf_req_flag, +krb5_gss_wrap(minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer) - void *ctx; OM_uint32 *minor_status; gss_ctx_id_t context_handle; int conf_req_flag; @@ -111,25 +84,12 @@ gss_buffer_t output_message_buffer; { #ifdef KRB5_NO_PRIVACY - return (GSS_S_FAILURE); + return (GSS_S_FAILURE); #else - krb5_context context; - OM_uint32 status; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ctx; - status = kg_seal(context, minor_status, context_handle, conf_req_flag, + return(kg_seal(minor_status, context_handle, conf_req_flag, (int) qop_req, input_message_buffer, conf_state, - output_message_buffer, KG_TOK_WRAP_MSG); - mutex_unlock(&krb5_mutex); - return(status); + output_message_buffer, KG_TOK_WRAP_MSG)); #endif } + /* EXPORT DELETE END */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -8,7 +8,7 @@ /* * lib/gssapi/krb5/ser_sctx.c * - * Copyright 1995 by the Massachusetts Institute of Technology. + * Copyright 1995, 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -35,12 +35,11 @@ /* * ser_sctx.c - Handle [de]serialization of GSSAPI security context. */ - -/* Solaris Kerberos: order is important here. include gssapiP_krb5.h - * before all others, otherwise we get a LINT error from MALLOC macro - * being redefined in mechglueP.h */ -#include -#include + /* Solaris Kerberos: order is important here. include gssapiP_krb5.h + * before all others, otherwise we get a LINT error from MALLOC macro + * being redefined in mechglueP.h */ +#include "gssapiP_krb5.h" +#include "k5-int.h" /* * This module contains routines to [de]serialize @@ -64,18 +63,18 @@ { gss_OID oid = (gss_OID) arg; krb5_error_code err; - + err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); if (err) - return err; + return err; err = krb5_ser_pack_int32((krb5_int32) oid->length, - buffer, lenremain); + buffer, lenremain); if (err) - return err; + return err; err = krb5_ser_pack_bytes((krb5_octet *) oid->elements, - oid->length, buffer, lenremain); + oid->length, buffer, lenremain); if (err) - return err; + return err; err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); return err; } @@ -88,12 +87,7 @@ krb5_octet **buffer; size_t *lenremain; { - /* Solaris Kerberos: note that by copying the argp pointer directly here, - * we avoid doing all the MALLOC and FREE calls later. - * Don't forget that when argp is ctx->mech_used, then this memory was - * already allocated. - */ - gss_OID oid = (gss_OID)argp; + gss_OID oid; krb5_int32 ibuf; krb5_octet *bp; size_t remain; @@ -107,48 +101,48 @@ if (ibuf != KV5M_GSS_OID) return (EINVAL); -/* oid = (gss_OID) MALLOC(sizeof(gss_OID_desc)); + + oid = (gss_OID) MALLOC(sizeof(gss_OID_desc)); if (oid == NULL) return ENOMEM; -*/ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { - return EINVAL; + FREE(oid, sizeof(gss_OID_desc)); + return EINVAL; } oid->length = ibuf; oid->elements = MALLOC(ibuf); - if (oid->elements == NULL) { - oid->length = 0; - return (ENOMEM); + if (oid->elements == 0) { + FREE(oid, sizeof(gss_OID_desc)); + return ENOMEM; } - if (krb5_ser_unpack_bytes((krb5_octet *) oid->elements, - oid->length, &bp, &remain)) { + oid->length, &bp, &remain)) { FREE(oid->elements, oid->length); - oid->length = 0; - return (EINVAL); + FREE(oid, sizeof(gss_OID_desc)); + return EINVAL; } /* Read in and check our trailing magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { - FREE (oid->elements, oid->length); - oid->length = 0; - return (EINVAL); + FREE(oid->elements, oid->length); + FREE(oid, sizeof(gss_OID_desc)); + return (EINVAL); } if (ibuf != KV5M_GSS_OID) { - FREE (oid->elements, oid->length); - oid->length = 0; - return (EINVAL); + FREE(oid->elements, oid->length); + FREE(oid, sizeof(gss_OID_desc)); + return (EINVAL); } *buffer = bp; *lenremain = remain; - /* *argp = (krb5_pointer) oid; */ + *argp = (krb5_pointer) oid; return 0; } + /*ARGSUSED*/ -krb5_error_code +static krb5_error_code kg_oid_size(kcontext, arg, sizep) krb5_context kcontext; krb5_pointer arg; @@ -159,8 +153,8 @@ size_t required; kret = EINVAL; - oid = (gss_OID) arg; - if (oid) { + /*LINTED*/ + if ((oid = (gss_OID) arg)) { required = 2*sizeof(krb5_int32); /* For the header and trailer */ required += sizeof(krb5_int32); required += oid->length; @@ -201,7 +195,7 @@ krb5_int32 ibuf; krb5_octet *bp; size_t remain; - krb5_error_code err; + krb5_error_code err; bp = *buffer; remain = *lenremain; @@ -215,21 +209,26 @@ err = g_queue_internalize(argp, &bp, &remain); if (err) - return err; + return err; /* Read in and check our trailing magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - return (EINVAL); + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { + g_order_free(argp); + return (EINVAL); + } - if (ibuf != KV5M_GSS_QUEUE) + if (ibuf != KV5M_GSS_QUEUE) { + g_order_free(argp); return (EINVAL); + } *buffer = bp; *lenremain = remain; return 0; } + /*ARGSUSED*/ -krb5_error_code +static krb5_error_code kg_queue_size(kcontext, arg, sizep) krb5_context kcontext; krb5_pointer arg; @@ -262,44 +261,42 @@ krb5_gss_ctx_id_rec *ctx; size_t required; - KRB5_LOG0(KRB5_INFO, "kg_ctx_size() start \n"); - /* * krb5_gss_ctx_id_rec requires: - * krb5_int32 for KG_CONTEXT - * krb5_int32 for initiate. - * krb5_int32 for established. - * krb5_int32 for big_endian. - * krb5_int32 for have_acceptor_subkey. - * krb5_int32 for seed_init. - * krb5_int32 for gss_flags. - * sizeof(seed) for seed - * krb5_int32 for signalg. - * krb5_int32 for cksum_size. - * krb5_int32 for sealalg. - * krb5_int32 for endtime. - * krb5_int32 for flags. - * krb5_int64 for seq_send. - * krb5_int64 for seq_recv. - * ... for mech_used - * ... for here - * ... for there - * ... for subkey - * ... for enc - * ... for seq - * ... for seqstate - * ... for auth_context - * krb5_int32 for proto - * krb5_int32 for cksumtype - * ... for acceptor_subkey - * krb5_int32 for acceptor_key_cksumtype - * krb5_int32 for trailer. + * krb5_int32 for KG_CONTEXT + * krb5_int32 for initiate. + * krb5_int32 for established. + * krb5_int32 for big_endian. + * krb5_int32 for have_acceptor_subkey. + * krb5_int32 for seed_init. + * krb5_int32 for gss_flags. + * sizeof(seed) for seed + * ... for here + * ... for there + * ... for subkey + * krb5_int32 for signalg. + * krb5_int32 for cksum_size. + * krb5_int32 for sealalg. + * ... for enc + * ... for seq + * krb5_int32 for endtime. + * krb5_int32 for flags. + * krb5_int64 for seq_send. + * krb5_int64 for seq_recv. + * ... for seqstate + * ... for auth_context + * ... for mech_used + * krb5_int32 for proto + * krb5_int32 for cksumtype + * ... for acceptor_subkey + * krb5_int32 for acceptor_key_cksumtype + * krb5_int32 for cred_rcache + * krb5_int32 for trailer. */ - kret = EINVAL; - ctx = (krb5_gss_ctx_id_rec *) arg; - if (ctx) { - required = 16*sizeof(krb5_int32); + /*LINTED*/ + if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { + required = 17*sizeof(krb5_int32); required += 2*sizeof(krb5_int64); required += sizeof(ctx->seed); @@ -336,28 +333,33 @@ if (!kret) kret = kg_oid_size(kcontext, - (krb5_pointer) &ctx->mech_used, + (krb5_pointer) ctx->mech_used, &required); if (!kret && ctx->seqstate) kret = kg_queue_size(kcontext, ctx->seqstate, &required); + #ifndef PROVIDE_KERNEL_IMPORT if (!kret) kret = krb5_size_opaque(kcontext, + KV5M_CONTEXT, + (krb5_pointer) ctx->k5_context, + &required); + if (!kret) + kret = krb5_size_opaque(kcontext, KV5M_AUTH_CONTEXT, (krb5_pointer) ctx->auth_context, &required); #endif + if (!kret && ctx->acceptor_subkey) - kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->acceptor_subkey, - &required); - + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->acceptor_subkey, + &required); if (!kret) *sizep += required; } - KRB5_LOG1(KRB5_INFO, "kg_ctx_size() end, kret = %d required = %lu\n", kret, required); return(kret); } @@ -376,16 +378,20 @@ size_t required; krb5_octet *bp; size_t remain; - /* SOLARIS KERBEROS: do not use accessor */ +#ifndef _KERNEL + krb5int_access kaccess; - KRB5_LOG0(KRB5_INFO, "kg_ctx_externalize() start\n"); + kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); + if (kret) + return(kret); +#endif required = 0; bp = *buffer; remain = *lenremain; kret = EINVAL; - ctx = (krb5_gss_ctx_id_rec *) arg; - if (ctx) { + /*LINTED*/ + if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { kret = ENOMEM; if (!kg_ctx_size(kcontext, arg, &required) && (required <= remain)) { @@ -393,21 +399,21 @@ (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); /* Now static data */ - (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate, - &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->established, - &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, - &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey, - &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init, - &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags, - &bp, &remain); - (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed, - sizeof(ctx->seed), - &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->established, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags, + &bp, &remain); + (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed, + sizeof(ctx->seed), + &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->signalg, &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->cksum_size, @@ -418,16 +424,23 @@ &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_flags, &bp, &remain); +#ifndef _KERNEL + (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_send, + &bp, &remain); + (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_recv, + &bp, &remain); +#else (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_send, &bp, &remain); (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_recv, &bp, &remain); +#endif /* Now dynamic data */ kret = 0; - if (!kret && &(ctx->mech_used)) - kret = kg_oid_externalize(kcontext, &(ctx->mech_used), + if (!kret && ctx->mech_used) + kret = kg_oid_externalize(kcontext, ctx->mech_used, &bp, &remain); if (!kret && ctx->here) @@ -467,34 +480,42 @@ #ifndef PROVIDE_KERNEL_IMPORT if (!kret) kret = krb5_externalize_opaque(kcontext, + KV5M_CONTEXT, + (krb5_pointer) ctx->k5_context, + &bp, &remain); + if (!kret) + kret = krb5_externalize_opaque(kcontext, KV5M_AUTH_CONTEXT, (krb5_pointer) ctx->auth_context, &bp, &remain); #endif - if (!kret) + if (!kret) kret = krb5_ser_pack_int32((krb5_int32) ctx->proto, - &bp, &remain); - if (!kret) + &bp, &remain); + if (!kret) kret = krb5_ser_pack_int32((krb5_int32) ctx->cksumtype, - &bp, &remain); - if (!kret && ctx->acceptor_subkey) + &bp, &remain); + if (!kret && ctx->acceptor_subkey) kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->acceptor_subkey, - &bp, &remain); - if (!kret) + KV5M_KEYBLOCK, + (krb5_pointer) ctx->acceptor_subkey, + &bp, &remain); + if (!kret) kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype, - &bp, &remain); + &bp, &remain); if (!kret) - (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); + kret = krb5_ser_pack_int32((krb5_int32) ctx->cred_rcache, + &bp, &remain); + /* trailer */ + if (!kret) + kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); if (!kret) { *buffer = bp; *lenremain = remain; } } } - KRB5_LOG(KRB5_INFO, "kg_ctx_externalize() end, kret = %d\n", kret); return(kret); } @@ -513,8 +534,13 @@ krb5_int32 ibuf; krb5_octet *bp; size_t remain; +#ifndef _KERNEL + krb5int_access kaccess; - KRB5_LOG0(KRB5_INFO, "kg_ctx_internalize() start\n"); + kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); + if (kret) + return(kret); +#endif bp = *buffer; remain = *lenremain; @@ -526,26 +552,28 @@ kret = ENOMEM; /* Get a context */ - if ((remain >= (16*sizeof(krb5_int32) + if ((remain >= (17*sizeof(krb5_int32) + 2*sizeof(krb5_int64) + sizeof(ctx->seed))) && (ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))) { (void) memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); + ctx->k5_context = kcontext; + /* Get static data */ - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->initiate = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->established = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->big_endian = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->have_acceptor_subkey = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->seed_init = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->gss_flags = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->initiate = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->established = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->big_endian = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->have_acceptor_subkey = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->seed_init = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->gss_flags = (int) ibuf; (void) krb5_ser_unpack_bytes((krb5_octet *) ctx->seed, sizeof(ctx->seed), &bp, &remain); @@ -559,11 +587,23 @@ ctx->endtime = (krb5_timestamp) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->krb_flags = (krb5_flags) ibuf; - (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_send), &bp, &remain); - (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_recv), &bp, &remain); +#ifndef _KERNEL + (void) (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_send, &bp, &remain); + kret = (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_recv, &bp, &remain); +#else + (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_send), + &bp, &remain); + kret = krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_recv), + &bp, &remain); +#endif + if (kret) { + xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec)); + return kret; + } + if ((kret = kg_oid_internalize(kcontext, - (krb5_pointer)&ctx->mech_used, &bp, - &remain))) { + (krb5_pointer *) &ctx->mech_used, &bp, + &remain))) { if (kret == EINVAL) kret = 0; } @@ -614,8 +654,15 @@ if (kret == EINVAL) kret = 0; } + #ifndef PROVIDE_KERNEL_IMPORT - if (!kret) + if (!kret) + kret = krb5_internalize_opaque(kcontext, + KV5M_CONTEXT, + (krb5_pointer *) &ctx->k5_context, + &bp, &remain); + + if (!kret) kret = krb5_internalize_opaque(kcontext, KV5M_AUTH_CONTEXT, (krb5_pointer *) &ctx->auth_context, @@ -633,26 +680,26 @@ (krb5_pointer *) &ctx->acceptor_subkey, &bp, &remain))) { if (kret == EINVAL) - kret = 0; - } - if (!kret) + kret = 0; + } + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->cred_rcache = ibuf; + if (!kret) kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->acceptor_subkey_cksumtype = ibuf; -done: + ctx->acceptor_subkey_cksumtype = ibuf; + /* Get trailer */ - if (!kret) + if (!kret) kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); - - if (!kret && ibuf != KG_CONTEXT) + if (!kret && ibuf != KG_CONTEXT) kret = EINVAL; - if (!kret) { + if (!kret) { *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) ctx; } else { - if (!kret && (ibuf != KG_CONTEXT)) - kret = EINVAL; if (ctx->seq) krb5_free_keyblock(kcontext, ctx->seq); if (ctx->enc) @@ -667,8 +714,5 @@ } } } - - KRB5_LOG(KRB5_INFO, "kg_ctx_internalize() end kret = %d\n", kret); - return(kret); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -27,79 +27,46 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: sign.c,v 1.11 1996/07/22 20:34:35 marc Exp $ + * $Id: sign.c 16171 2004-03-15 17:45:01Z raeburn $ */ + /*ARGSUSED*/ - OM_uint32 -krb5_gss_sign(ctx, minor_status, context_handle, +krb5_gss_sign(minor_status, context_handle, qop_req, message_buffer, message_token #ifdef _KERNEL - , gssd_ctx_verifier + , gssd_ctx_verifier #endif - ) - void *ctx; + ) OM_uint32 *minor_status; gss_ctx_id_t context_handle; int qop_req; gss_buffer_t message_buffer; gss_buffer_t message_token; #ifdef _KERNEL - OM_uint32 gssd_ctx_verifier; + OM_uint32 gssd_ctx_verifier; #endif { - krb5_context context; - OM_uint32 status; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - - context = ctx; - status = kg_seal(context, minor_status, context_handle, 0, + return(kg_seal(minor_status, context_handle, 0, qop_req, message_buffer, NULL, - message_token, KG_TOK_SIGN_MSG); - mutex_unlock(&krb5_mutex); - return(status); + message_token, KG_TOK_SIGN_MSG)); } /* V2 interface */ OM_uint32 -krb5_gss_get_mic(ctx, minor_status, context_handle, qop_req, +krb5_gss_get_mic(minor_status, context_handle, qop_req, message_buffer, message_token) - void *ctx; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_qop_t qop_req; gss_buffer_t message_buffer; gss_buffer_t message_token; { - krb5_context context; - OM_uint32 status; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - - context = ctx; - - status = kg_seal(context, minor_status, context_handle, 0, + return(kg_seal(minor_status, context_handle, 0, (int) qop_req, message_buffer, NULL, - message_token, KG_TOK_MIC_MSG); - mutex_unlock(&krb5_mutex); - return(status); + message_token, KG_TOK_MIC_MSG)); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,7 +1,7 @@ /* EXPORT DELETE START */ /* - * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,21 +29,21 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: unseal.c,v 1.10 1996/07/22 20:34:37 marc Exp $ + * $Id: unseal.c 16171 2004-03-15 17:45:01Z raeburn $ */ + /*ARGSUSED*/ OM_uint32 -krb5_gss_unseal(ctx, minor_status, context_handle, +krb5_gss_unseal(minor_status, context_handle, input_message_buffer, output_message_buffer, conf_state, qop_state #ifdef _KERNEL - , gssd_ctx_verifier + , gssd_ctx_verifier #endif - ) - void *ctx; + ) OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t input_message_buffer; @@ -51,45 +51,19 @@ int *conf_state; int *qop_state; #ifdef _KERNEL - OM_uint32 gssd_ctx_verifier; + OM_uint32 gssd_ctx_verifier; #endif { - krb5_context context; - OM_uint32 status; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ctx; - status = kg_unseal(context, minor_status, context_handle, + return(kg_unseal(minor_status, context_handle, input_message_buffer, output_message_buffer, - conf_state, qop_state, KG_TOK_SEAL_MSG); - mutex_unlock(&krb5_mutex); -#ifdef KRB5_NO_PRIVACY - /* - * Can't be paranoid enough; - * if someone plugs in their version of kg_unseal - * that does decryption we want to - * disallow that too. - */ - if (conf_state && *conf_state) - return (GSS_S_FAILURE); -#endif - return(status); + conf_state, qop_state, KG_TOK_SEAL_MSG)); } /* V2 interface */ -/*ARGSUSED*/ OM_uint32 -krb5_gss_unwrap(ctx, minor_status, context_handle, +krb5_gss_unwrap(minor_status, context_handle, input_message_buffer, output_message_buffer, conf_state, qop_state) - void *ctx; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t input_message_buffer; @@ -98,29 +72,18 @@ gss_qop_t *qop_state; { #ifdef KRB5_NO_PRIVACY - return (GSS_S_FAILURE); + return (GSS_S_FAILURE); #else - OM_uint32 rstat; - int qstate; - krb5_context context; + OM_uint32 rstat; + int qstate; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ctx; - - rstat = kg_unseal(context, minor_status, context_handle, - input_message_buffer, output_message_buffer, - conf_state, &qstate, KG_TOK_WRAP_MSG); - if (!rstat && qop_state) + rstat = kg_unseal(minor_status, context_handle, + input_message_buffer, output_message_buffer, + conf_state, &qstate, KG_TOK_WRAP_MSG); + if (!rstat && qop_state) *qop_state = (gss_qop_t) qstate; - mutex_unlock(&krb5_mutex); - return(rstat); + return(rstat); #endif } + /* EXPORT DELETE END */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -122,7 +122,7 @@ krb5_pointer iv; krb5_pointer in; krb5_pointer out; - int length; + unsigned int length; { krb5_error_code code; size_t blocksize; @@ -169,7 +169,7 @@ krb5_pointer iv; krb5_pointer in; krb5_pointer out; - int length; + unsigned int length; { krb5_error_code code; size_t blocksize; diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,6 +32,12 @@ */ /* + * SUNW15resync + * Left this alone (MIT version causes STC gss_verify_mic(6) test failure) + * as it has bug fixes that MIT does not yet. + */ + +/* * functions to check sequence numbers for replay and sequencing */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,5 @@ #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -21,11 +22,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include - -/* - * $Id: util_seed.c,v 1.13.6.1 2000/05/31 17:17:39 raeburn Exp $ - */ +#include "gssapiP_krb5.h" +#ifdef HAVE_MEMORY_H +#include +#endif static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; @@ -39,7 +39,8 @@ krb5_keyblock *tmpkey; int i; - if (code = krb5_copy_keyblock(context, key, &tmpkey)) + code = krb5_copy_keyblock(context, key, &tmpkey); + if (code) return(code); /* reverse the key bytes, as per spec */ diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" + /* + * Copyright2001 by the Massachusetts Institute of Technology. * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -21,10 +23,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" +#include "k5-int.h" /* - * $Id: util_seqnum.c,v 1.9.6.1 2000/05/31 17:17:39 raeburn Exp $ + * $Id: util_seqnum.c 15007 2002-11-15 16:12:20Z epeisach $ */ krb5_error_code @@ -38,22 +41,23 @@ { unsigned char plain[8]; - plain[4] = (unsigned char) direction; - plain[5] = (unsigned char) direction; - plain[6] = (unsigned char) direction; - plain[7] = (unsigned char) direction; + plain[4] = direction; + plain[5] = direction; + plain[6] = direction; + plain[7] = direction; if (key->enctype == ENCTYPE_ARCFOUR_HMAC ) { - /* Yes, Microsoft used big-endian sequence number.*/ - plain[0] = (seqnum>>24) & 0xff; - plain[1] = (seqnum>>16) & 0xff; - plain[2] = (seqnum>>8) & 0xff; - plain[3] = seqnum & 0xff; - return kg_arcfour_docrypt (context, key, 0, + /* Yes, Microsoft used big-endian sequence number.*/ + plain[0] = (seqnum>>24) & 0xff; + plain[1] = (seqnum>>16) & 0xff; + plain[2] = (seqnum>>8) & 0xff; + plain[3] = seqnum & 0xff; + return kg_arcfour_docrypt (context, key, 0, cksum, 8, &plain[0], 8, buf); - + } + plain[0] = (unsigned char) (seqnum&0xff); plain[1] = (unsigned char) ((seqnum>>8)&0xff); plain[2] = (unsigned char) ((seqnum>>16)&0xff); @@ -73,13 +77,16 @@ krb5_error_code code; unsigned char plain[8]; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC) - code = kg_arcfour_docrypt (context, key, 0, - cksum, 8, buf, 8, plain); - else - code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8); + if (key->enctype == ENCTYPE_ARCFOUR_HMAC) { + code = kg_arcfour_docrypt (context, key, 0, + cksum, 8, + buf, 8, + plain); + } else { + code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8); + } if (code) - return (code); + return(code); if ((plain[4] != plain[5]) || (plain[4] != plain[6]) || @@ -87,14 +94,14 @@ return((krb5_error_code) KG_BAD_SEQ); *direction = plain[4]; - - if (key->enctype == ENCTYPE_ARCFOUR_HMAC) - *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24)); - else - *seqnum = ((plain[0]) | + if (key->enctype == ENCTYPE_ARCFOUR_HMAC) { + *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24)); + } else { + *seqnum = ((plain[0]) | (plain[1]<<8) | (plain[2]<<16) | (plain[3]<<24)); + } return(0); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_set.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_set.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_set.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,10 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1995 by OpenVision Technologies, Inc. * @@ -22,26 +28,27 @@ */ /* - * $Id: util_set.c,v 1.1 1996/04/12 00:39:41 marc Exp $ + * $Id: util_set.c 16165 2004-03-14 05:31:43Z raeburn $ */ -#include -#include +#include /* SUNW15resync - for MALLOC/FREE */ +#include "gssapiP_generic.h" -struct _g_set { +struct _g_set_elt { void *key; void *value; - struct _g_set *next; + struct _g_set_elt *next; }; -int g_set_init(g_set *s) +int g_set_init(g_set_elt *s) { *s = NULL; return(0); } -int g_set_destroy(g_set *s) +#if 0 +int g_set_destroy(g_set_elt *s) { g_set next; @@ -53,12 +60,13 @@ return(0); } +#endif -int g_set_entry_add(g_set *s, void *key, void *value) +int g_set_entry_add(g_set_elt *s, void *key, void *value) { - g_set first; + g_set_elt first; - if ((first = (struct _g_set *) MALLOC(sizeof(struct _g_set))) == NULL) + if ((first = (struct _g_set_elt *) MALLOC(sizeof(struct _g_set_elt))) == NULL) return(ENOMEM); first->key = key; @@ -70,14 +78,14 @@ return(0); } -int g_set_entry_delete(g_set *s, void *key) +int g_set_entry_delete(g_set_elt *s, void *key) { - g_set *p; + g_set_elt *p; for (p=s; *p; p = &((*p)->next)) { if ((*p)->key == key) { - g_set next = (*p)->next; - FREE(*p, sizeof(struct _g_set)); + g_set_elt next = (*p)->next; + FREE(*p, sizeof(struct _g_set_elt)); *p = next; return(0); @@ -87,9 +95,9 @@ return(-1); } -int g_set_entry_get(g_set *s, void *key, void **value) +int g_set_entry_get(g_set_elt *s, void *key, void **value) { - g_set p; + g_set_elt p; for (p = *s; p; p = p->next) { if (p->key == key) { diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_token.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_token.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_token.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,4 +1,10 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #pragma ident "%Z%%M% %I% %E% SMI" + /* * Copyright 1993 by OpenVision Technologies, Inc. * @@ -21,18 +27,21 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_generic.h" + +#ifdef _KERNEL +#include +#else +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include +#endif /* _KERNEL */ + /* - * SUNW14resync - * This is defed in autoconf but we don't grok it for kernel (why?). - */ -#ifndef SIZEOF_INT -#define SIZEOF_INT 4 -#endif - -/* - * $Id: util_token.c,v 1.20.2.1 2003/12/16 02:56:16 tlyu Exp $ + * $Id: util_token.c 17987 2006-05-09 11:31:02Z epeisach $ */ /* XXXX this code currently makes the assumption that a mech oid will @@ -53,9 +62,9 @@ bytes 2,n are the token data Note that the token type field is a feature of RFC 1964 mechanisms and -is not used by other GSSAPI mechanisms. As such, a token type of -1 +is not used by other GSSAPI mechanisms. As such, a token type of -1 is interpreted to mean that no token type should be expected or -generated. +generated. For the purposes of this abstraction, the token "header" consists of the sequence tag and length octets, the mech OID DER encoding, and the @@ -64,14 +73,14 @@ */ -static int der_length_size(length) +static unsigned int der_length_size(length) int length; { if (length < (1<<7)) return(1); else if (length < (1<<8)) return(2); -#if (SIZEOF_INT == 2) +#if INT_MAX == 0x7fff else return(3); #else @@ -92,7 +101,7 @@ *(*buf)++ = (unsigned char) length; } else { *(*buf)++ = (unsigned char) (der_length_size(length)+127); -#if (SIZEOF_INT > 2) +#if INT_MAX > 0x7fff if (length >= (1<<24)) *(*buf)++ = (unsigned char) (length>>24); if (length >= (1<<16)) @@ -121,7 +130,7 @@ if (sf & 0x80) { if ((sf &= 0x7f) > ((*bufsize)-1)) return(-1); - if (sf > SIZEOF_INT) + if (sf > sizeof(int)) return (-1); ret = 0; for (; sf; sf--) { @@ -137,8 +146,8 @@ /* returns the length of a token, given the mech oid and the body size */ -int g_token_size(mech, body_size) - gss_OID mech; +unsigned int g_token_size(mech, body_size) + const gss_OID_desc * mech; unsigned int body_size; { /* set body_size to sequence contents size */ @@ -150,19 +159,20 @@ be the right size. buf is advanced past the token header */ void g_make_token_header(mech, body_size, buf, tok_type) - gss_OID mech; - int body_size; + const gss_OID_desc * mech; + unsigned int body_size; unsigned char **buf; int tok_type; { *(*buf)++ = 0x60; - der_write_length(buf, (int) (4 + mech->length + body_size)); + der_write_length(buf, + (tok_type == -1) ? 2 : (int) (4 + mech->length + body_size)); *(*buf)++ = 0x06; *(*buf)++ = (unsigned char) mech->length; - TWRITE_STR(*buf, mech->elements, ((int) mech->length)); + TWRITE_STR(*buf, mech->elements, mech->length); if (tok_type != -1) { - *(*buf)++ = (unsigned char) ((tok_type>>8)&0xff); - *(*buf)++ = (unsigned char) (tok_type&0xff); + *(*buf)++ = (unsigned char) ((tok_type>>8)&0xff); + *(*buf)++ = (unsigned char) (tok_type&0xff); } } @@ -177,12 +187,12 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in, wrapper_required) - gss_OID mech; - unsigned int *body_size; - unsigned char **buf_in; - int tok_type; - unsigned int toksize_in; - int wrapper_required; + const gss_OID_desc * mech; + unsigned int *body_size; + unsigned char **buf_in; + int tok_type; + unsigned int toksize_in; + int wrapper_required; { unsigned char *buf = *buf_in; int seqsize; @@ -190,43 +200,43 @@ int toksize = toksize_in; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return(G_BAD_TOK_HEADER); if (*buf++ != 0x60) { - if (wrapper_required) + if (wrapper_required) return(G_BAD_TOK_HEADER); - buf--; - toksize++; - goto skip_wrapper; + buf--; + toksize++; + goto skip_wrapper; } if ((seqsize = der_read_length(&buf, &toksize)) < 0) - return(G_BAD_TOK_HEADER); + return(G_BAD_TOK_HEADER); if (seqsize != toksize) - return(G_BAD_TOK_HEADER); + return(G_BAD_TOK_HEADER); if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return(G_BAD_TOK_HEADER); if (*buf++ != 0x06) - return(G_BAD_TOK_HEADER); - + return(G_BAD_TOK_HEADER); + if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return(G_BAD_TOK_HEADER); toid.length = *buf++; if ((toksize-=toid.length) < 0) - return(G_BAD_TOK_HEADER); + return(G_BAD_TOK_HEADER); toid.elements = buf; buf+=toid.length; - if (! g_OID_equal(&toid, mech)) - return G_WRONG_MECH; + if (! g_OID_equal(&toid, mech)) + return G_WRONG_MECH; skip_wrapper: if (tok_type != -1) { - if ((toksize-=2) < 0) + if ((toksize-=2) < 0) return(G_BAD_TOK_HEADER); - if ((*buf++ != ((tok_type>>8)&0xff)) || + if ((*buf++ != ((tok_type>>8)&0xff)) || (*buf++ != (tok_type&0xff))) return(G_WRONG_TOKID); } @@ -235,4 +245,3 @@ return 0; } - diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -28,14 +28,17 @@ */ /* - * $Id: util_validate.c,v 1.8 1996/08/28 21:50:37 tytso Exp $ + * $Id: util_validate.c 16475 2004-06-17 02:23:21Z raeburn $ */ /* * functions to validate name, credential, and context handles */ -#include +#include "gssapiP_generic.h" +#ifndef _KERNEL +#include "gss_libinit.h" +#endif #ifdef HAVE_SYS_TYPES_H #include @@ -48,10 +51,12 @@ #include #endif + #ifdef HAVE_BSD_DB #include #include + static const int one = 1; static const DBT dbtone = { (void *) &one, sizeof(one) }; @@ -64,19 +69,36 @@ #define V_NAME 1 #define V_CRED_ID 2 #define V_CTX_ID 3 +#define V_LCTX_ID 4 + +/* SUNW15resync + beware some of the uses below of type look dubious but seem + to have been working in Solaris for a long time */ /* All these functions return 0 on failure, and non-zero on success */ static int g_save(db, type, ptr) - void **db; + g_set *db; int type; void *ptr; { + int ret; #ifdef HAVE_BSD_DB - DB **vdb = (DB **) db; + DB **vdb; vkey vk; DBT key; +#ifndef _KERNEL + ret = gssint_initialize_library(); + if (ret) + return 0; +#endif + ret = k5_mutex_lock(&db->mutex); + if (ret) + return 0; + + vdb = (DB **) &db->data; + if (!*vdb) *vdb = dbopen(NULL, O_CREAT|O_RDWR, O_CREAT|O_RDWR, DB_HASH, NULL); @@ -86,30 +108,57 @@ key.data = &vk; key.size = sizeof(vk); - return((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0); + ret = ((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0); + (void) k5_mutex_unlock(&db->mutex); + return ret; #else - g_set *gs = (g_set *) db; + g_set_elt *gs; + +#ifndef _KERNEL + ret = gssint_initialize_library(); + if (ret) + return 0; +#endif + ret = k5_mutex_lock(&db->mutex); + if (ret) + return 0; + + gs = (g_set_elt *) &db->data; if (!*gs) - if (g_set_init(gs)) + if (g_set_init(gs)) { + (void) k5_mutex_unlock(&db->mutex); return(0); + } - return(g_set_entry_add(gs, ptr, (void *)(intptr_t)type) == 0); + /* SUNW15resync */ + ret = (g_set_entry_add(gs, ptr, (void *)(intptr_t)type) == 0); + + (void) k5_mutex_unlock(&db->mutex); + return ret; #endif } static int g_validate(db, type, ptr) - void **db; + g_set *db; int type; void *ptr; { + int ret; #ifdef HAVE_BSD_DB - DB **vdb = (DB **) db; + DB **vdb; vkey vk; DBT key, value; - if (!*vdb) + ret = k5_mutex_lock(&db->mutex); + if (ret) + return 0; + + vdb = (DB **) &db->data; + if (!*vdb) { + (void) k5_mutex_unlock(&db->mutex); return(0); + } vk.type = type; vk.ptr = ptr; @@ -117,38 +166,58 @@ key.data = &vk; key.size = sizeof(vk); - if ((*((*vdb)->get))(*vdb, &key, &value, 0)) + if ((*((*vdb)->get))(*vdb, &key, &value, 0)) { + (void) k5_mutex_unlock(&db->mutex); return(0); + } + (void) k5_mutex_unlock(&db->mutex); return((value.size == sizeof(one)) && (*((int *) value.data) == one)); #else - g_set *gs = (g_set *) db; + g_set_elt *gs; void *value; - if (!*gs) - return(0); + ret = k5_mutex_lock(&db->mutex); + if (ret) + return 0; - if (g_set_entry_get(gs, ptr, (void **) &value)) + gs = (g_set_elt *) &db->data; + if (!*gs) { + (void) k5_mutex_unlock(&db->mutex); return(0); + } - return((intptr_t)value == (intptr_t)type); + if (g_set_entry_get(gs, ptr, (void **) &value)) { + (void) k5_mutex_unlock(&db->mutex); + return(0); + } + (void) k5_mutex_unlock(&db->mutex); + return((intptr_t)value == (intptr_t)type); /* SUNW15resync */ #endif } /*ARGSUSED*/ static int g_delete(db, type, ptr) - void **db; + g_set *db; int type; void *ptr; { + int ret; #ifdef HAVE_BSD_DB - DB **vdb = (DB **) db; + DB **vdb; vkey vk; DBT key; - if (!*vdb) + ret = k5_mutex_lock(&db->mutex); + if (ret) + return 0; + + vdb = (DB **) &db->data; + if (!*vdb) { + (void) k5_mutex_unlock(&db->mutex); return(0); + } vk.type = type; vk.ptr = ptr; @@ -156,16 +225,27 @@ key.data = &vk; key.size = sizeof(vk); - return((*((*vdb)->del))(*vdb, &key, 0) == 0); + ret = ((*((*vdb)->del))(*vdb, &key, 0) == 0); + (void) k5_mutex_unlock(&db->mutex); + return ret; #else - g_set *gs = (g_set *) db; + g_set_elt *gs; + + ret = k5_mutex_lock(&db->mutex); + if (ret) + return 0; - if (!*gs) + gs = (g_set_elt *) &db->data; + if (!*gs) { + (void) k5_mutex_unlock(&db->mutex); return(0); + } - if (g_set_entry_delete(gs, ptr)) + if (g_set_entry_delete(gs, ptr)) { + (void) k5_mutex_unlock(&db->mutex); return(0); - + } + (void) k5_mutex_unlock(&db->mutex); return(1); #endif } @@ -175,63 +255,82 @@ /* save */ int g_save_name(vdb, name) - void **vdb; + g_set *vdb; gss_name_t name; { return(g_save(vdb, V_NAME, (void *) name)); } int g_save_cred_id(vdb, cred) - void **vdb; + g_set *vdb; gss_cred_id_t cred; { return(g_save(vdb, V_CRED_ID, (void *) cred)); } int g_save_ctx_id(vdb, ctx) - void **vdb; + g_set *vdb; gss_ctx_id_t ctx; { return(g_save(vdb, V_CTX_ID, (void *) ctx)); } +int g_save_lucidctx_id(vdb, lctx) + g_set *vdb; + void *lctx; +{ + return(g_save(vdb, V_LCTX_ID, (void *) lctx)); +} + /* validate */ int g_validate_name(vdb, name) - void **vdb; + g_set *vdb; gss_name_t name; { return(g_validate(vdb, V_NAME, (void *) name)); } int g_validate_cred_id(vdb, cred) - void **vdb; + g_set *vdb; gss_cred_id_t cred; { return(g_validate(vdb, V_CRED_ID, (void *) cred)); } int g_validate_ctx_id(vdb, ctx) - void **vdb; + g_set *vdb; gss_ctx_id_t ctx; { return(g_validate(vdb, V_CTX_ID, (void *) ctx)); } +int g_validate_lucidctx_id(vdb, lctx) + g_set *vdb; + void *lctx; +{ + return(g_validate(vdb, V_LCTX_ID, (void *) lctx)); +} /* delete */ int g_delete_name(vdb, name) - void **vdb; + g_set *vdb; gss_name_t name; { return(g_delete(vdb, V_NAME, (void *) name)); } int g_delete_cred_id(vdb, cred) - void **vdb; + g_set *vdb; gss_cred_id_t cred; { return(g_delete(vdb, V_CRED_ID, (void *) cred)); } int g_delete_ctx_id(vdb, ctx) - void **vdb; + g_set *vdb; gss_ctx_id_t ctx; { return(g_delete(vdb, V_CTX_ID, (void *) ctx)); } +int g_delete_lucidctx_id(vdb, lctx) + g_set *vdb; + void *lctx; +{ + return(g_delete(vdb, V_LCTX_ID, (void *) lctx)); +} diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,8 +1,3 @@ -/* - * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -30,72 +25,76 @@ * */ -#include - -OM_uint32 -krb5_gss_validate_cred(ct, minor_status, cred_handle) - void *ct; - OM_uint32 *minor_status; - gss_cred_id_t cred_handle; -{ - OM_uint32 major_status; - - mutex_lock(&krb5_mutex); - major_status = krb5_gss_validate_cred_no_lock(ct, minor_status, - cred_handle); - mutex_unlock(&krb5_mutex); - - return(major_status); -} +#include "gssapiP_krb5.h" /* * Check to see whether or not a GSSAPI krb5 credential is valid. If * it is not, return an error. */ -/*ARGSUSED*/ OM_uint32 -krb5_gss_validate_cred_no_lock(ct, minor_status, cred_handle) - void *ct; - OM_uint32 *minor_status; - gss_cred_id_t cred_handle; +krb5_gss_validate_cred_1(OM_uint32 *minor_status, gss_cred_id_t cred_handle, + krb5_context context) { - krb5_context context = ct; krb5_gss_cred_id_t cred; krb5_error_code code; krb5_principal princ; - OM_uint32 major_status = GSS_S_FAILURE; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return (major_status); -#endif if (!kg_validate_cred_id(cred_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - major_status = (GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL); - return (major_status); + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL); } cred = (krb5_gss_cred_id_t) cred_handle; - + + code = k5_mutex_lock(&cred->lock); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } + if (cred->ccache) { - code = krb5_cc_get_principal(context, cred->ccache, &princ); - if (code) { + if ((code = krb5_cc_get_principal(context, cred->ccache, &princ))) { + k5_mutex_unlock(&cred->lock); *minor_status = code; - major_status = GSS_S_DEFECTIVE_CREDENTIAL; - return (major_status); + return(GSS_S_DEFECTIVE_CREDENTIAL); } if (!krb5_principal_compare(context, princ, cred->princ)) { + k5_mutex_unlock(&cred->lock); *minor_status = KG_CCACHE_NOMATCH; - major_status = GSS_S_DEFECTIVE_CREDENTIAL; - return (major_status); + return(GSS_S_DEFECTIVE_CREDENTIAL); } (void)krb5_free_principal(context, princ); } *minor_status = 0; - major_status = GSS_S_COMPLETE; - return (major_status); + return GSS_S_COMPLETE; } + +OM_uint32 +krb5_gss_validate_cred(minor_status, cred_handle) + OM_uint32 *minor_status; + gss_cred_id_t cred_handle; +{ + krb5_context context; + krb5_error_code code; + OM_uint32 maj; + + code = krb5_gss_init_context(&context); + if (code) { + *minor_status = code; + return GSS_S_FAILURE; + } + + maj = krb5_gss_validate_cred_1(minor_status, cred_handle, context); + if (maj == 0) { + krb5_gss_cred_id_t cred = (krb5_gss_cred_id_t) cred_handle; + k5_mutex_assert_locked(&cred->lock); + k5_mutex_unlock(&cred->lock); + } + krb5_free_context(context); + return maj; +} + + + + diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -27,81 +27,54 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "gssapiP_krb5.h" /* - * $Id: verify.c,v 1.11 1996/07/22 20:34:45 marc Exp $ + * $Id: verify.c 16171 2004-03-15 17:45:01Z raeburn $ */ + /*ARGSUSED*/ OM_uint32 -krb5_gss_verify(ctx, minor_status, context_handle, +krb5_gss_verify(minor_status, context_handle, message_buffer, token_buffer, qop_state #ifdef _KERNEL , gssd_ctx_verifier #endif ) - void *ctx; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t message_buffer; gss_buffer_t token_buffer; int *qop_state; #ifdef _KERNEL - OM_uint32 gssd_ctx_verifier; + OM_uint32 gssd_ctx_verifier; #endif { - krb5_context context; - OM_uint32 status; - - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - mutex_lock(&krb5_mutex); - context = ctx; - - status = kg_unseal(context, minor_status, context_handle, + return(kg_unseal(minor_status, context_handle, token_buffer, message_buffer, - NULL, qop_state, KG_TOK_SIGN_MSG); - mutex_unlock(&krb5_mutex); - return(status); + NULL, qop_state, KG_TOK_SIGN_MSG)); } /* V2 interface */ OM_uint32 -krb5_gss_verify_mic(ctx, minor_status, context_handle, +krb5_gss_verify_mic(minor_status, context_handle, message_buffer, token_buffer, qop_state) - void *ctx; OM_uint32 *minor_status; gss_ctx_id_t context_handle; gss_buffer_t message_buffer; gss_buffer_t token_buffer; gss_qop_t *qop_state; { - krb5_context context; OM_uint32 rstat; int qstate; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - mutex_lock(&krb5_mutex); - context = ctx; - - rstat = kg_unseal(context, minor_status, context_handle, - token_buffer, message_buffer, - NULL, &qstate, KG_TOK_MIC_MSG); + rstat = kg_unseal(minor_status, context_handle, + token_buffer, message_buffer, + NULL, &qstate, KG_TOK_MIC_MSG); if (!rstat && qop_state) *qop_state = (gss_qop_t) qstate; - mutex_unlock(&krb5_mutex); return(rstat); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/uts/common/gssapi/mechs/krb5/mech/wrap_size_limit.c --- a/usr/src/uts/common/gssapi/mechs/krb5/mech/wrap_size_limit.c Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/wrap_size_limit.c Fri Sep 14 15:01:24 2007 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -77,19 +77,29 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#include -#include +#include "gssapiP_krb5.h" + +size_t KRB5_CALLCONV krb5_encrypt_size(size_t, krb5_enctype); -/* - * $Id: wrap_size_limit.c,v 1.7.6.2 2000/04/19 00:33:42 raeburn Exp $ - */ + /* SUNW15resync - XXX find new home for this func */ +#ifdef _KERNEL +size_t KRB5_CALLCONV +krb5_encrypt_size(size_t length, krb5_enctype crypto) +{ + size_t ret; + + if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret)) + /*LINTED*/ + return(-1); /* XXX */ + + return(ret); +} +#endif /* V2 interface */ - /*ARGSUSED*/ OM_uint32 -krb5_gss_wrap_size_limit(ct, minor_status, context_handle, conf_req_flag, +krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, qop_req, req_output_size, max_input_size) - void *ct; OM_uint32 *minor_status; gss_ctx_id_t context_handle; int conf_req_flag; @@ -97,118 +107,93 @@ OM_uint32 req_output_size; OM_uint32 *max_input_size; { - krb5_context context; krb5_gss_ctx_id_rec *ctx; - OM_uint32 conflen; + OM_uint32 data_size, conflen; OM_uint32 ohlen; - OM_uint32 data_size; + int overhead; - /* Solaris Kerberos: for MT safety, we avoid the use of a default - * context via kg_get_context() */ -#if 0 - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return(GSS_S_FAILURE); -#endif - - KRB5_LOG0(KRB5_INFO, "krb5_gss_wrap_size_limit() start\n"); - - /* check to make sure we aren't writing to a NULL pointer */ + /* Solaris Kerb - check to make sure we aren't writing to a NULL pointer */ if (!max_input_size) - return(GSS_S_CALL_INACCESSIBLE_WRITE); - - mutex_lock(&krb5_mutex); - context = ct; + return(GSS_S_CALL_INACCESSIBLE_WRITE); /* only default qop is allowed */ + /* + * SUNW15resync + * mit 1.2-6: if (qop_req != GSS_C_QOP_DEFAULT) { + * Go with Solaris version here, though not sure which is + * correct and RFC 2743 does not make it clear. + */ if ((qop_req & GSS_KRB5_CONF_C_QOP_MASK) != GSS_C_QOP_DEFAULT) { *minor_status = (OM_uint32) G_UNKNOWN_QOP; - mutex_unlock(&krb5_mutex); - return(GSS_S_BAD_QOP); + /* SUNW15resync - RFC 2743 is clear here but + this is still GSS_S_FAILURE in MIT */ + return(GSS_S_BAD_QOP); } - + /* validate the context handle */ if (! kg_validate_ctx_id(context_handle)) { *minor_status = (OM_uint32) G_VALIDATE_FAILED; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } - + ctx = (krb5_gss_ctx_id_rec *) context_handle; if (! ctx->established) { *minor_status = KG_CTX_INCOMPLETE; - mutex_unlock(&krb5_mutex); return(GSS_S_NO_CONTEXT); } if (ctx->proto == 1) { - /* No pseudo-ASN.1 wrapper overhead, so no sequence length and - OID. */ - OM_uint32 sz = req_output_size; - if (conf_req_flag) { - size_t enclen; - if ( (*minor_status = krb5_c_encrypt_length(context, - ctx->enc->enctype, - sz, &enclen))) { - mutex_unlock(&krb5_mutex); - return (GSS_S_FAILURE); - } - /* - * The 16 byte token header is included 2 times, - * once at the beginning of the token and once - * encrypted with the plaintext data. - */ - while (sz > 0 && enclen + 32 > req_output_size) { - sz--; - if ((*minor_status = krb5_c_encrypt_length(context, - ctx->enc->enctype, sz, &enclen))) { - mutex_unlock(&krb5_mutex); - return (GSS_S_FAILURE); - } - } - } else { - if (sz < 16 + ctx->cksum_size) - sz = 0; - else - sz -= (16 + ctx->cksum_size); - } + /* No pseudo-ASN.1 wrapper overhead, so no sequence length and + OID. */ + OM_uint32 sz = req_output_size; + /* Token header: 16 octets. */ + if (conf_req_flag) { + while (sz > 0 && krb5_encrypt_size(sz, ctx->enc->enctype) + 16 > req_output_size) + sz--; + /* Allow for encrypted copy of header. */ + if (sz > 16) + sz -= 16; + else + sz = 0; +#ifdef CFX_EXERCISE + /* Allow for EC padding. In the MIT implementation, only + added while testing. */ + if (sz > 65535) + sz -= 65535; + else + sz = 0; +#endif + } else { + /* Allow for token header and checksum. */ + if (sz < 16 + ctx->cksum_size) + sz = 0; + else + sz -= (16 + ctx->cksum_size); + } - *max_input_size = sz; - *minor_status = 0; - goto end; + *max_input_size = sz; + *minor_status = 0; + return GSS_S_COMPLETE; } + /* Calculate the token size and subtract that from the output size */ + overhead = 7 + ctx->mech_used->length; data_size = req_output_size; - - /* The confounder is always used */ - conflen = kg_confounder_size(context, ctx->enc); - data_size = (conflen + data_size + 8) & (~7); - - /* - * If we are encrypting, check the size, it may be larger than - * the input in some cases due to padding and byte-boundaries. - */ - if (conf_req_flag) { - data_size = kg_encrypt_size(context, ctx->enc, data_size); - } + conflen = kg_confounder_size(ctx->k5_context, ctx->enc); + data_size = (conflen + data_size + 8) & (~(OM_uint32)7); + ohlen = g_token_size(ctx->mech_used, + (unsigned int) (data_size + ctx->cksum_size + 14)) + - req_output_size; - /* - * Calculate the token size for a buffer that is 'req_output_size' - * long. - */ - ohlen = g_token_size(&(ctx->mech_used), - (unsigned int)(data_size + ctx->cksum_size + 14)) - - req_output_size; - - KRB5_LOG1(KRB5_INFO, "ohlen = %u, req_output_size = %u.\n", - ohlen, req_output_size); - - *max_input_size = (req_output_size > ohlen) ? - ((req_output_size - ohlen) & (~7)) : 0; + if (ohlen+overhead < req_output_size) + /* + * Cannot have trailer length that will cause us to pad over our + * length. + */ + *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7); + else + *max_input_size = 0; *minor_status = 0; -end: - mutex_unlock(&krb5_mutex); - KRB5_LOG(KRB5_INFO, "krb5_gss_wrap_size_limit() end, " - "max_input_size = %u.\n", *max_input_size); return(GSS_S_COMPLETE); } diff -r 82bdd5527b91 -r 532e59d6bffd usr/src/xmod/cry_files --- a/usr/src/xmod/cry_files Fri Sep 14 14:36:45 2007 -0700 +++ b/usr/src/xmod/cry_files Fri Sep 14 15:01:24 2007 -0700 @@ -25,7 +25,7 @@ usr/src/lib/gss_mechs/mech_krb5/Makefile usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c usr/src/lib/gss_mechs/mech_krb5/crypto/des/string2key.c -usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c +usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c usr/src/lib/gss_mechs/mech_spnego/Makefile usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c usr/src/lib/libgss/Makefile