Example #1
0
/*
 * Construct list of realms between client and server.
 */
static krb5_error_code
rtree_hier_realms(krb5_context context,
                  const krb5_data *client,
                  const krb5_data *server,
                  krb5_data **realms,
                  size_t *nrealms,
                  int sep)
{
    krb5_error_code retval;
    struct hstate c, s;
    krb5_data *ctweens = NULL, *stweens = NULL, *twp, *r, *rp;
    size_t nctween, nstween;

    *realms = NULL;
    *nrealms = 0;

    r = rp = NULL;
    c.str = client->data;
    c.len = client->length;
    c.dot = c.tail = NULL;
    s.str = server->data;
    s.len = server->length;
    s.dot = s.tail = NULL;

    comtail(&c, &s, sep);
    adjtail(&c, &s, sep);

    retval = rtree_hier_tweens(context, &c, &ctweens, &nctween, 1, sep);
    if (retval) goto error;
    retval = rtree_hier_tweens(context, &s, &stweens, &nstween, 0, sep);
    if (retval) goto error;

    rp = r = calloc(nctween + nstween, sizeof(krb5_data));
    if (r == NULL) {
        retval = ENOMEM;
        goto error;
    }
    /* Copy client realm "tweens" forward. */
    for (twp = ctweens; twp < &ctweens[nctween]; twp++) {
        retval = krb5int_copy_data_contents(context, twp, rp);
        if (retval) goto error;
        rp++;
    }
    /* Copy server realm "tweens" backward. */
    for (twp = &stweens[nstween]; twp-- > stweens;) {
        retval = krb5int_copy_data_contents(context, twp, rp);
        if (retval) goto error;
        rp++;
    }
error:
    free(ctweens);
    free(stweens);
    if (retval) {
        free_realmlist(context, r, rp - r);
        return retval;
    }
    *realms = r;
    *nrealms = rp - r;
    return 0;
}
Example #2
0
/*
 * Build tree by hierarchical traversal.
 */
static krb5_error_code
rtree_hier_tree(
    krb5_context context,
    const krb5_data *client,
    const krb5_data *server,
    krb5_principal **rettree,
    int sep)
{
    krb5_error_code retval;
    krb5_data *realms;
    const krb5_data *dstrealm, *srcrealm;
    krb5_principal *tree, *pprinc;
    size_t nrealms, nprincs, i;

    *rettree = NULL;
    retval = rtree_hier_realms(context, client, server,
			       &realms, &nrealms, sep);
    if (retval)
	return retval;
    nprincs = nrealms;
    pprinc = tree = calloc(nprincs + 1, sizeof(krb5_principal));
    if (tree == NULL) {
	retval = ENOMEM;
	goto error;
    }
    for (i = 0; i < nrealms; i++)
	tree[i] = NULL;
    srcrealm = client;
    for (i = 0; i < nrealms; i++) {
	dstrealm = &realms[i];
	retval = krb5_tgtname(context, dstrealm, srcrealm, pprinc++);
	if (retval) goto error;
	srcrealm = dstrealm;
    }
    *rettree = tree;
    free_realmlist(context, realms, nrealms);
    return 0;
error:
    while (pprinc != NULL && pprinc > tree) {
	krb5_free_principal(context, *--pprinc);
	*pprinc = NULL;
    }
    free_realmlist(context, realms, nrealms);
    free(tree);
    return retval;
}