OM_uint32 _netlogon_inquire_cred_by_mech ( OM_uint32 * minor_status, const gss_cred_id_t cred_handle, const gss_OID mech_type, gss_name_t * name, OM_uint32 * initiator_lifetime, OM_uint32 * acceptor_lifetime, gss_cred_usage_t * cred_usage ) { OM_uint32 ret; const gssnetlogon_cred cred = (const gssnetlogon_cred)cred_handle; if (name != NULL) { ret = _netlogon_duplicate_name(minor_status, (const gss_name_t)cred->Name, name); if (GSS_ERROR(ret)) return ret; } if (initiator_lifetime != NULL) *initiator_lifetime = GSS_C_INDEFINITE; if (acceptor_lifetime != NULL) *acceptor_lifetime = GSS_C_INDEFINITE; if (cred_usage != NULL) *cred_usage = GSS_C_INITIATE; *minor_status = 0; return GSS_S_COMPLETE; }
OM_uint32 _netlogon_canonicalize_name ( OM_uint32 * minor_status, const gss_name_t input_name, const gss_OID mech_type, gss_name_t * output_name ) { return _netlogon_duplicate_name(minor_status, input_name, output_name); }
OM_uint32 _netlogon_inquire_context ( OM_uint32 * minor_status, const gss_ctx_id_t context_handle, gss_name_t * src_name, gss_name_t * targ_name, OM_uint32 * lifetime_rec, gss_OID * mech_type, OM_uint32 * ctx_flags, int * locally_initiated, int * open_context ) { const gssnetlogon_ctx ctx = (const gssnetlogon_ctx)context_handle; OM_uint32 ret; if (src_name != NULL) { ret = _netlogon_duplicate_name(minor_status, (gss_name_t)ctx->SourceName, (gss_name_t *)src_name); if (GSS_ERROR(ret)) return ret; } if (targ_name != NULL) { ret = _netlogon_duplicate_name(minor_status, (gss_name_t)ctx->TargetName, (gss_name_t *)targ_name); if (GSS_ERROR(ret)) return ret; } if (mech_type != NULL) *mech_type = GSS_NETLOGON_MECHANISM; if (ctx_flags != NULL) *ctx_flags = ctx->GssFlags; if (locally_initiated != NULL) *locally_initiated = ctx->LocallyInitiated; if (open_context != NULL) *open_context = (ctx->State == NL_AUTH_ESTABLISHED); return GSS_S_COMPLETE; }
OM_uint32 _netlogon_acquire_cred(OM_uint32 * min_stat, 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) { OM_uint32 ret; gssnetlogon_cred cred; /* only initiator support so far */ if (cred_usage != GSS_C_INITIATE) return GSS_S_FAILURE; if (desired_name == GSS_C_NO_NAME) return GSS_S_BAD_NAME; cred = (gssnetlogon_cred)calloc(1, sizeof(*cred)); if (cred == NULL) { *min_stat = ENOMEM; return GSS_S_FAILURE; } cred->SignatureAlgorithm = NL_SIGN_ALG_HMAC_MD5; cred->SealAlgorithm = NL_SEAL_ALG_RC4; ret = _netlogon_duplicate_name(min_stat, desired_name, (gss_name_t *)&cred->Name); if (GSS_ERROR(ret)) { free(cred); return ret; } *output_cred_handle = (gss_cred_id_t)cred; if (actual_mechs != NULL) *actual_mechs = GSS_C_NO_OID_SET; if (time_rec != NULL) *time_rec = GSS_C_INDEFINITE; return GSS_S_COMPLETE; }
OM_uint32 _netlogon_init_sec_context(OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t * context_handle, const gss_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec) { const gssnetlogon_cred cred = (const gssnetlogon_cred)initiator_cred_handle; gssnetlogon_ctx ctx = (gssnetlogon_ctx)*context_handle; const gssnetlogon_name target = (const gssnetlogon_name)target_name; OM_uint32 ret; *minor_status = 0; output_token->value = NULL; output_token->length = 0; /* Validate arguments */ if (cred == NULL) return GSS_S_NO_CRED; else if (target == NULL) return GSS_S_BAD_NAME; if (ctx == NULL) { if (input_token->length != 0) return GSS_S_DEFECTIVE_TOKEN; ret = _netlogon_alloc_context(minor_status, &ctx); if (GSS_ERROR(ret)) goto cleanup; HEIMDAL_MUTEX_lock(&ctx->Mutex); *context_handle = (gss_ctx_id_t)ctx; ctx->GssFlags = req_flags & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_DCE_STYLE); ctx->SignatureAlgorithm = cred->SignatureAlgorithm; ctx->SealAlgorithm = cred->SealAlgorithm; ret = _netlogon_duplicate_name(minor_status, (gss_name_t)cred->Name, (gss_name_t *)&ctx->SourceName); if (GSS_ERROR(ret)) goto cleanup; ret = _netlogon_duplicate_name(minor_status, (gss_name_t)target, (gss_name_t *)&ctx->TargetName); if (GSS_ERROR(ret)) goto cleanup; memcpy(ctx->SessionKey, cred->SessionKey, sizeof(cred->SessionKey)); ret = _netlogon_make_initial_auth_message(minor_status, ctx, output_token); if (GSS_ERROR(ret)) goto cleanup; } else { HEIMDAL_MUTEX_lock(&ctx->Mutex); ret = _netlogon_read_initial_auth_message(minor_status, ctx, input_token); } if (ret_flags != NULL) *ret_flags = ctx->GssFlags; if (time_rec != NULL) *time_rec = GSS_C_INDEFINITE; if (actual_mech_type != NULL) *actual_mech_type = GSS_NETLOGON_MECHANISM; cleanup: HEIMDAL_MUTEX_unlock(&ctx->Mutex); if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { OM_uint32 tmp; _netlogon_delete_sec_context(&tmp, context_handle, NULL); } return ret; }