OM_uint32 krb5_gss_delete_name_attribute(OM_uint32 *minor_status, gss_name_t name, gss_buffer_t attr) { krb5_context context; krb5_error_code code; krb5_gss_name_t kname; krb5_data kattr; if (minor_status != NULL) *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (!kg_validate_name(name)) { *minor_status = (OM_uint32)G_VALIDATE_FAILED; krb5_free_context(context); return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME; } kname = (krb5_gss_name_t)name; code = k5_mutex_lock(&kname->lock); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (kname->ad_context == NULL) { code = krb5_authdata_context_init(context, &kname->ad_context); if (code != 0) { *minor_status = code; k5_mutex_unlock(&kname->lock); krb5_free_context(context); return GSS_S_UNAVAILABLE; } } kattr.data = (char *)attr->value; kattr.length = attr->length; code = krb5_authdata_delete_attribute(context, kname->ad_context, &kattr); k5_mutex_unlock(&kname->lock); krb5_free_context(context); return kg_map_name_error(minor_status, code); }
OM_uint32 krb5_gss_duplicate_name(OM_uint32 *minor_status, const gss_name_t input_name, gss_name_t *dest_name) { krb5_context context; krb5_error_code code; krb5_gss_name_t princ, outprinc; if (minor_status) *minor_status = 0; code = krb5_gss_init_context(&context); if (code) { if (minor_status) *minor_status = code; return GSS_S_FAILURE; } if (! kg_validate_name(input_name)) { if (minor_status) *minor_status = (OM_uint32) G_VALIDATE_FAILED; krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } princ = (krb5_gss_name_t)input_name; if ((code = kg_duplicate_name(context, princ, KG_INIT_NAME_INTERN, &outprinc))) { *minor_status = code; save_error_info(*minor_status, context); krb5_free_context(context); return(GSS_S_FAILURE); } krb5_free_context(context); *dest_name = (gss_name_t) outprinc; assert(kg_validate_name(*dest_name)); return(GSS_S_COMPLETE); }
OM_uint32 krb5_gss_export_name(OM_uint32 *minor_status, const gss_name_t input_name, gss_buffer_t exported_name) { krb5_context context; krb5_error_code code; size_t length; char *str; unsigned char *cp; if (minor_status) *minor_status = 0; code = krb5_gss_init_context(&context); if (code) { if (minor_status) *minor_status = code; return GSS_S_FAILURE; } exported_name->length = 0; exported_name->value = NULL; if (! kg_validate_name(input_name)) { if (minor_status) *minor_status = (OM_uint32) G_VALIDATE_FAILED; krb5_free_context(context); return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); } if ((code = krb5_unparse_name(context, (krb5_principal) input_name, &str))) { if (minor_status) *minor_status = code; save_error_info((OM_uint32)code, context); krb5_free_context(context); return(GSS_S_FAILURE); } krb5_free_context(context); length = strlen(str); exported_name->length = 10 + length + gss_mech_krb5->length; exported_name->value = malloc(exported_name->length); if (!exported_name->value) { free(str); if (minor_status) *minor_status = ENOMEM; return(GSS_S_FAILURE); } cp = exported_name->value; /* Note: we assume the OID will be less than 128 bytes... */ *cp++ = 0x04; *cp++ = 0x01; store_16_be(gss_mech_krb5->length+2, cp); cp += 2; *cp++ = 0x06; *cp++ = (gss_mech_krb5->length) & 0xFF; memcpy(cp, gss_mech_krb5->elements, gss_mech_krb5->length); cp += gss_mech_krb5->length; store_32_be(length, cp); cp += 4; memcpy(cp, str, length); free(str); return(GSS_S_COMPLETE); }
OM_uint32 krb5_gss_export_name_composite(OM_uint32 *minor_status, gss_name_t name, gss_buffer_t exp_composite_name) { krb5_context context; krb5_error_code code; krb5_gss_name_t kname; krb5_data *attrs = NULL; char *princstr = NULL; unsigned char *cp; size_t princlen; if (minor_status != NULL) *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (!kg_validate_name(name)) { *minor_status = (OM_uint32)G_VALIDATE_FAILED; krb5_free_context(context); return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME; } kname = (krb5_gss_name_t)name; code = k5_mutex_lock(&kname->lock); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } code = krb5_unparse_name(context, kname->princ, &princstr); if (code != 0) goto cleanup; princlen = strlen(princstr); if (kname->ad_context != NULL) { code = krb5_authdata_export_attributes(context, kname->ad_context, AD_USAGE_MASK, &attrs); if (code != 0) goto cleanup; } /* 04 02 OID Name AuthData */ exp_composite_name->length = 10 + gss_mech_krb5->length + princlen; if (attrs != NULL) exp_composite_name->length += 4 + attrs->length; exp_composite_name->value = malloc(exp_composite_name->length); if (exp_composite_name->value == NULL) { code = ENOMEM; goto cleanup; } cp = exp_composite_name->value; /* Note: we assume the OID will be less than 128 bytes... */ *cp++ = 0x04; if (attrs != NULL) *cp++ = 0x02; else *cp++ = 0x01; store_16_be(gss_mech_krb5->length + 2, cp); cp += 2; *cp++ = 0x06; *cp++ = (gss_mech_krb5->length) & 0xFF; memcpy(cp, gss_mech_krb5->elements, gss_mech_krb5->length); cp += gss_mech_krb5->length; store_32_be(princlen, cp); cp += 4; memcpy(cp, princstr, princlen); cp += princlen; if (attrs != NULL) { store_32_be(attrs->length, cp); cp += 4; memcpy(cp, attrs->data, attrs->length); cp += attrs->length; } cleanup: krb5_free_unparsed_name(context, princstr); krb5_free_data(context, attrs); k5_mutex_unlock(&kname->lock); krb5_free_context(context); return kg_map_name_error(minor_status, code); }
OM_uint32 krb5_gss_release_any_name_mapping(OM_uint32 *minor_status, gss_name_t name, gss_buffer_t type_id, gss_any_t *input) { krb5_context context; krb5_error_code code; krb5_gss_name_t kname; char *kmodule; if (minor_status != NULL) *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (!kg_validate_name(name)) { *minor_status = (OM_uint32)G_VALIDATE_FAILED; krb5_free_context(context); return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME; } kname = (krb5_gss_name_t)name; code = k5_mutex_lock(&kname->lock); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (kname->ad_context == NULL) { code = krb5_authdata_context_init(context, &kname->ad_context); if (code != 0) { *minor_status = code; k5_mutex_unlock(&kname->lock); krb5_free_context(context); return GSS_S_UNAVAILABLE; } } kmodule = (char *)type_id->value; if (kmodule[type_id->length] != '\0') { k5_mutex_unlock(&kname->lock); krb5_free_context(context); return GSS_S_UNAVAILABLE; } code = krb5_authdata_free_internal(context, kname->ad_context, kmodule, *input); if (code == 0) *input = NULL; k5_mutex_unlock(&kname->lock); krb5_free_context(context); return kg_map_name_error(minor_status, code); }
OM_uint32 krb5_gss_get_name_attribute(OM_uint32 *minor_status, gss_name_t name, gss_buffer_t attr, int *authenticated, int *complete, gss_buffer_t value, gss_buffer_t display_value, int *more) { krb5_context context; krb5_error_code code; krb5_gss_name_t kname; krb5_data kattr; krb5_boolean kauthenticated; krb5_boolean kcomplete; krb5_data kvalue; krb5_data kdisplay_value; if (minor_status != NULL) *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (!kg_validate_name(name)) { *minor_status = (OM_uint32)G_VALIDATE_FAILED; krb5_free_context(context); return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME; } kname = (krb5_gss_name_t)name; code = k5_mutex_lock(&kname->lock); if (code != 0) { *minor_status = code; krb5_free_context(context); return GSS_S_FAILURE; } if (kname->ad_context == NULL) { code = krb5_authdata_context_init(context, &kname->ad_context); if (code != 0) { *minor_status = code; k5_mutex_unlock(&kname->lock); krb5_free_context(context); return GSS_S_UNAVAILABLE; } } kattr.data = (char *)attr->value; kattr.length = attr->length; kauthenticated = FALSE; kcomplete = FALSE; code = krb5_authdata_get_attribute(context, kname->ad_context, &kattr, &kauthenticated, &kcomplete, value ? &kvalue : NULL, display_value ? &kdisplay_value : NULL, more); if (code == 0) { if (value != NULL) { value->value = kvalue.data; value->length = kvalue.length; } if (authenticated != NULL) *authenticated = kauthenticated; if (complete != NULL) *complete = kcomplete; if (display_value != NULL) { display_value->value = kdisplay_value.data; display_value->length = kdisplay_value.length; } } k5_mutex_unlock(&kname->lock); krb5_free_context(context); return kg_map_name_error(minor_status, code); }
OM_uint32 krb5_gss_inquire_name(OM_uint32 *minor_status, gss_name_t name, int *name_is_MN, gss_OID *MN_mech, gss_buffer_set_t *attrs) { krb5_context context; krb5_error_code code; krb5_gss_name_t kname; krb5_data *kattrs = NULL; if (minor_status != NULL) *minor_status = 0; if (attrs != NULL) *attrs = GSS_C_NO_BUFFER_SET; code = krb5_gss_init_context(&context); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (!kg_validate_name(name)) { *minor_status = (OM_uint32)G_VALIDATE_FAILED; krb5_free_context(context); return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME; } kname = (krb5_gss_name_t)name; code = k5_mutex_lock(&kname->lock); if (code != 0) { *minor_status = code; return GSS_S_FAILURE; } if (kname->ad_context == NULL) { code = krb5_authdata_context_init(context, &kname->ad_context); if (code != 0) goto cleanup; } code = krb5_authdata_get_attribute_types(context, kname->ad_context, &kattrs); if (code != 0) goto cleanup; code = kg_data_list_to_buffer_set_nocopy(&kattrs, attrs); if (code != 0) goto cleanup; cleanup: k5_mutex_unlock(&kname->lock); krb5int_free_data_list(context, kattrs); krb5_free_context(context); return kg_map_name_error(minor_status, code); }