OM_uint32 ntlm_gss_inquire_cred( OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_name_t *name, OM_uint32 *lifetime, int *cred_usage, gss_OID_set *mechanisms) { OM_uint32 status = 0; ntlm_gss_cred_id_t ntlm_cred_handle = NULL; gss_name_t ret_name = NULL; dsyslog("Entering inquire_cred\n"); ntlm_cred_handle = (ntlm_gss_cred_id_t) cred_handle; if (ntlm_cred_handle && ntlm_cred_handle->name && name) { status = gss_duplicate_name( minor_status, ntlm_cred_handle->name, &ret_name); if (status == 0) { *name = ret_name; } } dsyslog("Leaving inquire_cred\n"); return (status); }
bool_t Svcauth_gss_set_svc_name(gss_name_t name) { OM_uint32 maj_stat, min_stat; if(svcauth_gss_name != NULL) { maj_stat = gss_release_name(&min_stat, &svcauth_gss_name); if(maj_stat != GSS_S_COMPLETE) { return (FALSE); } svcauth_gss_name = NULL; } if(svcauth_gss_name == GSS_C_NO_NAME) return (TRUE); maj_stat = gss_duplicate_name(&min_stat, name, &svcauth_gss_name); if(maj_stat != GSS_S_COMPLETE) { return (FALSE); } return (TRUE); }
bool_t svcauth_gss_set_svc_name(gss_name_t name) { OM_uint32 maj_stat, min_stat; log_debug("in svcauth_gss_set_svc_name()"); if (_svcauth_gss_name != NULL) { maj_stat = gss_release_name(&min_stat, &_svcauth_gss_name); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_release_name", maj_stat, min_stat); return (FALSE); } _svcauth_gss_name = NULL; } maj_stat = gss_duplicate_name(&min_stat, name, &_svcauth_gss_name); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_duplicate_name", maj_stat, min_stat); return (FALSE); } return (TRUE); }
OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name ( OM_uint32 * minor_status, gss_const_name_t src_name, gss_name_t * dest_name ) { return gss_duplicate_name(minor_status, src_name, dest_name); }
OM_uint32 _gss_spnego_duplicate_name ( OM_uint32 * minor_status, const gss_name_t src_name, gss_name_t * dest_name ) { return gss_duplicate_name(minor_status, src_name, dest_name); }
uint32_t sapgss_duplicate_name( uint32_t *minor_status, gss_name_t input_name, gss_name_t *dest_name) { return gss_duplicate_name(minor_status, input_name, dest_name); }
AUTH * authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec) { AUTH *auth, *save_auth; struct rpc_gss_data *gd; OM_uint32 min_stat = 0; log_debug("in authgss_create()"); memset(&rpc_createerr, 0, sizeof(rpc_createerr)); if ((auth = calloc(sizeof(*auth), 1)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; return (NULL); } if ((gd = calloc(sizeof(*gd), 1)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; free(auth); return (NULL); } if (name != GSS_C_NO_NAME) { if (gss_duplicate_name(&min_stat, name, &gd->name) != GSS_S_COMPLETE) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; free(auth); free(gd); return (NULL); } } else gd->name = name; gd->clnt = clnt; gd->ctx = GSS_C_NO_CONTEXT; gd->sec = *sec; gd->gc.gc_v = RPCSEC_GSS_VERSION; gd->gc.gc_proc = RPCSEC_GSS_INIT; gd->gc.gc_svc = gd->sec.svc; auth->ah_ops = &authgss_ops; auth->ah_private = (caddr_t)gd; save_auth = clnt->cl_auth; clnt->cl_auth = auth; if (!authgss_refresh(auth, NULL)) auth = NULL; clnt->cl_auth = save_auth; log_debug("authgss_create returning auth 0x%08x", auth); return (auth); }
OM_uint32 _gss_ntlm_canonicalize_name ( OM_uint32 * minor_status, const gss_name_t input_name, const gss_OID mech_type, gss_name_t * output_name ) { return gss_duplicate_name (minor_status, input_name, output_name); }
OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name ( OM_uint32 * minor_status, gss_const_name_t input_name, const gss_OID mech_type, gss_name_t * output_name ) { /* XXX */ return gss_duplicate_name(minor_status, input_name, output_name); }
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) { if ((mech_type != GSS_C_NULL_OID) && !g_OID_equal(gss_mech_krb5, mech_type) && !g_OID_equal(gss_mech_krb5_old, mech_type)) { *minor_status = 0; return(GSS_S_BAD_MECH); } return(gss_duplicate_name(minor_status, input_name, output_name)); }
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/stat.h> #include <ctype.h> #include <pwd.h> #include <gfarm/gflog.h> #include <gfarm/error.h> #include "gssapi.h" #include "gfevent.h" #include "gfutil.h" #include "thrsubr.h" #include "tcputil.h" #include "gfsl_config.h" #include "gfarm_gsi.h" #if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS #include "gfarm_auth.h" #endif static pthread_mutex_t gss_mutex = PTHREAD_MUTEX_INITIALIZER; static const char gssDiag[] = "gss_mutex"; static char **gssCrackStatus(OM_uint32 statValue, int statType); static int gssInitiateSecurityContextSwitch(struct gfarmGssInitiateSecurityContextState *state); static int gssInitiateSecurityContextNext(struct gfarmGssInitiateSecurityContextState *state); static void gfarmGssInitiateSecurityContextSendToken(int events, int fd, void *closure, const struct timeval *t); static void gfarmGssInitiateSecurityContextReceiveToken(int events, int fd, void *closure, const struct timeval *t); static char ** gssCrackStatus(OM_uint32 statValue, int statType) { OM_uint32 msgCtx; OM_uint32 minStat; gss_buffer_desc stStr; char **ret, **ret_new; int i = 0; char *dP; GFARM_MALLOC_ARRAY(ret, 1); if (ret == NULL) { gflog_error(GFARM_MSG_1003406, "gssCrackStatus: no memory"); return (ret); } ret[0] = NULL; while (1) { msgCtx = 0; gss_display_status(&minStat, statValue, statType, GSS_C_NO_OID, &msgCtx, &stStr); GFARM_REALLOC_ARRAY(ret_new, ret, i + 2); if (ret_new == NULL) { gflog_error(GFARM_MSG_1003407, "gssCrackStatus: no memory"); goto free_ret; } ret = ret_new; GFARM_MALLOC_ARRAY(ret[i], stStr.length + 1); if (ret[i] == NULL) { gflog_error(GFARM_MSG_1003408, "gssCrackStatus: no memory"); goto free_ret; } dP = ret[i]; dP[stStr.length] = '\0'; i++; memcpy(dP, stStr.value, stStr.length); gss_release_buffer(&minStat, &stStr); if (msgCtx == 0) { break; } } ret[i] = NULL; return (ret); free_ret: for (--i; i >= 0; --i) free(ret[i]); free(ret); return (ret); } void gfarmGssFreeCrackedStatus(char **strPtr) { char **cpS = strPtr; while (*cpS != NULL) free(*cpS++); free(strPtr); } char ** gfarmGssCrackMajorStatus(OM_uint32 majStat) { return gssCrackStatus(majStat, GSS_C_GSS_CODE); } char ** gfarmGssCrackMinorStatus(OM_uint32 minStat) { return gssCrackStatus(minStat, GSS_C_MECH_CODE); } static void gfarmGssPrintStatus(char **list, const char *diag) { char **lP = list; if (lP != NULL && *lP != NULL) { while (*lP != NULL) { gflog_info(GFARM_MSG_1000607, "\t : %s", *lP++); } } else gflog_info(GFARM_MSG_1000608, "GSS %s Status Error: UNKNOWN", diag); gfarmGssFreeCrackedStatus(list); } void gfarmGssPrintMajorStatus(OM_uint32 majStat) { gfarmGssPrintStatus(gfarmGssCrackMajorStatus(majStat), "Major"); } void gfarmGssPrintMinorStatus(OM_uint32 minStat) { gfarmGssPrintStatus(gfarmGssCrackMinorStatus(minStat), "Minor"); } int gfarmGssImportName(gss_name_t *namePtr, void *nameValue, size_t nameLength, gss_OID nameType, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr) { OM_uint32 majStat = 0; OM_uint32 minStat = 0; int ret = -1; gss_buffer_desc buf; #if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS if (nameType == GSS_C_NT_USER_NAME) { char *user; gfarmAuthEntry *aePtr; GFARM_MALLOC_ARRAY(user, nameLength + 1); if (user == NULL) { gflog_auth_error(GFARM_MSG_1000611, "gfarmGssImportName(): no memory"); majStat = GSS_S_FAILURE; minStat = GFSL_DEFAULT_MINOR_ERROR; goto Done; } memcpy(user, nameValue, nameLength); user[nameLength] = '\0'; aePtr = gfarmAuthGetLocalUserEntry(user); if (aePtr == NULL) { gflog_auth_error(GFARM_MSG_1000612, "%s: ERROR: cannot convert " "this user name to X.509 Distinguish name", user); free(user); majStat = GSS_S_FAILURE; minStat = GFSL_DEFAULT_MINOR_ERROR; goto Done; } free(user); assert(aePtr->authType == GFARM_AUTH_USER); nameValue = aePtr->distName; nameLength = strlen(aePtr->distName); nameType = GSS_C_NO_OID; /* mechanism specific */ } #endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */ buf.length = nameLength; buf.value = nameValue; majStat = gss_import_name(&minStat, &buf, nameType, namePtr); if (majStat == GSS_S_COMPLETE) { ret = 1; /* OK */ } #if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS Done: #endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */ if (majStatPtr != NULL) { *majStatPtr = majStat; } if (minStatPtr != NULL) { *minStatPtr = minStat; } return ret; } int gfarmGssImportNameOfHostBasedService(gss_name_t *namePtr, char *service, char *hostname, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr) { OM_uint32 majStat; OM_uint32 minStat; int ret = -1; size_t nameLength = strlen(service) + 1 + strlen(hostname); char *nameString; GFARM_MALLOC_ARRAY(nameString, nameLength + 1); if (nameString == NULL) { gflog_auth_error(GFARM_MSG_1000613, "gfarmGssImportNameOfHostBasedService(): " "no memory"); majStat = GSS_S_FAILURE; minStat = GFSL_DEFAULT_MINOR_ERROR; } else { sprintf(nameString, "%s@%s", service, hostname); if (gfarmGssImportName(namePtr, nameString, nameLength, GSS_C_NT_HOSTBASED_SERVICE, &majStat, &minStat) > 0) { ret = 1; } free(nameString); } if (majStatPtr != NULL) { *majStatPtr = majStat; } if (minStatPtr != NULL) { *minStatPtr = minStat; } return ret; } int gfarmGssImportNameOfHost(gss_name_t *namePtr, char *hostname, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr) { return gfarmGssImportNameOfHostBasedService(namePtr, "host", hostname, majStatPtr, minStatPtr); } int gfarmGssDeleteName(gss_name_t *namePtr, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr) { OM_uint32 majStat; OM_uint32 minStat; majStat = gss_release_name(&minStat, namePtr); if (majStatPtr != NULL) { *majStatPtr = majStat; } if (minStatPtr != NULL) { *minStatPtr = minStat; } return majStat == GSS_S_COMPLETE ? 1 : -1; } #if 0 /* gss_duplicate_name() is not implemented at least in globus-2 yet. */ int gfarmGssDuplicateName(gss_name_t *outputNamePtr, const gss_name_t inputName, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr) { OM_uint32 majStat; OM_uint32 minStat; majStat = gss_duplicate_name(&minStat, inputName, outputNamePtr); if (majStatPtr != NULL) { *majStatPtr = majStat; } if (minStatPtr != NULL) { *minStatPtr = minStat; } return majStat == GSS_S_COMPLETE ? 1 : -1; }
GSSName::GSSName ( const GSSName& n ) { this->hashKey = n.hashKey; if (GSS_C_NO_NAME == n.name) { major_status = 0; minor_status = 0; name = GSS_C_NO_NAME; } else { this->major_status = gss_duplicate_name(&minor_status, n.name, &name); if ( GSS_ERROR(major_status) ) { throw GSSException("Cannot copy a GSS name.", major_status, minor_status); } } this->skipRelease = false; }
bool svcauth_gss_set_svc_name(gss_name_t name) { OM_uint32 maj_stat, min_stat; if (svcauth_gss_name != NULL) { maj_stat = gss_release_name(&min_stat, &svcauth_gss_name); if (maj_stat != GSS_S_COMPLETE) return (false); svcauth_gss_name = NULL; } /* XXX Ganesha */ if (svcauth_gss_name == GSS_C_NO_NAME) return (true); maj_stat = gss_duplicate_name(&min_stat, name, &svcauth_gss_name); if (maj_stat != GSS_S_COMPLETE) return (false); return (true); }
GSSName& GSSName::operator= ( const GSSName& rhs ) { if (rhs.toGss() != this->toGss()) { this->function = rhs.function; if (GSS_C_NO_NAME == rhs.name) { major_status = 0; minor_status = 0; name = GSS_C_NO_NAME; } else { this->major_status = gss_duplicate_name(&minor_status, rhs.name, &name); if ( GSS_ERROR(major_status) ) { throw GSSException("Cannot copy a GSS name.", major_status, minor_status); } } this->hashKey = ""; this->skipRelease = rhs.skipRelease; } return *this; }
OM_uint32 gss_acquire_cred (OM_uint32 * minor_status, const gss_name_t desired_name, OM_uint32 time_req, const 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 ) { gss_cred_id_t handle; OM_uint32 ret; if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) { *minor_status = GSS_KRB5_S_G_BAD_USAGE; return GSS_S_FAILURE; } GSSAPI_KRB5_INIT (); *output_cred_handle = NULL; if (time_rec) *time_rec = 0; if (actual_mechs) *actual_mechs = GSS_C_NO_OID_SET; if (desired_mechs) { int present = 0; ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM, desired_mechs, &present); if (ret) return ret; if (!present) { *minor_status = 0; return GSS_S_BAD_MECH; } } handle = (gss_cred_id_t)malloc(sizeof(*handle)); if (handle == GSS_C_NO_CREDENTIAL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } memset(handle, 0, sizeof (*handle)); HEIMDAL_MUTEX_init(&handle->cred_id_mutex); if (desired_name != GSS_C_NO_NAME) { ret = gss_duplicate_name(minor_status, desired_name, &handle->principal); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } } if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) { ret = acquire_initiator_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); krb5_free_principal(gssapi_krb5_context, handle->principal); free(handle); return (ret); } } if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) { ret = acquire_acceptor_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); krb5_free_principal(gssapi_krb5_context, handle->principal); free(handle); return (ret); } } ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret == GSS_S_COMPLETE) ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, &handle->mechanisms); if (ret == GSS_S_COMPLETE) ret = gss_inquire_cred(minor_status, handle, NULL, time_rec, NULL, actual_mechs); if (ret != GSS_S_COMPLETE) { if (handle->mechanisms != NULL) gss_release_oid_set(NULL, &handle->mechanisms); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); krb5_free_principal(gssapi_krb5_context, handle->principal); free(handle); return (ret); } *minor_status = 0; if (time_rec) { ret = gssapi_lifetime_left(minor_status, handle->lifetime, time_rec); if (ret) return ret; } handle->usage = cred_usage; *output_cred_handle = handle; return (GSS_S_COMPLETE); }
OM_uint32 srp_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, 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) { int oid_len = 0; int state = 0; srp_gss_cred_id_t srp_cred = NULL; unsigned char *ptr = NULL; int ptr_len = 0; OM_uint32 maj = 0; OM_uint32 min = 0; OM_uint32 tmp_maj = 0; OM_uint32 tmp_min = 0; gss_buffer_desc input_token_srp = {0}; srp_gss_ctx_id_t srp_context_handle = NULL; krb5_error_code krb5_err = 0; gss_cred_id_t srp_cred_handle = NULL; if (minor_status == NULL || output_token == GSS_C_NO_BUFFER || context_handle == NULL) { return GSS_S_CALL_INACCESSIBLE_WRITE; } if (input_token == GSS_C_NO_BUFFER) { return GSS_S_CALL_INACCESSIBLE_READ; } if (minor_status) { *minor_status = 0; } if (output_token != GSS_C_NO_BUFFER) { output_token->length = 0; output_token->value = NULL; } if (!context_handle) { maj = GSS_S_FAILURE; goto error; } if (*context_handle) { srp_context_handle = (srp_gss_ctx_id_t) *context_handle; } else { /* First call, allocate context handle */ srp_context_handle = (srp_gss_ctx_id_t) calloc(1, sizeof(srp_gss_ctx_id_rec)); if (!srp_context_handle) { min = ENOMEM; maj = GSS_S_FAILURE; goto error; } memset(srp_context_handle, 0, sizeof(srp_gss_ctx_id_rec)); /* Needed for Kerberos AES256-SHA1 keyblock generation */ krb5_err = krb5_init_context(&srp_context_handle->krb5_ctx); if (krb5_err) { maj = GSS_S_FAILURE; min = krb5_err; goto error; } maj = srp_gss_acquire_cred( &min, GSS_C_NO_NAME, 0, NULL, GSS_C_ACCEPT, &srp_cred_handle, NULL, NULL); if (maj) { goto error; } srp_cred = (srp_gss_cred_id_t) srp_cred_handle; srp_context_handle->magic_num = SRP_MAGIC_ID; maj = srp_gss_duplicate_oid(&min, srp_cred->srp_mech_oid, &srp_context_handle->mech); if (maj) { goto error; } srp_context_handle->state = SRP_AUTH_INIT; srp_context_handle->cred = (srp_gss_cred_id_t) verifier_cred_handle; *context_handle = (gss_ctx_id_t) srp_context_handle; } ptr = (unsigned char*) input_token->value; ptr_len = (int) input_token->length; maj = srp_gss_validate_oid_header( &min, input_token, &oid_len); if (maj) { goto error; } ptr += oid_len; ptr_len -= oid_len; input_token_srp.value = ptr; input_token_srp.length = ptr_len; /* This is the "t" field of ber_scanf() */ state = SRP_AUTH_STATE_VALUE(ptr[0]); /* Verify state machine is consistent with expected state */ state = SRP_AUTH_STATE_VALUE(ptr[0]); if (state != srp_context_handle->state) { maj = GSS_S_FAILURE; goto error; } switch(state) { case SRP_AUTH_INIT: srp_debug_printf("srp_gss_accept_sec_context: state=SRP_AUTH_INIT\n"); maj = _srp_gss_auth_init(minor_status, srp_context_handle, state, &input_token_srp, output_token); if (maj) { if (maj == GSS_S_CONTINUE_NEEDED) { srp_context_handle->state = SRP_AUTH_CLIENT_VALIDATE; } goto error; } break; case SRP_AUTH_CLIENT_VALIDATE: srp_debug_printf("srp_gss_accept_sec_context: " "state=SRP_AUTH_CLIENT_VALIDATE\n"); maj = _srp_gss_validate_client(minor_status, srp_context_handle, state, &input_token_srp, output_token); if (maj != GSS_S_CONTINUE_NEEDED && maj != GSS_S_COMPLETE) { /* Hard error occurred */ goto error; } srp_context_handle->state = SRP_AUTH_COMPLETE; if (mech_type) { /* The security mechanism with which the context was established. * If the security mechanism type is not required, specify NULL * for this parameter. The gss_OID value returned for this * parameter points to a read-only structure and must not be * released by the application. */ *mech_type = srp_context_handle->mech; } if (src_name) { /* Optional: Return UPN name to caller */ tmp_maj = gss_duplicate_name( &tmp_min, srp_context_handle->gss_upn_name, src_name); if (tmp_maj) { maj = tmp_maj; *minor_status = tmp_min; goto error; } } break; /* This should never happen, but include for completeness-sake */ case SRP_AUTH_COMPLETE: srp_debug_printf("srp_gss_accept_sec_context: " "state=SRP_AUTH_COMPLETE\n"); maj = GSS_S_COMPLETE; break; default: srp_debug_printf("srp_gss_accept_sec_context: state=UNKNOWN!!!\n"); maj = GSS_S_FAILURE; goto error; break; } if (srp_context_handle->state == SRP_AUTH_COMPLETE) { PVMDIR_SERVER_CONTEXT hServer = srp_context_handle->hServer; #ifdef SRP_FIPS_ENABLED krb5_err = srp_make_enc_keyblock_FIPS(srp_context_handle); #else krb5_err = srp_make_enc_keyblock(srp_context_handle); #endif if (krb5_err) { maj = GSS_S_FAILURE; min = krb5_err; goto error; } if (srp_context_handle->bUseCSRP) { srp_verifier_delete(srp_context_handle->srp_ver); } else { /* Clean up SRP server-side memory, then close the server context */ cli_rpc_srp_verifier_delete( hServer->hBinding, (void **) &srp_context_handle->srp_ver); VmDirCloseServer(hServer); srp_context_handle->hServer = NULL; } } error: if (maj != GSS_S_CONTINUE_NEEDED && maj != GSS_S_COMPLETE) { _srp_gss_accept_sec_ctx_error_resp( minor_status, output_token); } if (srp_cred_handle) { srp_gss_release_cred(&tmp_min, &srp_cred_handle); } return maj; }
OM_uint32 srp_gss_acquire_cred( 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 major = 0; OM_uint32 minor = 0; srp_gss_cred_id_t srp_cred = NULL; gss_name_t username_buf = NULL; /* Official "UNIX OID" */ int gssapi_srp_mech_oid_len = GSSAPI_UNIX_MECH_OID_LEN_ST; unsigned char *srp_mech_oid = GSSAPI_UNIX_MECH_OID_ST; /* Allocate the cred structure */ srp_cred = (srp_gss_cred_id_t) gssalloc_malloc(sizeof(*srp_cred)); if (!srp_cred) { minor = ENOMEM; major = GSS_S_FAILURE; goto error; } memset(srp_cred, 0, sizeof(*srp_cred)); /* Allocate/set the mech OID; must be SRP for this method to be called */ srp_cred->srp_mech_oid = (gss_OID) gssalloc_malloc(sizeof(*srp_cred->srp_mech_oid)); if (!srp_cred->srp_mech_oid) { minor = ENOMEM; major = GSS_S_FAILURE; goto error; } memset(srp_cred->srp_mech_oid, 0, sizeof(*srp_cred->srp_mech_oid)); srp_cred->srp_mech_oid->elements = (void *) gssalloc_malloc(gssapi_srp_mech_oid_len); if (!srp_cred->srp_mech_oid->elements) { minor = ENOMEM; major = GSS_S_FAILURE; goto error; } srp_cred->srp_mech_oid->length = gssapi_srp_mech_oid_len; memcpy(srp_cred->srp_mech_oid->elements, srp_mech_oid, gssapi_srp_mech_oid_len); if (desired_name) { major = gss_duplicate_name(&minor, desired_name, &username_buf); if (major) { goto error; } srp_cred->name = username_buf, username_buf = NULL; } *output_cred_handle = (gss_cred_id_t) srp_cred; error: if (major || minor) { *minor_status = minor; if (srp_cred) { if (srp_cred->srp_mech_oid) { if (srp_cred->srp_mech_oid->elements) { gssalloc_free(srp_cred->srp_mech_oid->elements); } gssalloc_free(srp_cred->srp_mech_oid); } gssalloc_free(srp_cred); } } return major; }