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

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