Blame src/client/gpm_import_and_canon_name.c

Packit Service 9f2c4a
/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */
Packit Service 9f2c4a
Packit Service 9f2c4a
#include "gssapi_gpm.h"
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_display_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                           gssx_name *in_name,
Packit Service 9f2c4a
                           gss_buffer_t output_name_buffer,
Packit Service 9f2c4a
                           gss_OID *output_name_type)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    gss_buffer_desc input_name_buffer = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gssx_name *output_name = NULL;
Packit Service 9f2c4a
    uint32_t ret_maj;
Packit Service 9f2c4a
    uint32_t ret_min;
Packit Service 9f2c4a
    uint32_t discard;
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!minor_status) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!in_name) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_READ;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    if (!output_name_buffer) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (in_name->display_name.octet_string_len == 0) {
Packit Service 9f2c4a
        if (in_name->exported_name.octet_string_len == 0) {
Packit Service 9f2c4a
            return GSS_S_BAD_NAME;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        gp_conv_gssx_to_buffer(&in_name->exported_name, &input_name_buffer);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret_maj = gpm_import_name(&ret_min, &input_name_buffer,
Packit Service 9f2c4a
                                  GSS_C_NT_EXPORT_NAME, &output_name);
Packit Service 9f2c4a
        if (ret_maj) {
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        /* steal display_name and name_type */
Packit Service 9f2c4a
        in_name->display_name = output_name->display_name;
Packit Service 9f2c4a
        output_name->display_name.octet_string_len = 0;
Packit Service 9f2c4a
        output_name->display_name.octet_string_val = NULL;
Packit Service 9f2c4a
        in_name->name_type = output_name->name_type;
Packit Service 9f2c4a
        output_name->name_type.octet_string_len = 0;
Packit Service 9f2c4a
        output_name->name_type.octet_string_val = NULL;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_copy_gssx_to_string_buffer(&in_name->display_name,
Packit Service 9f2c4a
                                        output_name_buffer);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        ret_min = ret;
Packit Service 9f2c4a
        ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (output_name_type) {
Packit Service 9f2c4a
        ret = gp_conv_gssx_to_oid_alloc(&in_name->name_type, output_name_type);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            gss_release_buffer(&discard, output_name_buffer);
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret_min = 0;
Packit Service 9f2c4a
    ret_maj = GSS_S_COMPLETE;
Packit Service 9f2c4a
Packit Service 9f2c4a
done:
Packit Service 9f2c4a
    if (output_name) {
Packit Service 9f2c4a
        xdr_free((xdrproc_t)xdr_gssx_name, (char *)output_name);
Packit Service 9f2c4a
        free(output_name);
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *minor_status = ret_min;
Packit Service 9f2c4a
    return ret_maj;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_import_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                          gss_buffer_t input_name_buffer,
Packit Service 9f2c4a
                          gss_OID input_name_type,
Packit Service 9f2c4a
                          gssx_name **output_name)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    gssx_name *name;
Packit Service 9f2c4a
    uint32_t maj, min;
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!minor_status) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!input_name_buffer || !input_name_type) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_READ;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    if (!output_name) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    /* ignore call_ctx for now */
Packit Service 9f2c4a
Packit Service 9f2c4a
    maj = GSS_S_FAILURE;
Packit Service 9f2c4a
Packit Service 9f2c4a
    name = calloc(1, sizeof(gssx_name));
Packit Service 9f2c4a
    if (!name) {
Packit Service 9f2c4a
        ret = ENOMEM;
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_conv_buffer_to_gssx(input_name_buffer, &name->display_name);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_conv_oid_to_gssx(input_name_type, &name->name_type);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    maj = GSS_S_COMPLETE;
Packit Service 9f2c4a
Packit Service 9f2c4a
done:
Packit Service 9f2c4a
    *minor_status = ret;
Packit Service 9f2c4a
    if (maj == GSS_S_COMPLETE) {
Packit Service 9f2c4a
        *output_name = name;
Packit Service 9f2c4a
    } else {
Packit Service 9f2c4a
        (void)gpm_release_name(&min, &name);
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    return maj;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_export_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                          gssx_name *input_name,
Packit Service 9f2c4a
                          gss_buffer_t exported_name)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!minor_status) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!input_name) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_READ;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (input_name->exported_name.octet_string_len == 0) {
Packit Service 9f2c4a
        return GSS_S_NAME_NOT_MN;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_copy_gssx_to_buffer(&input_name->exported_name, exported_name);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        *minor_status = ret;
Packit Service 9f2c4a
        return GSS_S_FAILURE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    return GSS_S_COMPLETE;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_export_name_composite(OM_uint32 *minor_status,
Packit Service 9f2c4a
                                    gssx_name *input_name,
Packit Service 9f2c4a
                                    gss_buffer_t exported_composite_name)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!minor_status) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!input_name) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_READ;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (input_name->exported_composite_name.octet_string_len == 0) {
Packit Service 9f2c4a
        return GSS_S_NAME_NOT_MN;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_copy_gssx_to_buffer(&input_name->exported_composite_name,
Packit Service 9f2c4a
                                 exported_composite_name);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        *minor_status = ret;
Packit Service 9f2c4a
        return GSS_S_FAILURE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    return GSS_S_COMPLETE;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_duplicate_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                             gssx_name *input_name,
Packit Service 9f2c4a
                             gssx_name **dest_name)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_copy_gssx_name_alloc(input_name, dest_name);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        *minor_status = ret;
Packit Service 9f2c4a
        return GSS_S_FAILURE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    return GSS_S_COMPLETE;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_canonicalize_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                                gssx_name *input_name,
Packit Service 9f2c4a
                                const gss_OID mech_type,
Packit Service 9f2c4a
                                gssx_name **output_name)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    union gp_rpc_arg uarg;
Packit Service 9f2c4a
    union gp_rpc_res ures;
Packit Service 9f2c4a
    gssx_arg_import_and_canon_name *arg = &uarg.import_and_canon_name;
Packit Service 9f2c4a
    gssx_res_import_and_canon_name *res = &ures.import_and_canon_name;
Packit Service 9f2c4a
    uint32_t ret_maj;
Packit Service 9f2c4a
    uint32_t ret_min;
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!minor_status) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (!input_name || !mech_type) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_READ;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    if (!output_name) {
Packit Service 9f2c4a
        return GSS_S_CALL_INACCESSIBLE_WRITE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    memset(arg, 0, sizeof(gssx_arg_import_and_canon_name));
Packit Service 9f2c4a
    memset(res, 0, sizeof(gssx_res_import_and_canon_name));
Packit Service 9f2c4a
Packit Service 9f2c4a
    /* ignore call_ctx for now */
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret = gp_copy_gssx_name(input_name, &arg->input_name);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    ret = gp_conv_oid_to_gssx(mech_type, &arg->mech);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    /* execute proxy request */
Packit Service 9f2c4a
    ret = gpm_make_call(GSSX_IMPORT_AND_CANON_NAME, &uarg, &ures);
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret_min = res->status.minor_status;
Packit Service 9f2c4a
    ret_maj = res->status.major_status;
Packit Service 9f2c4a
    if (res->status.major_status) {
Packit Service 9f2c4a
        gpm_save_status(&res->status);
Packit Service 9f2c4a
        ret = 0;
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    /* steal output_name */
Packit Service 9f2c4a
    *output_name = res->output_name;
Packit Service 9f2c4a
    res->output_name = NULL;
Packit Service 9f2c4a
Packit Service 9f2c4a
done:
Packit Service 9f2c4a
    if (ret) {
Packit Service 9f2c4a
        ret_min = ret;
Packit Service 9f2c4a
        ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    gpm_free_xdrs(GSSX_IMPORT_AND_CANON_NAME, &uarg, &ures);
Packit Service 9f2c4a
    *minor_status = ret_min;
Packit Service 9f2c4a
    return ret_maj;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_inquire_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                           gssx_name *name,
Packit Service 9f2c4a
                           int *name_is_MN,
Packit Service 9f2c4a
                           gss_OID *MN_mech,
Packit Service 9f2c4a
                           gss_buffer_set_t *attrs)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    gss_buffer_set_t xattrs = GSS_C_NO_BUFFER_SET;
Packit Service 9f2c4a
    int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (name->exported_name.octet_string_len != 0) {
Packit Service 9f2c4a
        if (name_is_MN != NULL) {
Packit Service 9f2c4a
            *name_is_MN = 1;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (MN_mech != NULL) {
Packit Service 9f2c4a
        ret = gp_conv_gssx_to_oid_alloc(&name->name_type, MN_mech);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            *minor_status = ret;
Packit Service 9f2c4a
            return GSS_S_FAILURE;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (name->name_attributes.name_attributes_len != 0) {
Packit Service 9f2c4a
        xattrs = calloc(1, sizeof(gss_buffer_set_desc));
Packit Service 9f2c4a
        if (!xattrs) {
Packit Service 9f2c4a
            *minor_status = ENOMEM;
Packit Service 9f2c4a
            return GSS_S_FAILURE;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        xattrs->count = name->name_attributes.name_attributes_len;
Packit Service 9f2c4a
        xattrs->elements = calloc(xattrs->count, sizeof(gss_buffer_desc));
Packit Service 9f2c4a
        if (!xattrs->elements) {
Packit Service 9f2c4a
            free(xattrs);
Packit Service 9f2c4a
            *minor_status = ENOMEM;
Packit Service 9f2c4a
            return GSS_S_FAILURE;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        for (unsigned i = 0; i < xattrs->count; i++) {
Packit Service 9f2c4a
            ret = gp_copy_gssx_to_buffer(
Packit Service 9f2c4a
                        &name->name_attributes.name_attributes_val[i].attr,
Packit Service 9f2c4a
                        &xattrs->elements[i]);
Packit Service 9f2c4a
            if (ret) {
Packit Service 9f2c4a
                for (; i > 0; i--) {
Packit Service 9f2c4a
                    free(xattrs->elements[i-1].value);
Packit Service 9f2c4a
                }
Packit Service 9f2c4a
                free(xattrs->elements);
Packit Service 9f2c4a
                free(xattrs);
Packit Service 9f2c4a
                *minor_status = ENOMEM;
Packit Service 9f2c4a
                return GSS_S_FAILURE;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    *attrs = xattrs;
Packit Service 9f2c4a
Packit Service 9f2c4a
    return GSS_S_COMPLETE;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_release_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                           gssx_name **input_name)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    *minor_status = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (*input_name != NULL) {
Packit Service 9f2c4a
        xdr_free((xdrproc_t)xdr_gssx_name, (char *)(*input_name));
Packit Service 9f2c4a
        free(*input_name);
Packit Service 9f2c4a
        *input_name = NULL;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    return GSS_S_COMPLETE;
Packit Service 9f2c4a
}
Packit Service 9f2c4a
Packit Service 9f2c4a
OM_uint32 gpm_compare_name(OM_uint32 *minor_status,
Packit Service 9f2c4a
                           gssx_name *name1,
Packit Service 9f2c4a
                           gssx_name *name2,
Packit Service 9f2c4a
                           int *name_equal)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    gss_buffer_desc buf1 = {0};
Packit Service 9f2c4a
    gss_buffer_desc buf2 = {0};
Packit Service 9f2c4a
    gss_OID type1 = GSS_C_NO_OID;
Packit Service 9f2c4a
    gss_OID type2 = GSS_C_NO_OID;
Packit Service 9f2c4a
    uint32_t ret_maj;
Packit Service 9f2c4a
    uint32_t ret_min;
Packit Service 9f2c4a
    int c;
Packit Service 9f2c4a
Packit Service 9f2c4a
    *name_equal = 0;
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret_maj = gpm_display_name(&ret_min, name1, &buf1, &type1);
Packit Service 9f2c4a
    if (ret_maj != GSS_S_COMPLETE) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret_maj = gpm_display_name(&ret_min, name2, &buf2, &type2);
Packit Service 9f2c4a
    if (ret_maj != GSS_S_COMPLETE) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    c = buf1.length - buf2.length;
Packit Service 9f2c4a
    if (c == 0) {
Packit Service 9f2c4a
        c = memcmp(buf1.value, buf2.value, buf1.length);
Packit Service 9f2c4a
        if (c == 0) {
Packit Service 9f2c4a
            c = gss_oid_equal(type1, type2);
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    if (c != 0) {
Packit Service 9f2c4a
        *name_equal = 1;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret_min = 0;
Packit Service 9f2c4a
    ret_maj = GSS_S_COMPLETE;
Packit Service 9f2c4a
Packit Service 9f2c4a
done:
Packit Service 9f2c4a
    *minor_status = ret_min;
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &buf1);
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &buf2);
Packit Service 9f2c4a
    gss_release_oid(&ret_min, &type1);
Packit Service 9f2c4a
    gss_release_oid(&ret_min, &type2);
Packit Service 9f2c4a
    return ret_maj;
Packit Service 9f2c4a
}