2 * lib/krb5/krb/walk_rtree.c
4 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 * krb5_walk_realm_tree()
28 #include "int-proto.h"
30 /* internal function, used by krb5_get_cred_from_kdc() */
33 #define min(x,y) ((x) < (y) ? (x) : (y))
34 #define max(x,y) ((x) > (y) ? (x) : (y))
38 krb5_walk_realm_tree(context, client, server, tree, realm_branch_char)
40 const krb5_data *client, *server;
41 krb5_principal **tree;
42 int realm_branch_char;
44 krb5_error_code retval;
45 krb5_principal *rettree;
46 register char *ccp, *scp;
47 register char *prevccp = 0, *prevscp = 0;
48 char *com_sdot = 0, *com_cdot = 0;
49 register int i, links = 0;
51 krb5_data tmpcrealm, tmpsrealm;
54 clen = client->length;
55 slen = server->length;
57 for (com_cdot = ccp = client->data + clen - 1,
58 com_sdot = scp = server->data + slen - 1;
59 clen && slen && *ccp == *scp ;
60 ccp--, scp--, clen--, slen--) {
61 if (*ccp == realm_branch_char) {
68 /* ccp, scp point to common root.
69 com_cdot, com_sdot point to common components. */
70 /* handle case of one ran out */
72 /* construct path from client to server, down the tree */
74 /* in the same realm--this means there is no ticket
76 return KRB5_NO_TKT_IN_RLM;
77 if (*scp == realm_branch_char) {
78 /* one is a subdomain of the other */
79 com_cdot = client->data;
82 } /* else normal case of two sharing parents */
85 /* construct path from client to server, up the tree */
86 if (*ccp == realm_branch_char) {
87 /* one is a subdomain of the other */
88 com_sdot = server->data;
91 } /* else normal case of two sharing parents */
93 /* determine #links to/from common ancestor */
98 /* if no common ancestor, artificially set up common root at the last
99 component, then join with special code */
100 for (ccp = client->data; ccp < com_cdot; ccp++) {
101 if (*ccp == realm_branch_char) {
108 for (scp = server->data; scp < com_sdot; scp++) {
109 if (*scp == realm_branch_char) {
121 if(com_cdot == client->data + client->length -1)
122 com_cdot = client->data - 1 ;
123 if(com_sdot == server->data + server->length -1)
124 com_sdot = server->data - 1 ;
127 if (!(rettree = (krb5_principal *)calloc(links+2,
128 sizeof(krb5_principal)))) {
132 if (retval = krb5_tgtname(context, client,
133 client, &rettree[0])) {
137 for (prevccp = ccp = client->data;
140 if (*ccp != realm_branch_char)
142 ++ccp; /* advance past dot */
143 tmpcrealm.data = prevccp;
144 tmpcrealm.length = client->length -
145 (prevccp - client->data);
146 tmpsrealm.data = ccp;
147 tmpsrealm.length = client->length -
148 (ccp - client->data);
149 if (retval = krb5_tgtname(context, &tmpsrealm, &tmpcrealm, &rettree[i])) {
151 krb5_free_principal(context, rettree[i-1]);
161 tmpcrealm.data = com_cdot + 1;
162 tmpcrealm.length = client->length -
163 (com_cdot + 1 - client->data);
164 tmpsrealm.data = com_sdot + 1;
165 tmpsrealm.length = server->length -
166 (com_sdot + 1 - server->data);
167 if (retval = krb5_tgtname(context, &tmpsrealm, &tmpcrealm, &rettree[i])) {
169 krb5_free_principal(context, rettree[i-1]);
178 for (prevscp = com_sdot + 1, scp = com_sdot - 1;
181 if (*scp != realm_branch_char)
183 if (scp - 1 < server->data)
184 break; /* XXX only if . starts realm? */
185 tmpcrealm.data = prevscp;
186 tmpcrealm.length = server->length -
187 (prevscp - server->data);
188 tmpsrealm.data = scp + 1;
189 tmpsrealm.length = server->length -
190 (scp + 1 - server->data);
191 if (retval = krb5_tgtname(context, &tmpsrealm, &tmpcrealm, &rettree[i])) {
193 krb5_free_principal(context, rettree[i-1]);
202 if (slen && com_sdot >= server->data) {
203 /* only necessary if building down tree from ancestor or client */
204 /* however, we can get here if we have only one component
205 in the server realm name, hence we make sure we found a component
206 separator there... */
207 tmpcrealm.data = prevscp;
208 tmpcrealm.length = server->length -
209 (prevscp - server->data);
210 if (retval = krb5_tgtname(context, server, &tmpcrealm,
213 krb5_free_principal(context, rettree[i-1]);