1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * A module for Kerberos V5 security mechanism. 6 * 7 */ 8 9 #pragma ident "%Z%%M% %I% %E% SMI" 10 11 char _depends_on[] = "misc/kgssapi crypto/md5"; 12 13 #include <sys/types.h> 14 #include <sys/modctl.h> 15 #include <sys/errno.h> 16 #include <mechglueP.h> 17 #include <gssapiP_krb5.h> 18 #include <gssapi_err_generic.h> 19 #include <gssapi/kgssapi_defs.h> 20 #include <sys/debug.h> 21 #include <k5-int.h> 22 23 OM_uint32 krb5_gss_get_context(void ** context); 24 25 extern krb5_error_code krb5_ser_context_init 26 (krb5_context); 27 28 extern krb5_error_code krb5_ser_auth_context_init 29 (krb5_context); 30 31 static struct gss_config krb5_mechanism = 32 {{9, "\052\206\110\206\367\022\001\002\002"}, 33 NULL, /* context */ 34 NULL, /* next */ 35 TRUE, /* uses_kmod */ 36 /* EXPORT DELETE START */ /* CRYPT DELETE START */ 37 krb5_gss_unseal, 38 /* EXPORT DELETE END */ /* CRYPT DELETE END */ 39 krb5_gss_delete_sec_context, 40 /* EXPORT DELETE START */ /* CRYPT DELETE START */ 41 krb5_gss_seal, 42 /* EXPORT DELETE END */ /* CRYPT DELETE END */ 43 krb5_gss_import_sec_context, 44 /* EXPORT DELETE START */ 45 /* CRYPT DELETE START */ 46 #if 0 47 /* CRYPT DELETE END */ 48 krb5_gss_seal, 49 krb5_gss_unseal, 50 /* CRYPT DELETE START */ 51 #endif 52 /* CRYPT DELETE END */ 53 /* EXPORT DELETE END */ 54 krb5_gss_sign, 55 krb5_gss_verify, 56 }; 57 58 static gss_mechanism 59 gss_mech_initialize() 60 { 61 (void) krb5_gss_get_context(&(krb5_mechanism.context)); 62 return (&krb5_mechanism); 63 } 64 65 66 /* 67 * Module linkage information for the kernel. 68 */ 69 extern struct mod_ops mod_miscops; 70 71 static struct modlmisc modlmisc = { 72 &mod_miscops, "Krb5 GSS mechanism" 73 }; 74 75 static struct modlinkage modlinkage = { 76 MODREV_1, 77 (void *)&modlmisc, 78 NULL 79 }; 80 81 82 static int krb5_fini_code = EBUSY; 83 84 int 85 _init() 86 { 87 int retval; 88 gss_mechanism mech, tmp; 89 90 if ((retval = mod_install(&modlinkage)) != 0) 91 return (retval); 92 93 mech = gss_mech_initialize(); 94 95 mutex_enter(&__kgss_mech_lock); 96 tmp = __kgss_get_mechanism(&mech->mech_type); 97 if (tmp != NULL) { 98 99 KRB5_LOG0(KRB5_INFO, 100 "KRB5 GSS mechanism: mechanism already in table.\n"); 101 102 if (tmp->uses_kmod == TRUE) { 103 KRB5_LOG0(KRB5_INFO, "KRB5 GSS mechanism: mechanism " 104 "table supports kernel operations!\n"); 105 } 106 /* 107 * keep us loaded, but let us be unloadable. This 108 * will give the developer time to trouble shoot 109 */ 110 krb5_fini_code = 0; 111 } else { 112 __kgss_add_mechanism(mech); 113 ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech); 114 } 115 mutex_exit(&__kgss_mech_lock); 116 117 return (0); 118 } 119 120 int 121 _fini() 122 { 123 int ret = krb5_fini_code; 124 125 if (ret == 0) { 126 ret = (mod_remove(&modlinkage)); 127 } 128 return (ret); 129 } 130 131 int 132 _info(struct modinfo *modinfop) 133 { 134 return (mod_info(&modlinkage, modinfop)); 135 } 136 137 OM_uint32 138 krb5_gss_get_context(context) 139 void ** context; 140 { 141 OM_uint32 major_status = 0; 142 143 mutex_lock(&krb5_mutex); 144 if (context == NULL) 145 { 146 major_status = GSS_S_FAILURE; 147 goto unlock; 148 } 149 if (kg_context) { 150 *context = kg_context; 151 major_status = GSS_S_COMPLETE; 152 goto unlock; 153 } 154 155 if (krb5_init_context(&kg_context)) 156 { 157 major_status = GSS_S_FAILURE; 158 goto unlock; 159 } 160 if (krb5_ser_auth_context_init(kg_context)) 161 { 162 kg_context = 0; 163 major_status = GSS_S_FAILURE; 164 goto unlock; 165 } 166 167 *context = kg_context; 168 unlock: 169 mutex_unlock(&krb5_mutex); 170 return (major_status); 171 } 172