source: trunk/athena/bin/attach/afs.c @ 5982

Revision 5982, 8.2 KB checked in by probe, 32 years ago (diff)
Don't consider aklog problems fatal unless we are authenticating.
Line 
1/*
2 * $Id: afs.c,v 1.8 1992-04-21 08:20:42 probe Exp $
3 *
4 * Copyright (c) 1990,1992 by the Massachusetts Institute of Technology.
5 */
6
7static char *rcsid = "$Id: afs.c,v 1.8 1992-04-21 08:20:42 probe Exp $";
8
9#include "attach.h"
10
11#ifdef AFS
12
13#include <sys/stat.h>
14#include <sys/wait.h>
15#include <sys/file.h>
16#include <sys/errno.h>
17
18#include <krb.h>
19
20extern char *krb_realmofhost(); /* <krb.h> doesn't declare this */
21
22/* Flags to afs_auth_internal() */
23#define AFSAUTH_DOAUTH          1
24#define AFSAUTH_CELL            2
25#define AFSAUTH_DOZEPHYR        4
26
27#ifdef __STDC__
28static int afs_auth_internal(char * errorname, char * afs_pathname,
29                             struct in_addr hostaddr[], int flags);
30#else
31static int afs_auth_internal();
32#endif
33
34
35/*
36 * The current implementation of AFS attaches is to make a symbolic
37 * link.  This is NOT GUARANTEED to always be the case.
38 */
39
40afs_attach(at, mopt, errorout)
41        struct _attachtab *at;
42        struct mntopts  *mopt;
43        int errorout;
44{
45        struct  stat    statbuf;
46        char    buf[BUFSIZ];
47        int     len;
48        int     afs_auth_flags = 0;
49
50        if ((at->mode != 'n') && do_nfsid)
51                afs_auth_flags |= AFSAUTH_DOAUTH;
52
53        if (use_zephyr)
54                afs_auth_flags |= AFSAUTH_DOZEPHYR;
55       
56        if (afs_auth_internal(at->hesiodname, at->hostdir,
57                              at->hostaddr, afs_auth_flags) == FAILURE)
58                return(FAILURE);
59       
60        if (debug_flag)
61                printf("lstating %s...\n", at->hostdir);
62        setreuid(effective_uid, owner_uid);
63        if (stat(at->hostdir, &statbuf)) {
64                if (errno == ENOENT)
65                        fprintf(stderr, "%s: %s does not exist\n",
66                                at->hesiodname, at->hostdir);
67                else
68                        perror(at->hostdir);
69                error_status = ERR_ATTACHNOFILSYS;
70                setreuid(real_uid, effective_uid);
71                return(FAILURE);
72        }
73        if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
74                fprintf(stderr, "%s: %s is not a directory\n",
75                        at->hesiodname, at->hostdir);
76                setreuid(real_uid, effective_uid);
77                error_status = ERR_ATTACHNOFILSYS;
78                return(FAILURE);
79        }
80       
81        if (debug_flag)
82                printf("lstating %s....\n", at->mntpt);
83        if (!lstat(at->mntpt, &statbuf)) {
84                setreuid(real_uid, effective_uid);
85                if ((statbuf.st_mode & S_IFMT) == S_IFLNK) {
86                        len = readlink(at->mntpt, buf, sizeof(buf));
87                        buf[len] = '\0';
88                        (void) strcpy(buf, path_canon(buf));
89                        if (!strcmp(buf, path_canon(at->hostdir))) {
90                                if (!print_path && verbose)
91                                    fprintf(stderr,
92                                            "%s: %s already sym linked%s\n",
93                                            at->hesiodname, at->hostdir,
94                                            (afs_auth_flags & AFSAUTH_DOAUTH) ?
95                                            ", authenticating..." : "");
96                                if (keep_mount)
97                                        at->flags |= FLAG_PERMANENT;
98                                return(SUCCESS);
99                        } else {
100                                if (keep_mount) {
101                                        fprintf(stderr,
102        "%s: Couldn't attach; symlink from %s to %s already exists.\n",
103                        at->hesiodname, at->mntpt, buf);
104                                        error_status = ERR_ATTACHINUSE;
105                                        return(FAILURE);
106                                }
107                                if (
108#if defined(_AIX) && (AIXV==12)
109                                    /* AIX 1.x */
110                                    rmslink(at->mntpt) == -1 &&
111#endif
112                                    unlink(at->mntpt) == -1)
113                                {
114                                        fprintf(stderr,
115        "%s: Couldn't remove existing symlink from %s to %s: %s\n",
116                        at->hesiodname, at->mntpt, buf, sys_errlist[errno]);
117                                        error_status = ERR_ATTACHINUSE;
118                                        return(FAILURE);
119                                }
120                        }
121                } else if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
122                        if (rmdir(at->mntpt)) {
123                                if (errno == ENOTEMPTY)
124                                        fprintf(stderr,
125                                "%s: %s is a non-empty directory.\n",
126                                                at->hesiodname, at->mntpt);
127                                else
128                                        fprintf(stderr,
129                                                "%s: Couldn't rmdir %s (%s)\n",
130                                                at->hesiodname, at->mntpt,
131                                                sys_errlist[errno]);
132                                error_status = ERR_ATTACHINUSE;
133                                return(FAILURE);
134                        }
135                } else {
136                        fprintf(stderr,
137                                "%s: Couldn't attach; %s already exists.\n",
138                                at->hesiodname, at->mntpt);
139                        error_status = ERR_ATTACHINUSE;
140                        return(FAILURE);
141                }
142        }
143        setreuid(real_uid, effective_uid);
144        /*
145         * Note: we do our own path canonicalization here, since
146         * we have to check the sym link first.
147         */
148        (void) strcpy(at->mntpt, path_canon(at->mntpt));
149        if (debug_flag)
150                printf("Mountpoint canonicalized as: %s\n", at->mntpt);
151       
152        if (!override && !check_mountpt(at->mntpt, at->fs->type)) {
153                error_status = ERR_ATTACHBADMNTPT;
154                return(FAILURE);
155        }
156       
157        if (debug_flag)
158                printf("symlinking %s to %s\n", at->hostdir, at->mntpt);
159        if (symlink(at->hostdir, at->mntpt) < 0) {
160                fprintf(stderr, "%s: ", at->hesiodname);
161                perror(at->hostdir);
162/*              error_status = ERR_; */
163                return(FAILURE);
164        }
165       
166        return (SUCCESS);
167}
168
169/*
170 * afs_auth_internal --- authenticate oneself to the afs system
171 *
172 * Actually, it also does the zephyr subscriptions, but that's because
173 * aklog does all of that stuff.
174 */
175static int afs_auth_internal(errorname, afs_pathname, hostlist, flags)
176        char    *errorname;
177        char    *afs_pathname;  /* For future expansion */
178        struct in_addr hostlist[];
179        int     flags;
180{
181#ifdef POSIX
182        int     waitb;
183#else
184        union wait      waitb;
185#endif
186        int     error_ret;
187        int     fds[2];
188        FILE    *f;
189        char    buff[512];
190        int     host_idx = 0;
191       
192        if (debug_flag)
193                printf("performing an %s %s %s -hosts -zsubs %s\n", aklog_fn,
194                       flags & AFSAUTH_CELL ? "-cell" : "-path",
195                       afs_pathname, flags & AFSAUTH_DOAUTH ? "" : "-noauth");
196       
197        if (pipe(fds)) {
198                perror("afs_auth: pipe");
199                return(FAILURE);
200        }
201       
202        switch(vfork()) {
203        case -1:
204                close(fds[0]);
205                close(fds[1]);
206                perror("vfork: to aklog");
207                error_status = ERR_AUTHFAIL;
208                return(FAILURE);
209        case 0:
210                if (!debug_flag) {
211                        close(0);
212                        open("/dev/null", O_RDWR, 0644);
213                }
214
215                close(fds[0]);
216                dup2(fds[1], 1);
217                close(fds[1]);
218                setuid(owner_uid);
219                execl(aklog_fn, AKLOG_SHORTNAME,
220                      flags & AFSAUTH_CELL ? "-cell" : "-path",
221                      afs_pathname, "-hosts", "-zsubs",
222                      (flags & AFSAUTH_DOAUTH) ? 0 : "-noauth", 0);
223                perror(aklog_fn);
224                exit(1);
225                /*NOTREACHED*/
226        default:
227                close(fds[1]);
228                if ((f = fdopen(fds[0], "r")) == NULL) {
229                        perror("fdopen: to aklog output");
230                        return(FAILURE);
231                }
232                while (fgets(buff, sizeof(buff), f)) {
233                        char    *cp;
234                        int     len;
235
236                        if (debug_flag)
237                                fputs(buff, stdout);
238                        if (!(cp = index(buff, ':')))
239                                continue;
240                        *cp = '\0';
241#ifdef ZEPHYR
242                        if (!strcmp(buff, "zsub") &&
243                            (flags & AFSAUTH_DOZEPHYR)) {
244                                cp++;
245                                while (*cp && isspace(*cp))
246                                        cp++;
247                                for (len=strlen(cp)-1;
248                                     len>=0 && !isprint(cp[len])
249                                     ; len--)
250                                        cp[len] = '\0';
251                                zephyr_addsub(cp);
252                        }
253#endif
254                        if (hostlist && !strcmp(buff, "host")) {
255                                cp++;
256                                while (*cp && isspace(*cp))
257                                        cp++;
258                                for (len=strlen(cp)-1;
259                                     len>=0 && !isprint(cp[len])
260                                     ; len--)
261                                        cp[len] = '\0';
262                                hostlist[host_idx++].s_addr = inet_addr(cp);
263                        }
264                }
265                fclose(f);
266                if (wait(&waitb) < 0) {
267                        perror("wait: for aklog");
268                        error_status = ERR_AUTHFAIL;
269                        return(FAILURE);
270                }
271        }
272
273#ifdef POSIX
274        error_ret = waitb;
275#else
276        error_ret = waitb.w_retcode;
277#endif
278        if (error_ret && (flags & AFSAUTH_DOAUTH)) {
279                error_status = ERR_AUTHFAIL;
280                return (FAILURE);
281        }
282        return(SUCCESS);
283}
284
285int afs_auth(hesname, afsdir)
286const char *hesname, *afsdir;
287{
288    return(afs_auth_internal(hesname, afsdir, 0, AFSAUTH_DOAUTH));
289}
290
291/*
292 * Parsing of explicit AFS file types
293 */
294char **afs_explicit(name)
295        char *name;
296{
297  char *dir;
298  char newmntpt[BUFSIZ];
299  extern char *exp_hesptr[2];
300
301  if (*name != '/')
302    {
303      fprintf(stderr, "%s: Illegal explicit definition \"%s\" for type %s\n",
304              progname, name, filsys_type);
305      return (0);
306    }
307       
308  dir = rindex(name, '/');
309  (void) strcpy(newmntpt, afs_mount_dir);
310  (void) strcat(newmntpt, dir);
311 
312  sprintf(exp_hesline, "AFS %s %c %s", name, override_mode ?
313          override_mode : 'w', mntpt ? mntpt : newmntpt);
314  exp_hesptr[0] = exp_hesline;
315  exp_hesptr[1] = 0;
316  return exp_hesptr;
317}
318
319int afs_detach(at)
320        struct _attachtab *at;
321{
322    if(at->flags & FLAG_PERMANENT)
323        return SUCCESS;
324     
325    if (
326#if defined(_AIX) && (AIXV==12)
327        /* AIX 1.x */
328        rmslink(at->mntpt) == -1 &&
329#endif
330        unlink(at->mntpt) == -1)
331        {
332            if(errno == ENOENT)
333                {
334                    fprintf(stderr, "%s: filesystem %s already detached\n",
335                            progname, at->hesiodname);
336                    return SUCCESS;
337                }
338            fprintf(stderr, "%s: detach of filesystem %s failed, unable to remove mountpoint\n\terror is %s\n",
339                    progname, at->hesiodname, errstr(errno));
340            /* Set error_status? */
341            return FAILURE;
342        }
343    return SUCCESS;
344}
345
346int afs_auth_to_cell(cell)
347const char *cell;
348{
349    return(afs_auth_internal(cell, cell, 0, AFSAUTH_DOAUTH | AFSAUTH_CELL));
350}
351
352int afs_zinit(hesname, afsdir)
353const char *hesname, *afsdir;
354{
355    return(afs_auth_internal(hesname, afsdir, 0, AFSAUTH_DOZEPHYR));
356}
357#endif  /* AFS */
358
359
Note: See TracBrowser for help on using the repository browser.