#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/cmn_err.h>
#include <gssapi/gssapi.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_defs.h>
#ifdef RPCGSS_DEBUG
uint_t rpcgss_log = 0;
#endif
void
__rpc_gss_dup_oid(gss_OID oid, gss_OID *ret)
{
gss_OID tmp;
if (oid == GSS_C_NULL_OID || oid->length == 0) {
*ret = NULL;
return;
}
tmp = (gss_OID) kmem_alloc(sizeof (gss_OID_desc), KM_SLEEP);
if (tmp) {
tmp->elements = kmem_alloc((oid->length), KM_SLEEP);
bcopy((char *)oid->elements, (char *)tmp->elements, oid->length);
tmp->length = oid->length;
*ret = tmp;
} else {
*ret = NULL;
}
}
bool_t
__rpc_gss_oids_equal(oid1, oid2)
gss_OID oid1, oid2;
{
if ((oid1->length == 0) && (oid2->length == 0))
return (TRUE);
if (oid1->length != oid2->length)
return (FALSE);
return (bcmp(oid1->elements, oid2->elements, oid1->length) == 0);
}
void
__rpc_gss_convert_name(principal, name, name_type)
rpc_gss_principal_t principal;
gss_buffer_desc *name;
gss_OID *name_type;
{
char *cp;
cp = principal->name;
if (*(int *)cp == 0)
*name_type = GSS_C_NULL_OID;
else {
(*name_type)->length = *(int *)cp;
(*name_type)->elements = (void *)(cp + sizeof (int));
}
cp += RNDUP(*(int *)cp) + sizeof (int);
if ((name->length = *(int *)cp) == 0)
name->value = NULL;
else
name->value = cp + sizeof (int);
}
bool_t
__rpc_gss_make_principal(principal, name)
rpc_gss_principal_t *principal;
gss_buffer_desc *name;
{
int plen;
char *s;
RPCGSS_LOG(8, "name-length = %lu\n", name->length);
RPCGSS_LOG(8, "name-value = 0x%p\n", (void *)name->value);
plen = RNDUP(name->length) + sizeof (int);
(*principal) = (rpc_gss_principal_t)kmem_alloc(plen, KM_SLEEP);
if ((*principal) == NULL)
return (FALSE);
bzero((caddr_t)(*principal), plen);
(*principal)->len = RNDUP(name->length);
s = (*principal)->name;
bcopy(name->value, s, name->length);
return (TRUE);
}
rpc_gss_principal_t
__rpc_gss_dup_principal(principal)
rpc_gss_principal_t principal;
{
rpc_gss_principal_t pdup;
int len;
if (principal == NULL)
return (NULL);
len = principal->len + sizeof (int);
if ((pdup = (rpc_gss_principal_t)mem_alloc(len)) == NULL)
return (NULL);
pdup->len = len;
bcopy(principal->name, pdup->name, len);
return (pdup);
}
bool_t
rpc_gss_get_versions(vers_hi, vers_lo)
uint_t *vers_hi;
uint_t *vers_lo;
{
*vers_hi = RPCSEC_GSS_VERSION;
*vers_lo = RPCSEC_GSS_VERSION;
return (TRUE);
}
void
rpc_gss_display_status(major, minor, mech_type,
uid, gss_function_name)
OM_uint32 major, minor;
gss_OID mech_type;
uid_t uid;
char *gss_function_name;
{
int message_context;
int major_stat;
uint_t minor_stat;
gss_buffer_desc status_string;
message_context = 0;
do {
major_stat = kgss_display_status(&minor_stat, major,
GSS_C_GSS_CODE, mech_type,
&message_context, &status_string, uid);
if (major_stat != GSS_S_COMPLETE &&
major != GSS_S_CONTINUE_NEEDED) {
RPCGSS_LOG1(1, "%s GSS major error 0x%x\n",
gss_function_name, major);
RPCGSS_LOG1(1, "%s GSS minor error 0x%x\n",
gss_function_name, minor);
return;
} else {
RPCGSS_LOG1(1, "%s GSS Error %s\n",
(char *)gss_function_name,
(char *)status_string.value);
(void) gss_release_buffer(&minor_stat, &status_string);
}
} while (message_context != 0);
message_context = 0;
do {
major_stat = kgss_display_status(&minor_stat, minor,
GSS_C_MECH_CODE, mech_type,
&message_context, &status_string, uid);
if (major_stat != GSS_S_COMPLETE &&
major_stat != GSS_S_CONTINUE_NEEDED) {
RPCGSS_LOG1(1, "%s GSS minor error 0x%x\n",
gss_function_name, minor);
return;
} else {
RPCGSS_LOG1(1,
"%s GSS Minor Error %s\n",
(char *)gss_function_name, (char *)status_string.value);
(void) gss_release_buffer(&minor_stat,
&status_string);
}
} while (message_context != 0);
}