source: trunk/athena/bin/attach/config.c @ 7417

Revision 7417, 11.0 KB checked in by miki, 30 years ago (diff)
replaces index by strchr
Line 
1/*
2 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/config.c,v $
3 *      $Author: miki $
4 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/config.c,v 1.7 1994-06-07 17:23:24 miki Exp $
5 */
6
7#ifndef lint
8static char *rcsid_config_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/config.c,v 1.7 1994-06-07 17:23:24 miki Exp $";
9#endif
10
11#include "attach.h"
12#include "pwd.h"
13#include <string.h>
14
15
16#define TOKSEP  " \t\r\n"
17
18/*
19 * Declare the filesystem tables for nosetuid and allowable mountings
20 */
21struct filesys_tab {
22        struct _tab {
23                char    *regexp;
24                int     fs_type;
25                int     explicit; /* 0 = don't care, 1 = explicit */
26                                  /* only, -1 = no explicit only */
27                char    *tab_data;
28        } tab[MAXFILTAB];
29        int     idx;            /* Index to next free entry */
30} nosuidtab, allowtab, goodmntpt, fsdb, optionsdb;
31
32static char     data_t[] = "#!TRUE";
33
34struct uid_tab {
35        int     tab[MAXTRUIDTAB];
36        int     idx;
37} trusted_uid;                  /* trusted uid table */
38
39/*
40 * Define the keyword table
41 */
42static void parse_boolean(), parse_string(), parse_uidlist(), parse_fslist();
43static void parse_fslista();
44static int get_fstype();
45
46struct key_def {
47        char    *key;
48        void    (*proc)();
49        caddr_t variable;
50        int     arg;
51} keyword_list[] = {
52        {"verbose",     parse_boolean,  (caddr_t) &verbose,     1 },
53        {"debug",       parse_boolean,  (caddr_t) &debug_flag,  1 },
54        {"ownercheck",  parse_boolean,  (caddr_t) &owner_check, 1 },
55        {"ownerlist",   parse_boolean,  (caddr_t) &owner_list,  1 },
56        {"keep-mount",  parse_boolean,  (caddr_t) &keep_mount,  1 },
57        {"explicit-mntpt",      parse_boolean,  (caddr_t) &exp_mntpt,   1 },
58        {"explicit",    parse_boolean,  (caddr_t) &exp_allow,   1 },
59               
60        {"nfs-root-hack", parse_boolean, (caddr_t) &nfs_root_hack, 1 },
61        {"nfs-mount-dir", parse_string, (caddr_t) &nfs_mount_dir, 0 },
62
63        {"attachtab",   parse_string,   (caddr_t) &attachtab_fn, 0 },
64        {"mtab",        parse_string,   (caddr_t) &mtab_fn, 0 },
65#ifdef AFS
66        {"aklog",       parse_string,   (caddr_t) &aklog_fn, 0 },
67        {"afs-mount-dir", parse_string, (caddr_t) &afs_mount_dir, 0 },
68#endif
69        {"fsck",        parse_string,   (caddr_t) &fsck_fn, 0 },
70
71        {"trusted",     parse_uidlist,  (caddr_t) &trusted_uid, 0 },
72        {"nosetuid",    parse_fslist,   (caddr_t) &nosuidtab,   1 },
73        {"nosuid",      parse_fslist,   (caddr_t) &nosuidtab,   1 },
74        {"setuid",      parse_fslist,   (caddr_t) &nosuidtab,   0 },
75        {"suid",        parse_fslist,   (caddr_t) &nosuidtab,   0 },
76        {"allow",       parse_fslist,   (caddr_t) &allowtab,    1 },
77        {"noallow",     parse_fslist,   (caddr_t) &allowtab,    0 },
78        {"mountpoint",  parse_fslist,   (caddr_t) &goodmntpt,   1 },
79        {"nomountpoint",parse_fslist,   (caddr_t) &goodmntpt,   0 },
80       
81        {"filesystem",  parse_fslista,  (caddr_t) &fsdb,        0 },
82        {"options",     parse_fslista,  (caddr_t) &optionsdb, 0},
83        {NULL,          NULL,           NULL,                   0 }
84};
85
86static void config_abort()
87{
88        fprintf(stderr, " Aborting...\n");
89        exit(ERR_BADCONF);
90}
91
92read_config_file(config_file_name)
93        const char *config_file_name;
94{
95        register FILE   *f;
96        static char     buff[256];
97        char            *cp;
98        register char   *keyword;
99        char            *argument;
100        struct key_def  *kp;
101
102        allowtab.tab[0].regexp = NULL;
103        nosuidtab.tab[0].regexp = NULL;
104        goodmntpt.tab[0].regexp = NULL;
105        fsdb.tab[0].regexp = NULL;
106        trusted_uid.tab[0] = -1;
107        if (debug_flag)
108                printf("Reading configuration file: %s\n", config_file_name);
109        if (!(f = fopen(config_file_name, "r"))) {
110                if (debug_flag)
111                        printf("Couldn't read conf file, continuing...\n");
112                return(SUCCESS);
113        }
114        while (fgets(buff, sizeof(buff), f)) {
115                cp = buff+strlen(buff)-1;
116                while (cp >= buff && *cp < 032)
117                        *cp-- = '\0';
118                cp = buff;
119                while (*cp && isspace(*cp)) cp++;
120                if (!*cp || *cp == '#')
121                        continue;
122                keyword = strtok(cp, TOKSEP);
123                argument = strtok(NULL, TOKSEP);
124                for (kp=keyword_list; kp->key; kp++) {
125                        if (!strcmp(kp->key, keyword)) {
126                                (kp->proc)(keyword,argument,buff,
127                                           kp->variable, kp->arg);
128                                break;
129                        }
130                }
131                if (!kp->key) {
132                        if (debug_flag)
133                fprintf(stderr, "%s: bad keyword in config file\n",
134                                        keyword);
135                }
136        }
137        return(SUCCESS);
138}
139
140static void parse_boolean(keyword, argument, buff, variable, arg)
141        char    *keyword, *argument, *buff;
142        caddr_t variable;
143        int     arg;
144{
145        if (argument && !strcmp(argument, "on"))
146                * (int *) variable = 1;
147        else if (argument && !strcmp(argument, "off"))
148                * (int *) variable = 0;
149        else {
150                if (arg == -1)
151                        if (argument)
152                          fprintf(stderr,
153                                  "%s: Argument to %s must be on or off!\n",
154                                  argument, keyword);
155                        else
156                          fprintf(stderr, "%s: Argument required!\n", keyword);
157                else
158                        * (int *) variable = arg;       /* Default */
159        }
160}
161
162static void parse_string(keyword, argument, buff, variable, arg)
163        char    *keyword, *argument, *buff;
164        caddr_t variable;
165        int     arg;
166{
167        if (!argument || !*argument) {
168                fprintf(stderr,
169                        "%s: missing argument in config file!\n",
170                        keyword);
171                config_abort();
172        }
173        if (* (char **) variable)
174                free(* (char **) variable);
175        * (char **) variable = strdup(argument);
176}
177
178static void parse_fslist(keyword, argument, buff, variable, set_sw)
179        char    *keyword, *argument, *buff;
180        caddr_t variable;
181        int     set_sw;
182{
183        register struct filesys_tab     *fslist;
184       
185        fslist = (struct filesys_tab *) variable;
186        while (argument && *argument) {
187                if (fslist->idx >= MAXFILTAB) {
188                        fprintf(stderr, "Exceeded filesystem table for %s!\n",
189                                keyword);
190                        config_abort();
191                }
192                fslist->tab[fslist->idx].fs_type = get_fstype(&argument,
193                                      &fslist->tab[fslist->idx].explicit);
194                fslist->tab[fslist->idx].regexp = strdup(argument);
195                fslist->tab[fslist->idx].tab_data = set_sw ? data_t : NULL;
196                fslist->idx++;
197                argument = strtok(NULL, TOKSEP);
198        }
199        fslist->tab[fslist->idx].regexp = NULL;
200        fslist->tab[fslist->idx].tab_data = NULL;
201}
202
203static void parse_fslista(keyword, argument, buff, variable, dummy)
204        char    *keyword, *argument, *buff;
205        caddr_t variable;
206        int     dummy;
207{
208        register struct filesys_tab     *fslist;
209        char    *cp;
210       
211        fslist = (struct filesys_tab *) variable;
212        if (fslist->idx >= MAXFILTAB) {
213                fprintf(stderr, "Exceeded filesystem table for %s!\n",
214                        keyword);
215                config_abort();
216        }
217        fslist->tab[fslist->idx].fs_type = get_fstype(&argument,
218                                      &fslist->tab[fslist->idx].explicit);
219        fslist->tab[fslist->idx].regexp = strdup(argument);
220        cp = strtok(NULL, "");
221        while (cp && *cp)
222                if (isspace(*cp))
223                        cp++;
224                else
225                        break;
226               
227        if (cp && *cp) {
228                fslist->tab[fslist->idx].tab_data = strdup(cp);
229        } else {
230                fprintf(stderr,
231                        "%s: missing filesystem definition in config file\n");
232                config_abort();
233        }
234        fslist->idx++;
235       
236        fslist->tab[fslist->idx].regexp = NULL;
237        fslist->tab[fslist->idx].tab_data = NULL;
238}
239
240/*
241 * Parse a filesystem type specification
242 *
243 * Format:   {nfs,afs}:tytso
244 *           {^ufs}:.*
245 *
246 */
247static int get_fstype(cpp, explicit)
248        char    **cpp;
249        int     *explicit;
250{
251        register char   *cp, *ptrstart;
252        register int    parsing, type;
253        int     negate = 0;
254        struct _fstypes *fs;
255        int     exp = 0;
256
257        if (explicit)
258                *explicit = 0;
259        cp = *cpp;
260        if (!cp || *cp++ != '{')
261                return(ALL_TYPES);
262        if (*cp == '+') {
263                exp = 1;
264                cp++;
265        } else if (*cp == '-') {
266                exp = -1;
267                cp++;
268        }
269        if (explicit)
270                *explicit = exp;
271        if (!strchr(cp, '}')) {
272                fprintf(stderr,"Error in filesystem specification:\n{%s\n",
273                        cp);
274                config_abort();
275        }
276        if (*cp == '^') {
277                negate++;
278                cp++;
279        }
280        parsing = 1;
281        type = 0;
282        while (parsing) {
283                ptrstart = cp;
284                if (!(cp = strchr(ptrstart,','))) {
285                        cp = strchr(ptrstart,'}');
286                        parsing = 0;
287                }
288                *cp++ = '\0';
289                fs = get_fs(ptrstart);
290                if (!fs) {
291                        fprintf(stderr,
292                                "%s: Illegal filesystem type in config file\n",
293                                ptrstart);
294                        config_abort();
295                }
296                type += fs->type;
297        }
298        if (negate)
299                type = ~type & ALL_TYPES;
300        if (*cp == ':')
301                cp++;
302        *cpp = cp;
303        return(type);
304}
305
306static void parse_uidlist(keyword, argument, buff, variable, arg)
307        char    *keyword, *argument, *buff;
308        caddr_t variable;
309        int     arg;
310{
311        register struct uid_tab         *ul;
312        int     uid;
313        struct passwd   *pw;
314       
315        ul = (struct uid_tab *) variable;
316        while (argument && *argument) {
317                if (ul->idx >= MAXTRUIDTAB) {
318                        fprintf(stderr, "Exceeded user table for %s!\n",
319                                keyword);
320                        config_abort();
321                }
322                if (isnumber(argument))
323                        uid = atoi(argument);
324                else {
325                        if ((pw = getpwnam(argument)))
326                                uid = pw->pw_uid;
327                        else {
328                                if (debug_flag)
329                                        fprintf(stderr,
330                                        "Unknown user %s in config file\n",
331                                                argument);
332                                argument = strtok(NULL, TOKSEP);
333                                continue;
334                        }
335                }
336                ul->tab[ul->idx] = uid;
337                ul->idx++;
338                argument = strtok(NULL, TOKSEP);
339        }
340        ul->tab[ul->idx] = -1;
341}
342
343isnumber(s)
344        register char   *s;
345{
346        register char   c;
347       
348        while (c = *s++)
349                if (!isdigit(c))
350                        return(0);
351        return(1);
352}
353
354char *re_comp();
355
356int nosetuid_filsys(name, type)
357        register char   *name;
358        int     type;
359{
360        register struct _tab    *fp;
361        char    *retval;
362
363        for (fp = nosuidtab.tab; fp->regexp; fp++) {
364                if (fp->explicit && ((explicit && fp->explicit == -1) ||
365                                     (!explicit && fp->explicit == 1)))
366                        continue;
367                if (!(fp->fs_type & type))
368                        continue;
369
370                if (retval=re_comp(fp->regexp)) {
371                        fprintf(stderr, "Nosetuid config: %s: %s",
372                                retval, fp->regexp);
373                        return(default_suid);
374                }
375                if (re_exec(name))
376                        return(fp->tab_data ? 1 : 0);
377        }
378
379        return(default_suid);
380}
381
382int allow_filsys(name, type)
383        register char   *name;
384        int     type;
385{
386        register struct _tab    *fp;
387        char    *retval;
388
389
390        for (fp = allowtab.tab; fp->regexp; fp++) {
391                if (fp->explicit && ((explicit && fp->explicit == -1) ||
392                                     (!explicit && fp->explicit == 1)))
393                        continue;
394                if (!(fp->fs_type & type))
395                        continue;
396
397                if (retval=re_comp(fp->regexp)) {
398                        fprintf(stderr, "Allow config: %s: %s",
399                                retval, fp->regexp);
400                        return(1);
401                }
402                if (re_exec(name))
403                        return(fp->tab_data ? 1 : 0);
404
405        }
406        return(1);              /* Default to allow filsystem to be mounted */
407}
408
409int check_mountpt(name, type)
410        register char   *name;
411        int     type;
412{
413        register struct _tab    *fp;
414        char    *retval;
415
416
417        for (fp = goodmntpt.tab; fp->regexp; fp++) {
418                if (fp->explicit && ((explicit && fp->explicit == -1) ||
419                                     (!explicit && fp->explicit == 1)))
420                        continue;
421                if (!(fp->fs_type & type))
422                        continue;
423
424
425                if (retval=re_comp(fp->regexp)) {
426                        fprintf(stderr, "Mountpoint config: %s: %s",
427                                retval, fp->regexp);
428                        return(1);
429                }
430                if (re_exec(name))
431                        return(fp->tab_data ? 1 : 0);
432
433        }
434        return(1);              /* Default to allow filsystem mounted */
435                                /* anywhere */
436}
437
438/*
439 * Return true if uid is of a trusted user.
440 */
441int trusted_user(uid)
442        int     uid;
443{
444        int     *ip;
445
446        ip = trusted_uid.tab;
447        while (*ip >= 0) {
448                if (uid == *ip)
449                        return(1);
450                ip++;
451        }
452        return(uid == 0);       /* Hard code root being trusted */
453}       
454
455/*
456 * Look up a filesystem name and return a ``hesiod'' entry
457 */
458char **conf_filsys_resolve(name)
459        char    *name;
460{
461        register struct _tab    *fp;
462        char    **hp;
463        static char     *hesptr[32];      /* Limit 32 ``hesiod'' entries */
464       
465        hp = hesptr;
466        for (fp = fsdb.tab; fp->regexp; fp++) {
467                if (!strcasecmp(fp->regexp, name))
468                        *hp++ = strdup(fp->tab_data);
469        }
470        *hp = NULL;
471        return(hesptr);
472}
473
474/*
475 * Return the options for a particular filesystem.
476 */
477char *filsys_options(name, type)
478        char    *name;
479        int     type;
480{
481        register struct _tab    *fp;
482        char    *retval;
483
484
485        for (fp = optionsdb.tab; fp->regexp; fp++) {
486                if (fp->explicit && ((explicit && fp->explicit == -1) ||
487                                     (!explicit && fp->explicit == 1)))
488                        continue;
489                if (!(fp->fs_type & type))
490                        continue;
491
492
493                if (retval=re_comp(fp->regexp)) {
494                        fprintf(stderr, "Mountpoint config: %s: %s",
495                                retval, fp->regexp);
496                        config_abort();
497                }
498                if (re_exec(name))
499                        return(fp->tab_data);
500
501        }
502        return(NULL);
503}
Note: See TracBrowser for help on using the repository browser.