1*d3273b5bSchristos /* $NetBSD: common.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */
2ca1c9b0cSelric
3ca1c9b0cSelric /*
4ca1c9b0cSelric * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
5ca1c9b0cSelric * (Royal Institute of Technology, Stockholm, Sweden).
6ca1c9b0cSelric * All rights reserved.
7ca1c9b0cSelric *
8ca1c9b0cSelric * Redistribution and use in source and binary forms, with or without
9ca1c9b0cSelric * modification, are permitted provided that the following conditions
10ca1c9b0cSelric * are met:
11ca1c9b0cSelric *
12ca1c9b0cSelric * 1. Redistributions of source code must retain the above copyright
13ca1c9b0cSelric * notice, this list of conditions and the following disclaimer.
14ca1c9b0cSelric *
15ca1c9b0cSelric * 2. Redistributions in binary form must reproduce the above copyright
16ca1c9b0cSelric * notice, this list of conditions and the following disclaimer in the
17ca1c9b0cSelric * documentation and/or other materials provided with the distribution.
18ca1c9b0cSelric *
19ca1c9b0cSelric * 3. Neither the name of the Institute nor the names of its contributors
20ca1c9b0cSelric * may be used to endorse or promote products derived from this software
21ca1c9b0cSelric * without specific prior written permission.
22ca1c9b0cSelric *
23ca1c9b0cSelric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ca1c9b0cSelric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ca1c9b0cSelric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ca1c9b0cSelric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ca1c9b0cSelric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ca1c9b0cSelric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ca1c9b0cSelric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ca1c9b0cSelric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ca1c9b0cSelric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ca1c9b0cSelric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ca1c9b0cSelric * SUCH DAMAGE.
34ca1c9b0cSelric */
35ca1c9b0cSelric
36ca1c9b0cSelric #include "kafs_locl.h"
37ca1c9b0cSelric
38ca1c9b0cSelric #define AUTH_SUPERUSER "afs"
39ca1c9b0cSelric
40ca1c9b0cSelric /*
41ca1c9b0cSelric * Here only ASCII characters are relevant.
42ca1c9b0cSelric */
43ca1c9b0cSelric
44ca1c9b0cSelric #define IsAsciiLower(c) ('a' <= (c) && (c) <= 'z')
45ca1c9b0cSelric
46ca1c9b0cSelric #define ToAsciiUpper(c) ((c) - 'a' + 'A')
47ca1c9b0cSelric
48ca1c9b0cSelric static void (*kafs_verbose)(void *, const char *);
49ca1c9b0cSelric static void *kafs_verbose_ctx;
50ca1c9b0cSelric
51ca1c9b0cSelric void
_kafs_foldup(char * a,const char * b)52ca1c9b0cSelric _kafs_foldup(char *a, const char *b)
53ca1c9b0cSelric {
54ca1c9b0cSelric for (; *b; a++, b++)
55ca1c9b0cSelric if (IsAsciiLower(*b))
56ca1c9b0cSelric *a = ToAsciiUpper(*b);
57ca1c9b0cSelric else
58ca1c9b0cSelric *a = *b;
59ca1c9b0cSelric *a = '\0';
60ca1c9b0cSelric }
61ca1c9b0cSelric
62ca1c9b0cSelric void
kafs_set_verbose(void (* f)(void *,const char *),void * ctx)63ca1c9b0cSelric kafs_set_verbose(void (*f)(void *, const char *), void *ctx)
64ca1c9b0cSelric {
65ca1c9b0cSelric if (f) {
66ca1c9b0cSelric kafs_verbose = f;
67ca1c9b0cSelric kafs_verbose_ctx = ctx;
68ca1c9b0cSelric }
69ca1c9b0cSelric }
70ca1c9b0cSelric
71ca1c9b0cSelric int
kafs_settoken_rxkad(const char * cell,struct ClearToken * ct,void * ticket,size_t ticket_len)72ca1c9b0cSelric kafs_settoken_rxkad(const char *cell, struct ClearToken *ct,
73ca1c9b0cSelric void *ticket, size_t ticket_len)
74ca1c9b0cSelric {
75ca1c9b0cSelric struct ViceIoctl parms;
76ca1c9b0cSelric char buf[2048], *t;
77ca1c9b0cSelric int32_t sizeof_x;
78ca1c9b0cSelric
79ca1c9b0cSelric t = buf;
80ca1c9b0cSelric /*
81ca1c9b0cSelric * length of secret token followed by secret token
82ca1c9b0cSelric */
83ca1c9b0cSelric sizeof_x = ticket_len;
84ca1c9b0cSelric memcpy(t, &sizeof_x, sizeof(sizeof_x));
85ca1c9b0cSelric t += sizeof(sizeof_x);
86ca1c9b0cSelric memcpy(t, ticket, sizeof_x);
87ca1c9b0cSelric t += sizeof_x;
88ca1c9b0cSelric /*
89ca1c9b0cSelric * length of clear token followed by clear token
90ca1c9b0cSelric */
91ca1c9b0cSelric sizeof_x = sizeof(*ct);
92ca1c9b0cSelric memcpy(t, &sizeof_x, sizeof(sizeof_x));
93ca1c9b0cSelric t += sizeof(sizeof_x);
94ca1c9b0cSelric memcpy(t, ct, sizeof_x);
95ca1c9b0cSelric t += sizeof_x;
96ca1c9b0cSelric
97ca1c9b0cSelric /*
98ca1c9b0cSelric * do *not* mark as primary cell
99ca1c9b0cSelric */
100ca1c9b0cSelric sizeof_x = 0;
101ca1c9b0cSelric memcpy(t, &sizeof_x, sizeof(sizeof_x));
102ca1c9b0cSelric t += sizeof(sizeof_x);
103ca1c9b0cSelric /*
104ca1c9b0cSelric * follow with cell name
105ca1c9b0cSelric */
106ca1c9b0cSelric sizeof_x = strlen(cell) + 1;
107ca1c9b0cSelric memcpy(t, cell, sizeof_x);
108ca1c9b0cSelric t += sizeof_x;
109ca1c9b0cSelric
110ca1c9b0cSelric /*
111ca1c9b0cSelric * Build argument block
112ca1c9b0cSelric */
113ca1c9b0cSelric parms.in = buf;
114ca1c9b0cSelric parms.in_size = t - buf;
115ca1c9b0cSelric parms.out = 0;
116ca1c9b0cSelric parms.out_size = 0;
117ca1c9b0cSelric
118ca1c9b0cSelric return k_pioctl(0, VIOCSETTOK, &parms, 0);
119ca1c9b0cSelric }
120ca1c9b0cSelric
121ca1c9b0cSelric void
_kafs_fixup_viceid(struct ClearToken * ct,uid_t uid)122ca1c9b0cSelric _kafs_fixup_viceid(struct ClearToken *ct, uid_t uid)
123ca1c9b0cSelric {
124ca1c9b0cSelric #define ODD(x) ((x) & 1)
125ca1c9b0cSelric /* According to Transarc conventions ViceId is valid iff
126ca1c9b0cSelric * (EndTimestamp - BeginTimestamp) is odd. By decrementing EndTime
127ca1c9b0cSelric * the transformations:
128ca1c9b0cSelric *
129ca1c9b0cSelric * (issue_date, life) -> (StartTime, EndTime) -> (issue_date, life)
130ca1c9b0cSelric * preserves the original values.
131ca1c9b0cSelric */
132ca1c9b0cSelric if (uid != 0) /* valid ViceId */
133ca1c9b0cSelric {
134ca1c9b0cSelric if (!ODD(ct->EndTimestamp - ct->BeginTimestamp))
135ca1c9b0cSelric ct->EndTimestamp--;
136ca1c9b0cSelric }
137ca1c9b0cSelric else /* not valid ViceId */
138ca1c9b0cSelric {
139ca1c9b0cSelric if (ODD(ct->EndTimestamp - ct->BeginTimestamp))
140ca1c9b0cSelric ct->EndTimestamp--;
141ca1c9b0cSelric }
142ca1c9b0cSelric }
143ca1c9b0cSelric
144ca1c9b0cSelric /* Try to get a db-server for an AFS cell from a AFSDB record */
145ca1c9b0cSelric
146ca1c9b0cSelric static int
dns_find_cell(const char * cell,char * dbserver,size_t len)147ca1c9b0cSelric dns_find_cell(const char *cell, char *dbserver, size_t len)
148ca1c9b0cSelric {
149ca1c9b0cSelric struct rk_dns_reply *r;
150ca1c9b0cSelric int ok = -1;
151ca1c9b0cSelric r = rk_dns_lookup(cell, "afsdb");
152ca1c9b0cSelric if(r){
153ca1c9b0cSelric struct rk_resource_record *rr = r->head;
154ca1c9b0cSelric while(rr){
155ca1c9b0cSelric if(rr->type == rk_ns_t_afsdb && rr->u.afsdb->preference == 1){
156ca1c9b0cSelric strlcpy(dbserver,
157ca1c9b0cSelric rr->u.afsdb->domain,
158ca1c9b0cSelric len);
159ca1c9b0cSelric ok = 0;
160ca1c9b0cSelric break;
161ca1c9b0cSelric }
162ca1c9b0cSelric rr = rr->next;
163ca1c9b0cSelric }
164ca1c9b0cSelric rk_dns_free_data(r);
165ca1c9b0cSelric }
166ca1c9b0cSelric return ok;
167ca1c9b0cSelric }
168ca1c9b0cSelric
169ca1c9b0cSelric
170ca1c9b0cSelric /*
171ca1c9b0cSelric * Try to find the cells we should try to klog to in "file".
172ca1c9b0cSelric */
173ca1c9b0cSelric static void
find_cells(const char * file,char *** cells,int * idx)174ca1c9b0cSelric find_cells(const char *file, char ***cells, int *idx)
175ca1c9b0cSelric {
176ca1c9b0cSelric FILE *f;
177ca1c9b0cSelric char cell[64];
178ca1c9b0cSelric int i;
179ca1c9b0cSelric int ind = *idx;
180ca1c9b0cSelric
181ca1c9b0cSelric f = fopen(file, "r");
182ca1c9b0cSelric if (f == NULL)
183ca1c9b0cSelric return;
184ca1c9b0cSelric while (fgets(cell, sizeof(cell), f)) {
185ca1c9b0cSelric char *t;
186ca1c9b0cSelric t = cell + strlen(cell);
187ca1c9b0cSelric for (; t >= cell; t--)
188ca1c9b0cSelric if (*t == '\n' || *t == '\t' || *t == ' ')
189ca1c9b0cSelric *t = 0;
190ca1c9b0cSelric if (cell[0] == '\0' || cell[0] == '#')
191ca1c9b0cSelric continue;
192ca1c9b0cSelric for(i = 0; i < ind; i++)
193ca1c9b0cSelric if(strcmp((*cells)[i], cell) == 0)
194ca1c9b0cSelric break;
195ca1c9b0cSelric if(i == ind){
196ca1c9b0cSelric char **tmp;
197ca1c9b0cSelric
198ca1c9b0cSelric tmp = realloc(*cells, (ind + 1) * sizeof(**cells));
199ca1c9b0cSelric if (tmp == NULL)
200ca1c9b0cSelric break;
201ca1c9b0cSelric *cells = tmp;
202ca1c9b0cSelric (*cells)[ind] = strdup(cell);
203ca1c9b0cSelric if ((*cells)[ind] == NULL)
204ca1c9b0cSelric break;
205ca1c9b0cSelric ++ind;
206ca1c9b0cSelric }
207ca1c9b0cSelric }
208ca1c9b0cSelric fclose(f);
209ca1c9b0cSelric *idx = ind;
210ca1c9b0cSelric }
211ca1c9b0cSelric
212ca1c9b0cSelric /*
213ca1c9b0cSelric * Get tokens for all cells[]
214ca1c9b0cSelric */
215ca1c9b0cSelric static int
afslog_cells(struct kafs_data * data,char ** cells,int max,uid_t uid,const char * homedir)216ca1c9b0cSelric afslog_cells(struct kafs_data *data, char **cells, int max, uid_t uid,
217ca1c9b0cSelric const char *homedir)
218ca1c9b0cSelric {
219ca1c9b0cSelric int ret = 0;
220ca1c9b0cSelric int i;
221ca1c9b0cSelric for (i = 0; i < max; i++) {
222ca1c9b0cSelric int er = (*data->afslog_uid)(data, cells[i], 0, uid, homedir);
223ca1c9b0cSelric if (er)
224ca1c9b0cSelric ret = er;
225ca1c9b0cSelric }
226ca1c9b0cSelric return ret;
227ca1c9b0cSelric }
228ca1c9b0cSelric
229ca1c9b0cSelric int
_kafs_afslog_all_local_cells(struct kafs_data * data,uid_t uid,const char * homedir)230ca1c9b0cSelric _kafs_afslog_all_local_cells(struct kafs_data *data,
231ca1c9b0cSelric uid_t uid, const char *homedir)
232ca1c9b0cSelric {
233ca1c9b0cSelric int ret;
234ca1c9b0cSelric char **cells = NULL;
235ca1c9b0cSelric int idx = 0;
236ca1c9b0cSelric
237ca1c9b0cSelric if (homedir == NULL)
238ca1c9b0cSelric homedir = getenv("HOME");
239ca1c9b0cSelric if (homedir != NULL) {
240ca1c9b0cSelric char home[MaxPathLen];
241ca1c9b0cSelric snprintf(home, sizeof(home), "%s/.TheseCells", homedir);
242ca1c9b0cSelric find_cells(home, &cells, &idx);
243ca1c9b0cSelric }
244ca1c9b0cSelric find_cells(_PATH_THESECELLS, &cells, &idx);
245ca1c9b0cSelric find_cells(_PATH_THISCELL, &cells, &idx);
246ca1c9b0cSelric find_cells(_PATH_ARLA_THESECELLS, &cells, &idx);
247ca1c9b0cSelric find_cells(_PATH_ARLA_THISCELL, &cells, &idx);
248ca1c9b0cSelric find_cells(_PATH_OPENAFS_DEBIAN_THESECELLS, &cells, &idx);
249ca1c9b0cSelric find_cells(_PATH_OPENAFS_DEBIAN_THISCELL, &cells, &idx);
250ca1c9b0cSelric find_cells(_PATH_OPENAFS_MACOSX_THESECELLS, &cells, &idx);
251ca1c9b0cSelric find_cells(_PATH_OPENAFS_MACOSX_THISCELL, &cells, &idx);
252ca1c9b0cSelric find_cells(_PATH_ARLA_DEBIAN_THESECELLS, &cells, &idx);
253ca1c9b0cSelric find_cells(_PATH_ARLA_DEBIAN_THISCELL, &cells, &idx);
254ca1c9b0cSelric find_cells(_PATH_ARLA_OPENBSD_THESECELLS, &cells, &idx);
255ca1c9b0cSelric find_cells(_PATH_ARLA_OPENBSD_THISCELL, &cells, &idx);
256ca1c9b0cSelric
257ca1c9b0cSelric ret = afslog_cells(data, cells, idx, uid, homedir);
258ca1c9b0cSelric while(idx > 0)
259ca1c9b0cSelric free(cells[--idx]);
260ca1c9b0cSelric free(cells);
261ca1c9b0cSelric return ret;
262ca1c9b0cSelric }
263ca1c9b0cSelric
264ca1c9b0cSelric
265ca1c9b0cSelric static int
file_find_cell(struct kafs_data * data,const char * cell,char ** realm,int exact)266ca1c9b0cSelric file_find_cell(struct kafs_data *data,
267ca1c9b0cSelric const char *cell, char **realm, int exact)
268ca1c9b0cSelric {
269ca1c9b0cSelric FILE *F;
270ca1c9b0cSelric char buf[1024];
271ca1c9b0cSelric char *p;
272ca1c9b0cSelric int ret = -1;
273ca1c9b0cSelric
274ca1c9b0cSelric if ((F = fopen(_PATH_CELLSERVDB, "r"))
275ca1c9b0cSelric || (F = fopen(_PATH_ARLA_CELLSERVDB, "r"))
276ca1c9b0cSelric || (F = fopen(_PATH_OPENAFS_DEBIAN_CELLSERVDB, "r"))
277ca1c9b0cSelric || (F = fopen(_PATH_OPENAFS_MACOSX_CELLSERVDB, "r"))
278ca1c9b0cSelric || (F = fopen(_PATH_ARLA_DEBIAN_CELLSERVDB, "r"))) {
279ca1c9b0cSelric while (fgets(buf, sizeof(buf), F)) {
280ca1c9b0cSelric int cmp;
281ca1c9b0cSelric
282ca1c9b0cSelric if (buf[0] != '>')
283ca1c9b0cSelric continue; /* Not a cell name line, try next line */
284ca1c9b0cSelric p = buf;
285ca1c9b0cSelric strsep(&p, " \t\n#");
286ca1c9b0cSelric
287ca1c9b0cSelric if (exact)
288ca1c9b0cSelric cmp = strcmp(buf + 1, cell);
289ca1c9b0cSelric else
290ca1c9b0cSelric cmp = strncmp(buf + 1, cell, strlen(cell));
291ca1c9b0cSelric
292ca1c9b0cSelric if (cmp == 0) {
293ca1c9b0cSelric /*
294ca1c9b0cSelric * We found the cell name we're looking for.
295ca1c9b0cSelric * Read next line on the form ip-address '#' hostname
296ca1c9b0cSelric */
297ca1c9b0cSelric if (fgets(buf, sizeof(buf), F) == NULL)
298ca1c9b0cSelric break; /* Read failed, give up */
299ca1c9b0cSelric p = strchr(buf, '#');
300ca1c9b0cSelric if (p == NULL)
301ca1c9b0cSelric break; /* No '#', give up */
302ca1c9b0cSelric p++;
303ca1c9b0cSelric if (buf[strlen(buf) - 1] == '\n')
304ca1c9b0cSelric buf[strlen(buf) - 1] = '\0';
305ca1c9b0cSelric *realm = (*data->get_realm)(data, p);
306ca1c9b0cSelric if (*realm && **realm != '\0')
307ca1c9b0cSelric ret = 0;
308ca1c9b0cSelric break; /* Won't try any more */
309ca1c9b0cSelric }
310ca1c9b0cSelric }
311ca1c9b0cSelric fclose(F);
312ca1c9b0cSelric }
313ca1c9b0cSelric return ret;
314ca1c9b0cSelric }
315ca1c9b0cSelric
316ca1c9b0cSelric /* Find the realm associated with cell. Do this by opening CellServDB
317ca1c9b0cSelric file and getting the realm-of-host for the first VL-server for the
318ca1c9b0cSelric cell.
319ca1c9b0cSelric
320ca1c9b0cSelric This does not work when the VL-server is living in one realm, but
321ca1c9b0cSelric the cell it is serving is living in another realm.
322ca1c9b0cSelric
323ca1c9b0cSelric Return 0 on success, -1 otherwise.
324ca1c9b0cSelric */
325ca1c9b0cSelric
326ca1c9b0cSelric int
_kafs_realm_of_cell(struct kafs_data * data,const char * cell,char ** realm)327ca1c9b0cSelric _kafs_realm_of_cell(struct kafs_data *data,
328ca1c9b0cSelric const char *cell, char **realm)
329ca1c9b0cSelric {
330ca1c9b0cSelric char buf[1024];
331ca1c9b0cSelric int ret;
332ca1c9b0cSelric
333ca1c9b0cSelric ret = file_find_cell(data, cell, realm, 1);
334ca1c9b0cSelric if (ret == 0)
335ca1c9b0cSelric return ret;
336ca1c9b0cSelric if (dns_find_cell(cell, buf, sizeof(buf)) == 0) {
337ca1c9b0cSelric *realm = (*data->get_realm)(data, buf);
338ca1c9b0cSelric if(*realm != NULL)
339ca1c9b0cSelric return 0;
340ca1c9b0cSelric }
341ca1c9b0cSelric return file_find_cell(data, cell, realm, 0);
342ca1c9b0cSelric }
343ca1c9b0cSelric
344ca1c9b0cSelric static int
_kafs_try_get_cred(struct kafs_data * data,const char * user,const char * cell,const char * realm,uid_t uid,struct kafs_token * kt)345ca1c9b0cSelric _kafs_try_get_cred(struct kafs_data *data, const char *user, const char *cell,
346ca1c9b0cSelric const char *realm, uid_t uid, struct kafs_token *kt)
347ca1c9b0cSelric {
348ca1c9b0cSelric int ret;
349ca1c9b0cSelric
350ca1c9b0cSelric ret = (*data->get_cred)(data, user, cell, realm, uid, kt);
351ca1c9b0cSelric if (kafs_verbose) {
352ca1c9b0cSelric const char *estr = (*data->get_error)(data, ret);
353ca1c9b0cSelric char *str;
354b9d004c6Schristos int aret;
355b9d004c6Schristos
356b9d004c6Schristos aret = asprintf(&str, "%s tried afs%s%s@%s -> %s (%d)",
357ca1c9b0cSelric data->name, cell ? "/" : "",
358ca1c9b0cSelric cell ? cell : "", realm, estr ? estr : "unknown", ret);
359b9d004c6Schristos if (aret != -1) {
360ca1c9b0cSelric (*kafs_verbose)(kafs_verbose_ctx, str);
361b9d004c6Schristos free(str);
362b9d004c6Schristos } else {
363b9d004c6Schristos (*kafs_verbose)(kafs_verbose_ctx, "out of memory");
364b9d004c6Schristos }
365ca1c9b0cSelric if (estr)
366ca1c9b0cSelric (*data->free_error)(data, estr);
367ca1c9b0cSelric }
368ca1c9b0cSelric
369ca1c9b0cSelric return ret;
370ca1c9b0cSelric }
371ca1c9b0cSelric
372ca1c9b0cSelric
373ca1c9b0cSelric int
_kafs_get_cred(struct kafs_data * data,const char * cell,const char * realm_hint,const char * realm,uid_t uid,struct kafs_token * kt)374ca1c9b0cSelric _kafs_get_cred(struct kafs_data *data,
375ca1c9b0cSelric const char *cell,
376ca1c9b0cSelric const char *realm_hint,
377ca1c9b0cSelric const char *realm,
378ca1c9b0cSelric uid_t uid,
379ca1c9b0cSelric struct kafs_token *kt)
380ca1c9b0cSelric {
381ca1c9b0cSelric int ret = -1;
382ca1c9b0cSelric char *vl_realm;
383ca1c9b0cSelric char CELL[64];
384ca1c9b0cSelric
385ca1c9b0cSelric /* We're about to find the realm that holds the key for afs in
386ca1c9b0cSelric * the specified cell. The problem is that null-instance
387ca1c9b0cSelric * afs-principals are common and that hitting the wrong realm might
388ca1c9b0cSelric * yield the wrong afs key. The following assumptions were made.
389ca1c9b0cSelric *
390ca1c9b0cSelric * Any realm passed to us is preferred.
391ca1c9b0cSelric *
392ca1c9b0cSelric * If there is a realm with the same name as the cell, it is most
393ca1c9b0cSelric * likely the correct realm to talk to.
394ca1c9b0cSelric *
395ca1c9b0cSelric * In most (maybe even all) cases the database servers of the cell
396ca1c9b0cSelric * will live in the realm we are looking for.
397ca1c9b0cSelric *
398ca1c9b0cSelric * Try the local realm, but if the previous cases fail, this is
399ca1c9b0cSelric * really a long shot.
400ca1c9b0cSelric *
401ca1c9b0cSelric */
402ca1c9b0cSelric
403ca1c9b0cSelric /* comments on the ordering of these tests */
404ca1c9b0cSelric
405ca1c9b0cSelric /* If the user passes a realm, she probably knows something we don't
406ca1c9b0cSelric * know and we should try afs@realm_hint.
407ca1c9b0cSelric */
408ca1c9b0cSelric
409ca1c9b0cSelric if (realm_hint) {
410ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
411ca1c9b0cSelric cell, realm_hint, uid, kt);
412ca1c9b0cSelric if (ret == 0) return 0;
413ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
414ca1c9b0cSelric NULL, realm_hint, uid, kt);
415ca1c9b0cSelric if (ret == 0) return 0;
416ca1c9b0cSelric }
417ca1c9b0cSelric
418ca1c9b0cSelric _kafs_foldup(CELL, cell);
419ca1c9b0cSelric
420ca1c9b0cSelric /*
421ca1c9b0cSelric * If the AFS servers have a file /usr/afs/etc/krb.conf containing
422ca1c9b0cSelric * REALM we still don't have to resort to cross-cell authentication.
423ca1c9b0cSelric * Try afs.cell@REALM.
424ca1c9b0cSelric */
425ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
426ca1c9b0cSelric cell, realm, uid, kt);
427ca1c9b0cSelric if (ret == 0) return 0;
428ca1c9b0cSelric
429ca1c9b0cSelric /*
430ca1c9b0cSelric * If cell == realm we don't need no cross-cell authentication.
431ca1c9b0cSelric * Try afs@REALM.
432ca1c9b0cSelric */
433ca1c9b0cSelric if (strcmp(CELL, realm) == 0) {
434ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
435ca1c9b0cSelric NULL, realm, uid, kt);
436ca1c9b0cSelric if (ret == 0) return 0;
437ca1c9b0cSelric }
438ca1c9b0cSelric
439ca1c9b0cSelric /*
440ca1c9b0cSelric * We failed to get ``first class tickets'' for afs,
441ca1c9b0cSelric * fall back to cross-cell authentication.
442ca1c9b0cSelric * Try afs@CELL.
443ca1c9b0cSelric * Try afs.cell@CELL.
444ca1c9b0cSelric */
445ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
446ca1c9b0cSelric NULL, CELL, uid, kt);
447ca1c9b0cSelric if (ret == 0) return 0;
448ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
449ca1c9b0cSelric cell, CELL, uid, kt);
450ca1c9b0cSelric if (ret == 0) return 0;
451ca1c9b0cSelric
452ca1c9b0cSelric /*
453ca1c9b0cSelric * Perhaps the cell doesn't correspond to any realm?
454ca1c9b0cSelric * Use realm of first volume location DB server.
455ca1c9b0cSelric * Try afs.cell@VL_REALM.
456ca1c9b0cSelric * Try afs@VL_REALM???
457ca1c9b0cSelric */
458ca1c9b0cSelric if (_kafs_realm_of_cell(data, cell, &vl_realm) == 0
459ca1c9b0cSelric && strcmp(vl_realm, realm) != 0
460ca1c9b0cSelric && strcmp(vl_realm, CELL) != 0) {
461ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
462ca1c9b0cSelric cell, vl_realm, uid, kt);
463ca1c9b0cSelric if (ret)
464ca1c9b0cSelric ret = _kafs_try_get_cred(data, AUTH_SUPERUSER,
465ca1c9b0cSelric NULL, vl_realm, uid, kt);
466ca1c9b0cSelric free(vl_realm);
467ca1c9b0cSelric if (ret == 0) return 0;
468ca1c9b0cSelric }
469ca1c9b0cSelric
470ca1c9b0cSelric return ret;
471ca1c9b0cSelric }
472