示例#1
0
文件: iakerb.c 项目: greghudson/krb5
/*
 * Allocate and initialise an IAKERB context
 */
static krb5_error_code
iakerb_alloc_context(iakerb_ctx_id_t *pctx, int initiate)
{
    iakerb_ctx_id_t ctx;
    krb5_error_code code;

    *pctx = NULL;

    ctx = k5alloc(sizeof(*ctx), &code);
    if (ctx == NULL)
        goto cleanup;
    ctx->defcred = GSS_C_NO_CREDENTIAL;
    ctx->magic = KG_IAKERB_CONTEXT;
    ctx->state = IAKERB_AS_REQ;
    ctx->count = 0;
    ctx->initiate = initiate;
    ctx->established = 0;

    code = krb5_gss_init_context(&ctx->k5c);
    if (code != 0)
        goto cleanup;

    *pctx = ctx;

cleanup:
    if (code != 0)
        iakerb_release_context(ctx);

    return code;
}
示例#2
0
OM_uint32 KRB5_CALLCONV
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;
    }

    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);

}
示例#3
0
OM_uint32 KRB5_CALLCONV
krb5_gss_set_name_attribute(OM_uint32 *minor_status,
                            gss_name_t name,
                            int complete,
                            gss_buffer_t attr,
                            gss_buffer_t value)
{
    krb5_context context;
    krb5_error_code code;
    krb5_gss_name_t kname;
    krb5_data kattr;
    krb5_data kvalue;

    if (minor_status != NULL)
        *minor_status = 0;

    code = krb5_gss_init_context(&context);
    if (code != 0) {
        *minor_status = code;
        return GSS_S_FAILURE;
    }

    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;

    kvalue.data = (char *)value->value;
    kvalue.length = value->length;

    code = krb5_authdata_set_attribute(context,
                                       kname->ad_context,
                                       complete,
                                       &kattr,
                                       &kvalue);

    k5_mutex_unlock(&kname->lock);
    krb5_free_context(context);

    return kg_map_name_error(minor_status, code);
}
示例#4
0
OM_uint32 KRB5_CALLCONV
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;
    }

    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 = data_list_to_buffer_set(context, kattrs, attrs);
    kattrs = NULL;
    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);
}
示例#5
0
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);
}
示例#6
0
OM_uint32 KRB5_CALLCONV
krb5_gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
                     gss_cred_id_t *cred_handle)
{
    OM_uint32 status = GSS_S_COMPLETE;
    krb5_context context;
    krb5_error_code ret;
    krb5_gss_cred_id_t cred;
    k5_json_value v = NULL;
    k5_json_array array;
    k5_json_string str;
    char *copy = NULL;

    ret = krb5_gss_init_context(&context);
    if (ret) {
        *minor_status = ret;
        return GSS_S_FAILURE;
    }

    /* Decode token. */
    copy = k5memdup0(token->value, token->length, &ret);
    if (copy == NULL) {
        status = GSS_S_FAILURE;
        *minor_status = ret;
        goto cleanup;
    }
    if (k5_json_decode(copy, &v))
        goto invalid;

    /* Decode the CRED_EXPORT_MAGIC array wrapper. */
    if (k5_json_get_tid(v) != K5_JSON_TID_ARRAY)
        goto invalid;
    array = v;
    if (k5_json_array_length(array) != 2)
        goto invalid;
    str = check_element(array, 0, K5_JSON_TID_STRING);
    if (str == NULL ||
        strcmp(k5_json_string_utf8(str), CRED_EXPORT_MAGIC) != 0)
        goto invalid;
    if (json_to_kgcred(context, k5_json_array_get(array, 1), &cred))
        goto invalid;

    *cred_handle = (gss_cred_id_t)cred;

cleanup:
    free(copy);
    k5_json_release(v);
    krb5_free_context(context);
    return status;

invalid:
    status = GSS_S_DEFECTIVE_TOKEN;
    goto cleanup;
}
示例#7
0
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);

}
示例#8
0
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);
}
示例#9
0
/* The mechglue always passes null desired_mechs and actual_mechs. */
OM_uint32 KRB5_CALLCONV
krb5_gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
                                       const gss_cred_id_t impersonator_cred_handle,
                                       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 major_status;
    krb5_error_code code;
    krb5_gss_cred_id_t cred;
    krb5_context context;

    if (impersonator_cred_handle == GSS_C_NO_CREDENTIAL)
        return GSS_S_CALL_INACCESSIBLE_READ;

    if (desired_name == GSS_C_NO_NAME)
        return GSS_S_CALL_INACCESSIBLE_READ;

    if (output_cred_handle == NULL)
        return GSS_S_CALL_INACCESSIBLE_WRITE;

    if (cred_usage != GSS_C_INITIATE) {
        *minor_status = (OM_uint32)G_BAD_USAGE;
        return GSS_S_FAILURE;
    }

    *output_cred_handle = GSS_C_NO_CREDENTIAL;
    if (time_rec != NULL)
        *time_rec = 0;

    code = krb5_gss_init_context(&context);
    if (code != 0) {
        *minor_status = code;
        return GSS_S_FAILURE;
    }

    major_status = kg_cred_resolve(minor_status, context,
                                   impersonator_cred_handle, NULL);
    if (GSS_ERROR(major_status)) {
        krb5_free_context(context);
        return major_status;
    }

    major_status = kg_impersonate_name(minor_status,
                                       (krb5_gss_cred_id_t)impersonator_cred_handle,
                                       (krb5_gss_name_t)desired_name,
                                       time_req,
                                       &cred,
                                       time_rec,
                                       context);

    if (!GSS_ERROR(major_status))
        *output_cred_handle = (gss_cred_id_t)cred;

    k5_mutex_unlock(&((krb5_gss_cred_id_t)impersonator_cred_handle)->lock);
    krb5_free_context(context);

    return major_status;

}
OM_uint32 KRB5_CALLCONV
gss_krb5int_copy_ccache(OM_uint32 *minor_status,
                        gss_cred_id_t cred_handle,
                        const gss_OID desired_object,
                        const gss_buffer_t value)
{
    krb5_gss_cred_id_t k5creds;
    krb5_cc_cursor cursor;
    krb5_creds creds;
    krb5_error_code code;
    krb5_context context;
    krb5_ccache out_ccache;

    assert(value->length == sizeof(out_ccache));

    if (value->length != sizeof(out_ccache))
        return GSS_S_FAILURE;

    out_ccache = (krb5_ccache)value->value;

    /* cred handle will have been validated by gssspi_set_cred_option() */

    k5creds = (krb5_gss_cred_id_t) cred_handle;
    code = k5_mutex_lock(&k5creds->lock);
    if (code) {
        *minor_status = code;
        return GSS_S_FAILURE;
    }
    if (k5creds->usage == GSS_C_ACCEPT) {
        k5_mutex_unlock(&k5creds->lock);
        *minor_status = (OM_uint32) G_BAD_USAGE;
        return(GSS_S_FAILURE);
    }

    code = krb5_gss_init_context(&context);
    if (code) {
        k5_mutex_unlock(&k5creds->lock);
        *minor_status = code;
        return GSS_S_FAILURE;
    }

    code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor);
    if (code) {
        k5_mutex_unlock(&k5creds->lock);
        *minor_status = code;
        save_error_info(*minor_status, context);
        krb5_free_context(context);
        return(GSS_S_FAILURE);
    }
    while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor,
                                       &creds)) {
        code = krb5_cc_store_cred(context, out_ccache, &creds);
        krb5_free_cred_contents(context, &creds);
    }
    krb5_cc_end_seq_get(context, k5creds->ccache, &cursor);
    k5_mutex_unlock(&k5creds->lock);
    *minor_status = code;
    if (code)
        save_error_info(*minor_status, context);
    krb5_free_context(context);
    return code ? GSS_S_FAILURE : GSS_S_COMPLETE;
}
示例#11
0
OM_uint32 KRB5_CALLCONV
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;
    }

    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);
}
示例#12
0
OM_uint32 KRB5_CALLCONV
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;
    }

    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)
            code = data_to_gss(&kvalue, value);

        if (authenticated != NULL)
            *authenticated = kauthenticated;
        if (complete != NULL)
            *complete = kcomplete;

        if (display_value != NULL) {
            if (code == 0)
                code = data_to_gss(&kdisplay_value, display_value);
            else
                free(kdisplay_value.data);
        }
    }

    k5_mutex_unlock(&kname->lock);
    krb5_free_context(context);

    return kg_map_name_error(minor_status, code);
}
示例#13
0
OM_uint32
krb5_gss_map_name_to_any(OM_uint32 *minor_status,
                         gss_name_t name,
                         int authenticated,
                         gss_buffer_t type_id,
                         gss_any_t *output)
{
    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_export_internal(context,
                                         kname->ad_context,
                                         authenticated,
                                         kmodule,
                                         (void **)output);

    k5_mutex_unlock(&kname->lock);
    krb5_free_context(context);

    return kg_map_name_error(minor_status, code);
}
示例#14
0
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);
}
示例#15
0
static OM_uint32
copy_initiator_creds(OM_uint32 *minor_status,
                     gss_cred_id_t input_cred_handle,
                     const gss_OID desired_mech,
                     OM_uint32 overwrite_cred,
                     OM_uint32 default_cred)
{
    OM_uint32 major_status;
    krb5_error_code code;
    krb5_gss_cred_id_t kcred = NULL;
    krb5_context context = NULL;
    krb5_ccache ccache = NULL;

    if (!default_cred) {
        *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    code = krb5_gss_init_context(&context);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    major_status = krb5_gss_validate_cred_1(minor_status,
                                            input_cred_handle,
                                            context);
    if (GSS_ERROR(major_status))
        goto cleanup;

    kcred = (krb5_gss_cred_id_t)input_cred_handle;

    if (kcred->ccache == NULL || kcred->proxy_cred) {
        *minor_status = KG_CCACHE_NOMATCH;
        major_status = GSS_S_DEFECTIVE_CREDENTIAL;
        goto cleanup;
    }

    if (!overwrite_cred &&
        has_unexpired_creds(kcred, desired_mech, default_cred)) {
        major_status = GSS_S_DUPLICATE_ELEMENT;
        goto cleanup;
    }

    code = krb5int_cc_default(context, &ccache);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    code = krb5_cc_copy_creds(context, kcred->ccache, ccache);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    *minor_status = 0;
    major_status = GSS_S_COMPLETE;

cleanup:
    if (kcred != NULL)
        k5_mutex_unlock(&kcred->lock);
    if (ccache != NULL)
        krb5_cc_close(context, ccache);
    krb5_free_context(context);

    return major_status;
}
示例#16
0
static OM_uint32
copy_initiator_creds(OM_uint32 *minor_status,
                     gss_cred_id_t input_cred_handle,
                     const gss_OID desired_mech,
                     OM_uint32 overwrite_cred,
                     OM_uint32 default_cred,
                     gss_const_key_value_set_t cred_store)
{
    OM_uint32 major_status;
    krb5_error_code code;
    krb5_gss_cred_id_t kcred = NULL;
    krb5_context context = NULL;
    krb5_ccache ccache = NULL;
    const char *ccache_name;

    *minor_status = 0;

    if (!default_cred && cred_store == GSS_C_NO_CRED_STORE) {
        *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    code = krb5_gss_init_context(&context);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    major_status = krb5_gss_validate_cred_1(minor_status,
                                            input_cred_handle,
                                            context);
    if (GSS_ERROR(major_status))
        goto cleanup;

    kcred = (krb5_gss_cred_id_t)input_cred_handle;

    if (kcred->ccache == NULL) {
        *minor_status = KG_CCACHE_NOMATCH;
        major_status = GSS_S_DEFECTIVE_CREDENTIAL;
        goto cleanup;
    }

    if (!overwrite_cred &&
        has_unexpired_creds(kcred, desired_mech, default_cred, cred_store)) {
        major_status = GSS_S_DUPLICATE_ELEMENT;
        goto cleanup;
    }

    major_status = kg_value_from_cred_store(cred_store,
                                            KRB5_CS_CCACHE_URN, &ccache_name);
    if (GSS_ERROR(major_status))
        goto cleanup;

    if (ccache_name != NULL) {
        code = krb5_cc_resolve(context, ccache_name, &ccache);
        if (code != 0) {
            *minor_status = code;
            major_status = GSS_S_CRED_UNAVAIL;
            goto cleanup;
        }
        code = krb5_cc_initialize(context, ccache,
                                  kcred->name->princ);
        if (code != 0) {
            *minor_status = code;
            major_status = GSS_S_CRED_UNAVAIL;
            goto cleanup;
        }
    }

    if (ccache == NULL) {
        if (!default_cred) {
            *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
            major_status = GSS_S_FAILURE;
            goto cleanup;
        }
        code = krb5int_cc_default(context, &ccache);
        if (code != 0) {
            *minor_status = code;
            major_status = GSS_S_FAILURE;
            goto cleanup;
        }
    }

    code = krb5_cc_copy_creds(context, kcred->ccache, ccache);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    *minor_status = 0;
    major_status = GSS_S_COMPLETE;

cleanup:
    if (kcred != NULL)
        k5_mutex_unlock(&kcred->lock);
    if (ccache != NULL)
        krb5_cc_close(context, ccache);
    krb5_free_context(context);

    return major_status;
}