1*5e01956fSGlenn Barry /*
2*5e01956fSGlenn Barry * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3*5e01956fSGlenn Barry */
47c478bd9Sstevel@tonic-gate /*
57c478bd9Sstevel@tonic-gate * lib/krb5/krb/walk_rtree.c
67c478bd9Sstevel@tonic-gate *
77c478bd9Sstevel@tonic-gate * Copyright 1990,1991 by the Massachusetts Institute of Technology.
87c478bd9Sstevel@tonic-gate * All Rights Reserved.
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
117c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
127c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
137c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
147c478bd9Sstevel@tonic-gate *
157c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
167c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
177c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
187c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
197c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
207c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
217c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
227c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
237c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
247c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
257c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
267c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
277c478bd9Sstevel@tonic-gate * or implied warranty.
287c478bd9Sstevel@tonic-gate *
297c478bd9Sstevel@tonic-gate *
307c478bd9Sstevel@tonic-gate * krb5_walk_realm_tree()
317c478bd9Sstevel@tonic-gate */
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate /* ANL - Modified to allow Configurable Authentication Paths.
347c478bd9Sstevel@tonic-gate * This modification removes the restriction on the choice of realm
357c478bd9Sstevel@tonic-gate * names, i.e. they nolonger have to be hierarchical. This
367c478bd9Sstevel@tonic-gate * is allowed by RFC 1510: "If a hierarchical orginization is not used
377c478bd9Sstevel@tonic-gate * it may be necessary to consult some database in order to construct
387c478bd9Sstevel@tonic-gate * an authentication path between realms." The database is contained
39fe598cdcSmp153739 * in the [capaths] section of the krb5.conf file.
407c478bd9Sstevel@tonic-gate * Client to server paths are defined. There are n**2 possible
417c478bd9Sstevel@tonic-gate * entries, but only those entries which are needed by the client
427c478bd9Sstevel@tonic-gate * or server need be present in its krb5.conf file. (n entries or 2*n
437c478bd9Sstevel@tonic-gate * entries if the same krb5.conf is used for clients and servers)
447c478bd9Sstevel@tonic-gate *
457c478bd9Sstevel@tonic-gate * for example: ESnet will be running a KDC which will share
467c478bd9Sstevel@tonic-gate * inter-realm keys with its many orginizations which include among
477c478bd9Sstevel@tonic-gate * other ANL, NERSC and PNL. Each of these orginizations wants to
487c478bd9Sstevel@tonic-gate * use its DNS name in the realm, ANL.GOV. In addition ANL wants
497c478bd9Sstevel@tonic-gate * to authenticatite to HAL.COM via a K5.MOON and K5.JUPITER
50fe598cdcSmp153739 * A [capaths] section of the krb5.conf file for the ANL.GOV clients
517c478bd9Sstevel@tonic-gate * and servers would look like:
527c478bd9Sstevel@tonic-gate *
53fe598cdcSmp153739 * [capaths]
547c478bd9Sstevel@tonic-gate * ANL.GOV = {
557c478bd9Sstevel@tonic-gate * NERSC.GOV = ES.NET
567c478bd9Sstevel@tonic-gate * PNL.GOV = ES.NET
577c478bd9Sstevel@tonic-gate * ES.NET = .
587c478bd9Sstevel@tonic-gate * HAL.COM = K5.MOON
597c478bd9Sstevel@tonic-gate * HAL.COM = K5.JUPITER
607c478bd9Sstevel@tonic-gate * }
617c478bd9Sstevel@tonic-gate * NERSC.GOV = {
627c478bd9Sstevel@tonic-gate * ANL.GOV = ES.NET
637c478bd9Sstevel@tonic-gate * }
647c478bd9Sstevel@tonic-gate * PNL.GOV = {
657c478bd9Sstevel@tonic-gate * ANL.GOV = ES.NET
667c478bd9Sstevel@tonic-gate * }
677c478bd9Sstevel@tonic-gate * ES.NET = {
687c478bd9Sstevel@tonic-gate * ANL.GOV = .
697c478bd9Sstevel@tonic-gate * }
707c478bd9Sstevel@tonic-gate * HAL.COM = {
717c478bd9Sstevel@tonic-gate * ANL.GOV = K5.JUPITER
727c478bd9Sstevel@tonic-gate * ANL.GOV = K5.MOON
737c478bd9Sstevel@tonic-gate * }
747c478bd9Sstevel@tonic-gate *
757c478bd9Sstevel@tonic-gate * In the above a "." is used to mean directly connected since the
767c478bd9Sstevel@tonic-gate * the profile routines cannot handle a null entry.
777c478bd9Sstevel@tonic-gate *
787c478bd9Sstevel@tonic-gate * If no client-to-server path is found, the default hierarchical path
797c478bd9Sstevel@tonic-gate * is still generated.
807c478bd9Sstevel@tonic-gate *
817c478bd9Sstevel@tonic-gate * This version of the Configurable Authentication Path modification
827c478bd9Sstevel@tonic-gate * differs from the previous versions prior to K5 beta 5 in that
837c478bd9Sstevel@tonic-gate * the profile routines are used, and the explicite path from
847c478bd9Sstevel@tonic-gate * client's realm to server's realm must be given. The modifications
857c478bd9Sstevel@tonic-gate * will work together.
867c478bd9Sstevel@tonic-gate * DEE - 5/23/95
877c478bd9Sstevel@tonic-gate */
887c478bd9Sstevel@tonic-gate #define CONFIGURABLE_AUTHENTICATION_PATH
897c478bd9Sstevel@tonic-gate #include "k5-int.h"
907c478bd9Sstevel@tonic-gate #include "int-proto.h"
91*5e01956fSGlenn Barry #include <locale.h>
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate /* internal function, used by krb5_get_cred_from_kdc() */
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate #ifndef min
967c478bd9Sstevel@tonic-gate #define min(x,y) ((x) < (y) ? (x) : (y))
977c478bd9Sstevel@tonic-gate #define max(x,y) ((x) > (y) ? (x) : (y))
987c478bd9Sstevel@tonic-gate #endif
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate /*
1017c478bd9Sstevel@tonic-gate * xxx The following function is very confusing to read and probably
1027c478bd9Sstevel@tonic-gate * is buggy. It should be documented better. Here is what I've
1037c478bd9Sstevel@tonic-gate * learned about it doing a quick bug fixing walk through. The
1047c478bd9Sstevel@tonic-gate * function takes a client and server realm name and returns the set
1057c478bd9Sstevel@tonic-gate * of realms (in a field called tree) that you need to get tickets in
1067c478bd9Sstevel@tonic-gate * in order to get from the source realm to the destination realm. It
1077c478bd9Sstevel@tonic-gate * takes a realm separater character (normally ., but presumably there
1087c478bd9Sstevel@tonic-gate * for all those X.500 realms) . There are two modes it runs in: the
1097c478bd9Sstevel@tonic-gate * ANL krb5.conf mode and the hierarchy mode. The ANL mode is
1107c478bd9Sstevel@tonic-gate * fairly obvious. The hierarchy mode looks for common components in
1117c478bd9Sstevel@tonic-gate * both the client and server realms. In general, the pointer scp and
1127c478bd9Sstevel@tonic-gate * ccp are used to walk through the client and server realms. The
1137c478bd9Sstevel@tonic-gate * com_sdot and com_cdot pointers point to (I think) the beginning of
1147c478bd9Sstevel@tonic-gate * the common part of the realm names. I.E. strcmp(com_cdot,
1157c478bd9Sstevel@tonic-gate * com_sdot) ==0 is roughly an invarient. However, there are cases
1167c478bd9Sstevel@tonic-gate * where com_sdot and com_cdot are set to point before the start of
1177c478bd9Sstevel@tonic-gate * the client or server strings. I think this only happens when there
1187c478bd9Sstevel@tonic-gate * are no common components. --hartmans 2002/03/14
1197c478bd9Sstevel@tonic-gate */
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate krb5_error_code
krb5_walk_realm_tree(krb5_context context,const krb5_data * client,const krb5_data * server,krb5_principal ** tree,int realm_branch_char)122fe598cdcSmp153739 krb5_walk_realm_tree(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_principal **tree, int realm_branch_char)
1237c478bd9Sstevel@tonic-gate {
1247c478bd9Sstevel@tonic-gate krb5_error_code retval;
1257c478bd9Sstevel@tonic-gate krb5_principal *rettree;
1267c478bd9Sstevel@tonic-gate register char *ccp, *scp;
1277c478bd9Sstevel@tonic-gate register char *prevccp = 0, *prevscp = 0;
1287c478bd9Sstevel@tonic-gate char *com_sdot = 0, *com_cdot = 0;
1297c478bd9Sstevel@tonic-gate register int i, links = 0;
130fe598cdcSmp153739 int clen, slen = -1;
1317c478bd9Sstevel@tonic-gate krb5_data tmpcrealm, tmpsrealm;
1327c478bd9Sstevel@tonic-gate int nocommon = 1;
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate #ifdef CONFIGURABLE_AUTHENTICATION_PATH
1357c478bd9Sstevel@tonic-gate const char *cap_names[4];
1367c478bd9Sstevel@tonic-gate char *cap_client, *cap_server;
1377c478bd9Sstevel@tonic-gate char **cap_nodes;
1387c478bd9Sstevel@tonic-gate krb5_error_code cap_code;
1397c478bd9Sstevel@tonic-gate #endif
140fe598cdcSmp153739
141fe598cdcSmp153739 #ifdef DEBUG_REFERRALS
142fe598cdcSmp153739 printf("krb5_walk_realm_tree starting\n");
143fe598cdcSmp153739 printf(" client is %s\n",client->data);
144fe598cdcSmp153739 printf(" server is %s\n",server->data);
145fe598cdcSmp153739 #endif
146fe598cdcSmp153739
147*5e01956fSGlenn Barry if (!(client->data && server->data)) {
148*5e01956fSGlenn Barry /* Solaris Kerberos - enhance error message */
149*5e01956fSGlenn Barry if (!client->data && !server->data) {
150*5e01956fSGlenn Barry krb5_set_error_message(context, KRB5_NO_TKT_IN_RLM,
151*5e01956fSGlenn Barry dgettext(TEXT_DOMAIN,
152*5e01956fSGlenn Barry "Cannot find ticket for requested realm: unknown client and server"));
153*5e01956fSGlenn Barry } else {
154*5e01956fSGlenn Barry if (!client->data) {
155*5e01956fSGlenn Barry krb5_set_error_message(context, KRB5_NO_TKT_IN_RLM,
156*5e01956fSGlenn Barry dgettext(TEXT_DOMAIN,
157*5e01956fSGlenn Barry "Cannot find ticket for requested realm: unknown client"));
158*5e01956fSGlenn Barry } else {
159*5e01956fSGlenn Barry krb5_set_error_message(context, KRB5_NO_TKT_IN_RLM,
160*5e01956fSGlenn Barry dgettext(TEXT_DOMAIN,
161*5e01956fSGlenn Barry "Cannot find ticket for requested realm: unknown server"));
162*5e01956fSGlenn Barry }
163*5e01956fSGlenn Barry }
1647c478bd9Sstevel@tonic-gate return KRB5_NO_TKT_IN_RLM;
165*5e01956fSGlenn Barry }
1667c478bd9Sstevel@tonic-gate #ifdef CONFIGURABLE_AUTHENTICATION_PATH
1677c478bd9Sstevel@tonic-gate if ((cap_client = (char *)malloc(client->length + 1)) == NULL)
1687c478bd9Sstevel@tonic-gate return ENOMEM;
1697c478bd9Sstevel@tonic-gate strncpy(cap_client, client->data, client->length);
1707c478bd9Sstevel@tonic-gate cap_client[client->length] = '\0';
1717c478bd9Sstevel@tonic-gate if ((cap_server = (char *)malloc(server->length + 1)) == NULL) {
1727c478bd9Sstevel@tonic-gate krb5_xfree(cap_client);
1737c478bd9Sstevel@tonic-gate return ENOMEM;
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate strncpy(cap_server, server->data, server->length);
1767c478bd9Sstevel@tonic-gate cap_server[server->length] = '\0';
1777c478bd9Sstevel@tonic-gate cap_names[0] = "capaths";
1787c478bd9Sstevel@tonic-gate cap_names[1] = cap_client;
1797c478bd9Sstevel@tonic-gate cap_names[2] = cap_server;
1807c478bd9Sstevel@tonic-gate cap_names[3] = 0;
1817c478bd9Sstevel@tonic-gate cap_code = profile_get_values(context->profile, cap_names, &cap_nodes);
182fe598cdcSmp153739 krb5_xfree(cap_client); /* done with client string */
183fe598cdcSmp153739 cap_names[1] = 0;
1847c478bd9Sstevel@tonic-gate if (cap_code == 0) { /* found a path, so lets use it */
1857c478bd9Sstevel@tonic-gate links = 0;
1867c478bd9Sstevel@tonic-gate if (*cap_nodes[0] != '.') { /* a link of . means direct */
1877c478bd9Sstevel@tonic-gate while(cap_nodes[links]) {
1887c478bd9Sstevel@tonic-gate links++;
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate }
191fe598cdcSmp153739 if (cap_nodes[links] != NULL)
192fe598cdcSmp153739 krb5_xfree(cap_nodes[links]);
193fe598cdcSmp153739
1947c478bd9Sstevel@tonic-gate cap_nodes[links] = cap_server; /* put server on end of list */
1957c478bd9Sstevel@tonic-gate /* this simplifies the code later and make */
1967c478bd9Sstevel@tonic-gate /* cleanup eaiser as well */
1977c478bd9Sstevel@tonic-gate links++; /* count the null entry at end */
1987c478bd9Sstevel@tonic-gate } else { /* no path use hierarchical method */
199fe598cdcSmp153739 krb5_xfree(cap_server); /* failed, don't need server string */
200fe598cdcSmp153739 cap_names[2] = 0;
2017c478bd9Sstevel@tonic-gate #endif
2027c478bd9Sstevel@tonic-gate clen = client->length;
2037c478bd9Sstevel@tonic-gate slen = server->length;
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate for (com_cdot = ccp = client->data + clen - 1,
2067c478bd9Sstevel@tonic-gate com_sdot = scp = server->data + slen - 1;
2077c478bd9Sstevel@tonic-gate clen && slen && *ccp == *scp ;
2087c478bd9Sstevel@tonic-gate ccp--, scp--, clen--, slen--) {
2097c478bd9Sstevel@tonic-gate if (*ccp == realm_branch_char) {
2107c478bd9Sstevel@tonic-gate com_cdot = ccp;
2117c478bd9Sstevel@tonic-gate com_sdot = scp;
2127c478bd9Sstevel@tonic-gate nocommon = 0;
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate /* ccp, scp point to common root.
2177c478bd9Sstevel@tonic-gate com_cdot, com_sdot point to common components. */
2187c478bd9Sstevel@tonic-gate /* handle case of one ran out */
2197c478bd9Sstevel@tonic-gate if (!clen) {
2207c478bd9Sstevel@tonic-gate /* construct path from client to server, down the tree */
221*5e01956fSGlenn Barry if (!slen) {
2227c478bd9Sstevel@tonic-gate /* in the same realm--this means there is no ticket
2237c478bd9Sstevel@tonic-gate in this realm. */
224*5e01956fSGlenn Barry krb5_set_error_message(context, KRB5_NO_TKT_IN_RLM,
225*5e01956fSGlenn Barry dgettext(TEXT_DOMAIN,
226*5e01956fSGlenn Barry "Cannot find ticket for requested realm: client is '%s', server is '%s'"),
227*5e01956fSGlenn Barry client->data, server->data);
2287c478bd9Sstevel@tonic-gate return KRB5_NO_TKT_IN_RLM;
229*5e01956fSGlenn Barry }
2307c478bd9Sstevel@tonic-gate if (*scp == realm_branch_char) {
2317c478bd9Sstevel@tonic-gate /* one is a subdomain of the other */
2327c478bd9Sstevel@tonic-gate com_cdot = client->data;
2337c478bd9Sstevel@tonic-gate com_sdot = scp;
2347c478bd9Sstevel@tonic-gate nocommon = 0;
2357c478bd9Sstevel@tonic-gate } /* else normal case of two sharing parents */
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate if (!slen) {
2387c478bd9Sstevel@tonic-gate /* construct path from client to server, up the tree */
2397c478bd9Sstevel@tonic-gate if (*ccp == realm_branch_char) {
2407c478bd9Sstevel@tonic-gate /* one is a subdomain of the other */
2417c478bd9Sstevel@tonic-gate com_sdot = server->data;
2427c478bd9Sstevel@tonic-gate com_cdot = ccp;
2437c478bd9Sstevel@tonic-gate nocommon = 0;
2447c478bd9Sstevel@tonic-gate } /* else normal case of two sharing parents */
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate /* determine #links to/from common ancestor */
2477c478bd9Sstevel@tonic-gate if (nocommon)
2487c478bd9Sstevel@tonic-gate links = 1;
2497c478bd9Sstevel@tonic-gate else
2507c478bd9Sstevel@tonic-gate links = 2;
2517c478bd9Sstevel@tonic-gate /* if no common ancestor, artificially set up common root at the last
2527c478bd9Sstevel@tonic-gate component, then join with special code */
2537c478bd9Sstevel@tonic-gate for (ccp = client->data; ccp < com_cdot; ccp++) {
2547c478bd9Sstevel@tonic-gate if (*ccp == realm_branch_char) {
2557c478bd9Sstevel@tonic-gate links++;
2567c478bd9Sstevel@tonic-gate if (nocommon)
2577c478bd9Sstevel@tonic-gate prevccp = ccp;
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate for (scp = server->data; scp < com_sdot; scp++) {
2627c478bd9Sstevel@tonic-gate if (*scp == realm_branch_char) {
2637c478bd9Sstevel@tonic-gate links++;
2647c478bd9Sstevel@tonic-gate if (nocommon)
2657c478bd9Sstevel@tonic-gate prevscp = scp;
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate if (nocommon) {
2697c478bd9Sstevel@tonic-gate if (prevccp)
2707c478bd9Sstevel@tonic-gate com_cdot = prevccp;
2717c478bd9Sstevel@tonic-gate if (prevscp)
2727c478bd9Sstevel@tonic-gate com_sdot = prevscp;
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate if(com_cdot == client->data + client->length -1)
2757c478bd9Sstevel@tonic-gate com_cdot = client->data - 1 ;
2767c478bd9Sstevel@tonic-gate if(com_sdot == server->data + server->length -1)
2777c478bd9Sstevel@tonic-gate com_sdot = server->data - 1 ;
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate #ifdef CONFIGURABLE_AUTHENTICATION_PATH
2807c478bd9Sstevel@tonic-gate } /* end of if use hierarchical method */
2817c478bd9Sstevel@tonic-gate #endif
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate if (!(rettree = (krb5_principal *)calloc(links+2,
2847c478bd9Sstevel@tonic-gate sizeof(krb5_principal)))) {
2857c478bd9Sstevel@tonic-gate return ENOMEM;
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate i = 1;
2887c478bd9Sstevel@tonic-gate if ((retval = krb5_tgtname(context, client, client, &rettree[0]))) {
2897c478bd9Sstevel@tonic-gate krb5_xfree(rettree);
2907c478bd9Sstevel@tonic-gate return retval;
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate #ifdef CONFIGURABLE_AUTHENTICATION_PATH
2937c478bd9Sstevel@tonic-gate links--; /* dont count the null entry on end */
2947c478bd9Sstevel@tonic-gate if (cap_code == 0) { /* found a path above */
2957c478bd9Sstevel@tonic-gate tmpcrealm.data = client->data;
2967c478bd9Sstevel@tonic-gate tmpcrealm.length = client->length;
2977c478bd9Sstevel@tonic-gate while( i-1 <= links) {
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate tmpsrealm.data = cap_nodes[i-1];
3007c478bd9Sstevel@tonic-gate /* don't count trailing whitespace from profile_get */
3017c478bd9Sstevel@tonic-gate tmpsrealm.length = strcspn(cap_nodes[i-1],"\t ");
3027c478bd9Sstevel@tonic-gate if ((retval = krb5_tgtname(context,
3037c478bd9Sstevel@tonic-gate &tmpsrealm,
3047c478bd9Sstevel@tonic-gate &tmpcrealm,
3057c478bd9Sstevel@tonic-gate &rettree[i]))) {
3067c478bd9Sstevel@tonic-gate while (i) {
3077c478bd9Sstevel@tonic-gate krb5_free_principal(context, rettree[i-1]);
3087c478bd9Sstevel@tonic-gate i--;
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate krb5_xfree(rettree);
3117c478bd9Sstevel@tonic-gate /* cleanup the cap_nodes from profile_get */
3127c478bd9Sstevel@tonic-gate for (i = 0; i<=links; i++) {
3137c478bd9Sstevel@tonic-gate krb5_xfree(cap_nodes[i]);
3147c478bd9Sstevel@tonic-gate }
3157c478bd9Sstevel@tonic-gate krb5_xfree((char *)cap_nodes);
3167c478bd9Sstevel@tonic-gate return retval;
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate tmpcrealm.data = tmpsrealm.data;
3197c478bd9Sstevel@tonic-gate tmpcrealm.length = tmpsrealm.length;
3207c478bd9Sstevel@tonic-gate i++;
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate /* cleanup the cap_nodes from profile_get last one has server */
3237c478bd9Sstevel@tonic-gate for (i = 0; i<=links; i++) {
3247c478bd9Sstevel@tonic-gate krb5_xfree(cap_nodes[i]);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate krb5_xfree((char *)cap_nodes);
3277c478bd9Sstevel@tonic-gate } else { /* if not cap then use hierarchical method */
3287c478bd9Sstevel@tonic-gate #endif
3297c478bd9Sstevel@tonic-gate for (prevccp = ccp = client->data;
3307c478bd9Sstevel@tonic-gate ccp <= com_cdot;
3317c478bd9Sstevel@tonic-gate ccp++) {
3327c478bd9Sstevel@tonic-gate if (*ccp != realm_branch_char)
3337c478bd9Sstevel@tonic-gate continue;
3347c478bd9Sstevel@tonic-gate ++ccp; /* advance past dot */
3357c478bd9Sstevel@tonic-gate tmpcrealm.data = prevccp;
3367c478bd9Sstevel@tonic-gate tmpcrealm.length = client->length -
3377c478bd9Sstevel@tonic-gate (prevccp - client->data);
3387c478bd9Sstevel@tonic-gate tmpsrealm.data = ccp;
3397c478bd9Sstevel@tonic-gate tmpsrealm.length = client->length -
3407c478bd9Sstevel@tonic-gate (ccp - client->data);
3417c478bd9Sstevel@tonic-gate if ((retval = krb5_tgtname(context, &tmpsrealm, &tmpcrealm,
3427c478bd9Sstevel@tonic-gate &rettree[i]))) {
3437c478bd9Sstevel@tonic-gate while (i) {
3447c478bd9Sstevel@tonic-gate krb5_free_principal(context, rettree[i-1]);
3457c478bd9Sstevel@tonic-gate i--;
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate krb5_xfree(rettree);
3487c478bd9Sstevel@tonic-gate return retval;
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate prevccp = ccp;
3517c478bd9Sstevel@tonic-gate i++;
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate if (nocommon) {
3547c478bd9Sstevel@tonic-gate tmpcrealm.data = com_cdot + 1;
3557c478bd9Sstevel@tonic-gate tmpcrealm.length = client->length -
3567c478bd9Sstevel@tonic-gate (com_cdot + 1 - client->data);
3577c478bd9Sstevel@tonic-gate tmpsrealm.data = com_sdot + 1;
3587c478bd9Sstevel@tonic-gate tmpsrealm.length = server->length -
3597c478bd9Sstevel@tonic-gate (com_sdot + 1 - server->data);
3607c478bd9Sstevel@tonic-gate if ((retval = krb5_tgtname(context, &tmpsrealm, &tmpcrealm,
3617c478bd9Sstevel@tonic-gate &rettree[i]))) {
3627c478bd9Sstevel@tonic-gate while (i) {
3637c478bd9Sstevel@tonic-gate krb5_free_principal(context, rettree[i-1]);
3647c478bd9Sstevel@tonic-gate i--;
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate krb5_xfree(rettree);
3677c478bd9Sstevel@tonic-gate return retval;
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate i++;
3707c478bd9Sstevel@tonic-gate }
3717c478bd9Sstevel@tonic-gate
3727c478bd9Sstevel@tonic-gate for (prevscp = com_sdot + 1, scp = com_sdot - 1;
3737c478bd9Sstevel@tonic-gate scp > server->data;
3747c478bd9Sstevel@tonic-gate scp--) {
3757c478bd9Sstevel@tonic-gate if (*scp != realm_branch_char)
3767c478bd9Sstevel@tonic-gate continue;
3777c478bd9Sstevel@tonic-gate if (scp - 1 < server->data)
3787c478bd9Sstevel@tonic-gate break; /* XXX only if . starts realm? */
3797c478bd9Sstevel@tonic-gate tmpcrealm.data = prevscp;
3807c478bd9Sstevel@tonic-gate tmpcrealm.length = server->length -
3817c478bd9Sstevel@tonic-gate (prevscp - server->data);
3827c478bd9Sstevel@tonic-gate tmpsrealm.data = scp + 1;
3837c478bd9Sstevel@tonic-gate tmpsrealm.length = server->length -
3847c478bd9Sstevel@tonic-gate (scp + 1 - server->data);
3857c478bd9Sstevel@tonic-gate if ((retval = krb5_tgtname(context, &tmpsrealm, &tmpcrealm,
3867c478bd9Sstevel@tonic-gate &rettree[i]))) {
3877c478bd9Sstevel@tonic-gate while (i) {
3887c478bd9Sstevel@tonic-gate krb5_free_principal(context, rettree[i-1]);
3897c478bd9Sstevel@tonic-gate i--;
3907c478bd9Sstevel@tonic-gate }
3917c478bd9Sstevel@tonic-gate krb5_xfree(rettree);
3927c478bd9Sstevel@tonic-gate return retval;
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate prevscp = scp + 1;
3957c478bd9Sstevel@tonic-gate i++;
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate if (slen && com_sdot >= server->data) {
3987c478bd9Sstevel@tonic-gate /* only necessary if building down tree from ancestor or client */
3997c478bd9Sstevel@tonic-gate /* however, we can get here if we have only one component
4007c478bd9Sstevel@tonic-gate in the server realm name, hence we make sure we found a component
4017c478bd9Sstevel@tonic-gate separator there... */
4027c478bd9Sstevel@tonic-gate tmpcrealm.data = prevscp;
4037c478bd9Sstevel@tonic-gate tmpcrealm.length = server->length -
4047c478bd9Sstevel@tonic-gate (prevscp - server->data);
4057c478bd9Sstevel@tonic-gate if ((retval = krb5_tgtname(context, server, &tmpcrealm,
4067c478bd9Sstevel@tonic-gate &rettree[i]))) {
4077c478bd9Sstevel@tonic-gate while (i) {
4087c478bd9Sstevel@tonic-gate krb5_free_principal(context, rettree[i-1]);
4097c478bd9Sstevel@tonic-gate i--;
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate krb5_xfree(rettree);
4127c478bd9Sstevel@tonic-gate return retval;
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate #ifdef CONFIGURABLE_AUTHENTICATION_PATH
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate #endif
4187c478bd9Sstevel@tonic-gate *tree = rettree;
419fe598cdcSmp153739
420fe598cdcSmp153739 #ifdef DEBUG_REFERRALS
421fe598cdcSmp153739 printf("krb5_walk_realm_tree ending; tree (length %d) is:\n",links);
422fe598cdcSmp153739 for(i=0;i<links+2;i++) {
423fe598cdcSmp153739 if ((*tree)[i])
424fe598cdcSmp153739 krb5int_dbgref_dump_principal("krb5_walk_realm_tree tree",(*tree)[i]);
425fe598cdcSmp153739 else
426fe598cdcSmp153739 printf("tree element %i null\n");
427fe598cdcSmp153739 }
428fe598cdcSmp153739 #endif
4297c478bd9Sstevel@tonic-gate return 0;
4307c478bd9Sstevel@tonic-gate }
431fe598cdcSmp153739
432fe598cdcSmp153739 #ifdef DEBUG_REFERRALS
krb5int_dbgref_dump_principal(char * d,krb5_principal p)433fe598cdcSmp153739 void krb5int_dbgref_dump_principal(char *d, krb5_principal p)
434fe598cdcSmp153739 {
435fe598cdcSmp153739 int n;
436fe598cdcSmp153739
437fe598cdcSmp153739 printf(" **%s: ",d);
438fe598cdcSmp153739 for (n=0;n<p->length;n++)
439fe598cdcSmp153739 printf("%s<%.*s>",(n>0)?"/":"",p->data[n].length,p->data[n].data);
440fe598cdcSmp153739 printf("@<%.*s> (length %d, type %d)\n",p->realm.length,p->realm.data,
441fe598cdcSmp153739 p->length, p->type);
442fe598cdcSmp153739 }
443fe598cdcSmp153739 #endif
444