krb5mech.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* A module for Kerberos V5 security mechanism.
*
*/
#pragma ident "%Z%%M% %I% %E% SMI"
char _depends_on[] = "misc/kgssapi crypto/md5";
#include <sys/types.h>
#include <sys/modctl.h>
#include <sys/errno.h>
#include <mechglueP.h>
#include <gssapiP_krb5.h>
#include <gssapi_err_generic.h>
#include <gssapi/kgssapi_defs.h>
#include <sys/debug.h>
#include <k5-int.h>
OM_uint32 krb5_gss_get_context(void ** context);
extern krb5_error_code krb5_ser_context_init
KRB5_PROTOTYPE((krb5_context));
extern krb5_error_code krb5_ser_auth_context_init
KRB5_PROTOTYPE((krb5_context));
static struct gss_config krb5_mechanism =
{{9, "\052\206\110\206\367\022\001\002\002"},
NULL, /* context */
NULL, /* next */
TRUE, /* uses_kmod */
/* EXPORT DELETE START */ /* CRYPT DELETE START */
krb5_gss_unseal,
/* EXPORT DELETE END */ /* CRYPT DELETE END */
krb5_gss_delete_sec_context,
/* EXPORT DELETE START */ /* CRYPT DELETE START */
krb5_gss_seal,
/* EXPORT DELETE END */ /* CRYPT DELETE END */
krb5_gss_import_sec_context,
/* 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,
};
static gss_mechanism
gss_mech_initialize()
{
(void) krb5_gss_get_context(&(krb5_mechanism.context));
return (&krb5_mechanism);
}
/*
* Module linkage information for the kernel.
*/
extern struct mod_ops mod_miscops;
#if defined(sun4u)
static struct modlmisc modlmisc = {
&mod_miscops, "Krb5 GSS mech, sun4u optimized"
};
#else
static struct modlmisc modlmisc = {
&mod_miscops, "Krb5 GSS mechanism"
};
#endif
static struct modlinkage modlinkage = {
MODREV_1,
(void *)&modlmisc,
NULL
};
static int krb5_fini_code = EBUSY;
int
_init()
{
int retval;
gss_mechanism mech, tmp;
if ((retval = mod_install(&modlinkage)) != 0)
return (retval);
mech = gss_mech_initialize();
mutex_enter(&__kgss_mech_lock);
tmp = __kgss_get_mechanism(&mech->mech_type);
if (tmp != NULL) {
KRB5_LOG0(KRB5_INFO,
"KRB5 GSS mechanism: mechanism already in table.\n");
if (tmp->uses_kmod == TRUE) {
KRB5_LOG0(KRB5_INFO, "KRB5 GSS mechanism: mechanism "
"table supports kernel operations!\n");
}
/*
* keep us loaded, but let us be unloadable. This
* will give the developer time to trouble shoot
*/
krb5_fini_code = 0;
} else {
__kgss_add_mechanism(mech);
ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech);
}
mutex_exit(&__kgss_mech_lock);
return (0);
}
int
_fini()
{
int ret = krb5_fini_code;
if (ret == 0) {
ret = (mod_remove(&modlinkage));
}
return (ret);
}
int
_info(struct modinfo *modinfop)
{
return (mod_info(&modlinkage, modinfop));
}
OM_uint32
krb5_gss_get_context(context)
void ** context;
{
OM_uint32 major_status = 0;
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;
}
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;
}
*context = kg_context;
unlock:
mutex_unlock(&krb5_mutex);
return (major_status);
}