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