Annotation of 43BSDReno/sbin/mountd/mountd.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Rick Macklem at The University of Guelph.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted provided
                      9:  * that: (1) source distributions retain this entire copyright notice and
                     10:  * comment, and (2) distributions including binaries display the following
                     11:  * acknowledgement:  ``This product includes software developed by the
                     12:  * University of California, Berkeley and its contributors'' in the
                     13:  * documentation or other materials provided with the distribution and in
                     14:  * all advertising materials mentioning features or use of this software.
                     15:  * Neither the name of the University nor the names of its contributors may
                     16:  * be used to endorse or promote products derived from this software without
                     17:  * specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     19:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     20:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: char copyright[] =
                     25: "@(#) Copyright (c) 1989 Regents of the University of California.\n\
                     26:  All rights reserved.\n";
                     27: #endif not lint
                     28: 
                     29: #ifndef lint
                     30: static char sccsid[] = "@(#)mountd.c   5.11 (Berkeley) 6/29/90";
                     31: #endif not lint
                     32: 
                     33: #include <sys/param.h>
                     34: #include <sys/ioctl.h>
                     35: #include <sys/stat.h>
                     36: #include <sys/file.h>
                     37: #include <sys/mount.h>
                     38: #include <sys/socket.h>
                     39: #include <sys/errno.h>
                     40: #include <sys/signal.h>
                     41: #include <stdio.h>
                     42: #include <string.h>
                     43: #include <syslog.h>
                     44: #include <netdb.h>
                     45: #include <rpc/rpc.h>
                     46: #include <rpc/pmap_clnt.h>
                     47: #include <rpc/pmap_prot.h>
                     48: #include <nfs/rpcv2.h>
                     49: #include <nfs/nfsv2.h>
                     50: #include "pathnames.h"
                     51: 
                     52: struct ufid {
                     53:        u_short ufid_len;
                     54:        ino_t   ufid_ino;
                     55:        long    ufid_gen;
                     56: };
                     57: /*
                     58:  * Structures for keeping the mount list and export list
                     59:  */
                     60: struct mountlist {
                     61:        struct mountlist *ml_next;
                     62:        char    ml_host[RPCMNT_NAMELEN+1];
                     63:        char    ml_dirp[RPCMNT_PATHLEN+1];
                     64: };
                     65: 
                     66: struct exportlist {
                     67:        struct exportlist *ex_next;
                     68:        struct exportlist *ex_prev;
                     69:        struct grouplist *ex_groups;
                     70:        int     ex_rootuid;
                     71:        int     ex_exflags;
                     72:        dev_t   ex_dev;
                     73:        char    ex_dirp[RPCMNT_PATHLEN+1];
                     74: };
                     75: 
                     76: struct grouplist {
                     77:        struct grouplist *gr_next;
                     78:        struct hostent *gr_hp;
                     79: };
                     80: 
                     81: /* Global defs */
                     82: int xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist();
                     83: int mntsrv(), get_exportlist(), send_umntall(), umntall_each();
                     84: void get_mountlist(), add_mlist(), del_mlist();
                     85: struct exportlist exphead;
                     86: struct mountlist *mlhead;
                     87: char exname[MAXPATHLEN];
                     88: int def_rootuid = -2;
                     89: int root_only = 1;
                     90: extern int errno;
                     91: #ifdef DEBUG
                     92: int debug = 1;
                     93: #else
                     94: int debug = 0;
                     95: #endif
                     96: 
                     97: /*
                     98:  * Mountd server for NFS mount protocol as described in:
                     99:  * NFS: Network File System Protocol Specification, RFC1094, Appendix A
                    100:  * The optional arguments are the exports file name
                    101:  * default: _PATH_EXPORTS
                    102:  * and "-n" to allow nonroot mount.
                    103:  */
                    104: main(argc, argv)
                    105:        int argc;
                    106:        char **argv;
                    107: {
                    108:        SVCXPRT *transp;
                    109:        int c;
                    110:        extern int optind;
                    111:        extern char *optarg;
                    112: 
                    113:        while ((c = getopt(argc, argv, "n")) != EOF)
                    114:                switch (c) {
                    115:                case 'n':
                    116:                        root_only = 0;
                    117:                        break;
                    118:                default:
                    119:                        fprintf(stderr, "Usage: mountd [-n] [export_file]\n");
                    120:                        exit(1);
                    121:                };
                    122:        argc -= optind;
                    123:        argv += optind;
                    124:        exphead.ex_next = exphead.ex_prev = (struct exportlist *)0;
                    125:        mlhead = (struct mountlist *)0;
                    126:        if (argc == 1) {
                    127:                strncpy(exname, *argv, MAXPATHLEN-1);
                    128:                exname[MAXPATHLEN-1] = '\0';
                    129:        } else
                    130:                strcpy(exname, _PATH_EXPORTS);
                    131:        openlog("mountd:", LOG_PID, LOG_DAEMON);
                    132:        get_exportlist();
                    133:        get_mountlist();
                    134:        if (debug == 0) {
                    135:                daemon(0, 0);
                    136:                signal(SIGINT, SIG_IGN);
                    137:                signal(SIGQUIT, SIG_IGN);
                    138:        }
                    139:        signal(SIGHUP, get_exportlist);
                    140:        signal(SIGTERM, send_umntall);
                    141:        { FILE *pidfile = fopen(_PATH_MOUNTDPID, "w");
                    142:          if (pidfile != NULL) {
                    143:                fprintf(pidfile, "%d\n", getpid());
                    144:                fclose(pidfile);
                    145:          }
                    146:        }
                    147:        if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) {
                    148:                syslog(LOG_ERR, "Can't create socket");
                    149:                exit(1);
                    150:        }
                    151:        pmap_unset(RPCPROG_MNT, RPCMNT_VER1);
                    152:        if (!svc_register(transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, IPPROTO_UDP)) {
                    153:                syslog(LOG_ERR, "Can't register mount");
                    154:                exit(1);
                    155:        }
                    156:        svc_run();
                    157:        syslog(LOG_ERR, "Mountd died");
                    158:        exit(1);
                    159: }
                    160: 
                    161: /*
                    162:  * The mount rpc service
                    163:  */
                    164: mntsrv(rqstp, transp)
                    165:        register struct svc_req *rqstp;
                    166:        register SVCXPRT *transp;
                    167: {
                    168:        register struct grouplist *grp;
                    169:        register u_long **addrp;
                    170:        register struct exportlist *ep;
                    171:        nfsv2fh_t nfh;
                    172:        struct authunix_parms *ucr;
                    173:        struct stat stb;
                    174:        struct hostent *hp;
                    175:        u_long saddr;
                    176:        char dirpath[RPCMNT_PATHLEN+1];
                    177:        int bad = ENOENT;
                    178:        int omask;
                    179:        uid_t uid = -2;
                    180: 
                    181:        /* Get authorization */
                    182:        switch (rqstp->rq_cred.oa_flavor) {
                    183:        case AUTH_UNIX:
                    184:                ucr = (struct authunix_parms *)rqstp->rq_clntcred;
                    185:                uid = ucr->aup_uid;
                    186:                break;
                    187:        case AUTH_NULL:
                    188:        default:
                    189:                break;
                    190:        }
                    191: 
                    192:        saddr = transp->xp_raddr.sin_addr.s_addr;
                    193:        hp = (struct hostent *)0;
                    194:        switch (rqstp->rq_proc) {
                    195:        case NULLPROC:
                    196:                if (!svc_sendreply(transp, xdr_void, (caddr_t)0))
                    197:                        syslog(LOG_ERR, "Can't send reply");
                    198:                return;
                    199:        case RPCMNT_MOUNT:
                    200:                if (uid != 0 && root_only) {
                    201:                        svcerr_weakauth(transp);
                    202:                        return;
                    203:                }
                    204:                if (!svc_getargs(transp, xdr_dir, dirpath)) {
                    205:                        svcerr_decode(transp);
                    206:                        return;
                    207:                }
                    208: 
                    209:                /* Check to see if it's a valid dirpath */
                    210:                if (stat(dirpath, &stb) < 0 || (stb.st_mode&S_IFMT) !=
                    211:                        S_IFDIR) {
                    212:                        if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
                    213:                                syslog(LOG_ERR, "Can't send reply");
                    214:                        return;
                    215:                }
                    216: 
                    217:                /* Check in the exports list */
                    218:                omask = sigblock(sigmask(SIGHUP));
                    219:                ep = exphead.ex_next;
                    220:                while (ep != NULL) {
                    221:                        if (!strcmp(ep->ex_dirp, dirpath)) {
                    222:                                grp = ep->ex_groups;
                    223:                                if (grp == NULL)
                    224:                                        break;
                    225: 
                    226:                                /* Check for a host match */
                    227:                                addrp = (u_long **)grp->gr_hp->h_addr_list;
                    228:                                for (;;) {
                    229:                                        if (**addrp == saddr)
                    230:                                                break;
                    231:                                        if (*++addrp == NULL)
                    232:                                                if (grp = grp->gr_next) {
                    233:                                                        addrp = (u_long **)
                    234:                                                                grp->gr_hp->h_addr_list;
                    235:                                                } else {
                    236:                                                        bad = EACCES;
                    237:                                                        if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
                    238:                                                                syslog(LOG_ERR, "Can't send reply");
                    239:                                                        sigsetmask(omask);
                    240:                                                        return;
                    241:                                                }
                    242:                                }
                    243:                                hp = grp->gr_hp;
                    244:                                break;
                    245:                        }
                    246:                        ep = ep->ex_next;
                    247:                }
                    248:                sigsetmask(omask);
                    249:                if (ep == NULL) {
                    250:                        bad = EACCES;
                    251:                        if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
                    252:                                syslog(LOG_ERR, "Can't send reply");
                    253:                        return;
                    254:                }
                    255: 
                    256:                /* Get the file handle */
                    257:                bzero((caddr_t)&nfh, sizeof(nfh));
                    258:                if (getfh(dirpath, (fhandle_t *)&nfh) < 0) {
                    259:                        bad = errno;
                    260:                        if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
                    261:                                syslog(LOG_ERR, "Can't send reply");
                    262:                        return;
                    263:                }
                    264:                if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&nfh))
                    265:                        syslog(LOG_ERR, "Can't send reply");
                    266:                if (hp == NULL)
                    267:                        hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET);
                    268:                if (hp)
                    269:                        add_mlist(hp->h_name, dirpath);
                    270:                return;
                    271:        case RPCMNT_DUMP:
                    272:                if (!svc_sendreply(transp, xdr_mlist, (caddr_t)0))
                    273:                        syslog(LOG_ERR, "Can't send reply");
                    274:                return;
                    275:        case RPCMNT_UMOUNT:
                    276:                if (uid != 0 && root_only) {
                    277:                        svcerr_weakauth(transp);
                    278:                        return;
                    279:                }
                    280:                if (!svc_getargs(transp, xdr_dir, dirpath)) {
                    281:                        svcerr_decode(transp);
                    282:                        return;
                    283:                }
                    284:                if (!svc_sendreply(transp, xdr_void, (caddr_t)0))
                    285:                        syslog(LOG_ERR, "Can't send reply");
                    286:                hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET);
                    287:                if (hp)
                    288:                        del_mlist(hp->h_name, dirpath);
                    289:                return;
                    290:        case RPCMNT_UMNTALL:
                    291:                if (uid != 0 && root_only) {
                    292:                        svcerr_weakauth(transp);
                    293:                        return;
                    294:                }
                    295:                if (!svc_sendreply(transp, xdr_void, (caddr_t)0))
                    296:                        syslog(LOG_ERR, "Can't send reply");
                    297:                hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET);
                    298:                if (hp)
                    299:                        del_mlist(hp->h_name, (char *)0);
                    300:                return;
                    301:        case RPCMNT_EXPORT:
                    302:                if (!svc_sendreply(transp, xdr_explist, (caddr_t)0))
                    303:                        syslog(LOG_ERR, "Can't send reply");
                    304:                return;
                    305:        default:
                    306:                svcerr_noproc(transp);
                    307:                return;
                    308:        }
                    309: }
                    310: 
                    311: /*
                    312:  * Xdr conversion for a dirpath string
                    313:  */
                    314: xdr_dir(xdrsp, dirp)
                    315:        XDR *xdrsp;
                    316:        char *dirp;
                    317: {
                    318:        return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
                    319: }
                    320: 
                    321: /*
                    322:  * Xdr routine to generate fhstatus
                    323:  */
                    324: xdr_fhs(xdrsp, nfh)
                    325:        XDR *xdrsp;
                    326:        nfsv2fh_t *nfh;
                    327: {
                    328:        int ok = 0;
                    329: 
                    330:        if (!xdr_long(xdrsp, &ok))
                    331:                return (0);
                    332:        return (xdr_opaque(xdrsp, (caddr_t)nfh, NFSX_FH));
                    333: }
                    334: 
                    335: xdr_mlist(xdrsp, cp)
                    336:        XDR *xdrsp;
                    337:        caddr_t cp;
                    338: {
                    339:        register struct mountlist *mlp;
                    340:        int true = 1;
                    341:        int false = 0;
                    342:        char *strp;
                    343: 
                    344:        mlp = mlhead;
                    345:        while (mlp) {
                    346:                if (!xdr_bool(xdrsp, &true))
                    347:                        return (0);
                    348:                strp = &mlp->ml_host[0];
                    349:                if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
                    350:                        return (0);
                    351:                strp = &mlp->ml_dirp[0];
                    352:                if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
                    353:                        return (0);
                    354:                mlp = mlp->ml_next;
                    355:        }
                    356:        if (!xdr_bool(xdrsp, &false))
                    357:                return (0);
                    358:        return (1);
                    359: }
                    360: 
                    361: /*
                    362:  * Xdr conversion for export list
                    363:  */
                    364: xdr_explist(xdrsp, cp)
                    365:        XDR *xdrsp;
                    366:        caddr_t cp;
                    367: {
                    368:        register struct exportlist *ep;
                    369:        register struct grouplist *grp;
                    370:        int true = 1;
                    371:        int false = 0;
                    372:        char *strp;
                    373:        int omask;
                    374: 
                    375:        omask = sigblock(sigmask(SIGHUP));
                    376:        ep = exphead.ex_next;
                    377:        while (ep != NULL) {
                    378:                if (!xdr_bool(xdrsp, &true))
                    379:                        goto errout;
                    380:                strp = &ep->ex_dirp[0];
                    381:                if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
                    382:                        goto errout;
                    383:                grp = ep->ex_groups;
                    384:                while (grp != NULL) {
                    385:                        if (!xdr_bool(xdrsp, &true))
                    386:                                goto errout;
                    387:                        strp = grp->gr_hp->h_name;
                    388:                        if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
                    389:                                goto errout;
                    390:                        grp = grp->gr_next;
                    391:                }
                    392:                if (!xdr_bool(xdrsp, &false))
                    393:                        goto errout;
                    394:                ep = ep->ex_next;
                    395:        }
                    396:        sigsetmask(omask);
                    397:        if (!xdr_bool(xdrsp, &false))
                    398:                return (0);
                    399:        return (1);
                    400: errout:
                    401:        sigsetmask(omask);
                    402:        return (0);
                    403: }
                    404: 
                    405: #define LINESIZ        10240
                    406: char line[LINESIZ];
                    407: 
                    408: /*
                    409:  * Get the export list
                    410:  */
                    411: get_exportlist()
                    412: {
                    413:        register struct hostent *hp, *nhp;
                    414:        register char **addrp, **naddrp;
                    415:        register int i;
                    416:        register struct grouplist *grp;
                    417:        register struct exportlist *ep, *ep2;
                    418:        struct ufs_args args;
                    419:        struct stat sb;
                    420:        FILE *inf;
                    421:        char *cp, *endcp;
                    422:        char savedc;
                    423:        int len, dirplen;
                    424:        int rootuid, exflags;
                    425:        u_long saddr;
                    426:        struct exportlist *fep;
                    427: 
                    428:        /*
                    429:         * First, get rid of the old list
                    430:         */
                    431:        ep = exphead.ex_next;
                    432:        while (ep != NULL) {
                    433:                ep2 = ep;
                    434:                ep = ep->ex_next;
                    435:                free_exp(ep2);
                    436:        }
                    437: 
                    438:        /*
                    439:         * Read in the exports file and build the list, calling
                    440:         * exportfs() as we go along
                    441:         */
                    442:        exphead.ex_next = exphead.ex_prev = (struct exportlist *)0;
                    443:        if ((inf = fopen(exname, "r")) == NULL) {
                    444:                syslog(LOG_ERR, "Can't open %s", exname);
                    445:                exit(2);
                    446:        }
                    447:        while (fgets(line, LINESIZ, inf)) {
                    448:                exflags = MNT_EXPORTED;
                    449:                rootuid = def_rootuid;
                    450:                cp = line;
                    451:                nextfield(&cp, &endcp);
                    452: 
                    453:                /*
                    454:                 * Get file system devno and see if an entry for this
                    455:                 * file system already exists.
                    456:                 */
                    457:                savedc = *endcp;
                    458:                *endcp = '\0';
                    459:                if (stat(cp, &sb) < 0 || (sb.st_mode & S_IFMT) != S_IFDIR)
                    460:                        goto err;
                    461:                fep = (struct exportlist *)0;
                    462:                ep = exphead.ex_next;
                    463:                while (ep) {
                    464:                        if (ep->ex_dev == sb.st_dev) {
                    465:                                fep = ep;
                    466:                                break;
                    467:                        }
                    468:                        ep = ep->ex_next;
                    469:                }
                    470:                *endcp = savedc;
                    471: 
                    472:                /*
                    473:                 * Create new exports list entry
                    474:                 */
                    475:                len = endcp-cp;
                    476:                if (len <= RPCMNT_PATHLEN && len > 0) {
                    477:                        ep = (struct exportlist *)malloc(sizeof(*ep));
                    478:                        ep->ex_next = ep->ex_prev = (struct exportlist *)0;
                    479:                        ep->ex_groups = (struct grouplist *)0;
                    480:                        bcopy(cp, ep->ex_dirp, len);
                    481:                        ep->ex_dirp[len] = '\0';
                    482:                        dirplen = len;
                    483:                } else
                    484:                        goto err;
                    485:                cp = endcp;
                    486:                nextfield(&cp, &endcp);
                    487:                len = endcp-cp;
                    488:                while (len > 0) {
                    489:                        savedc = *endcp;
                    490:                        *endcp = '\0';
                    491:                        if (len <= RPCMNT_NAMELEN) {
                    492:                                if (*cp == '-') {
                    493:                                    do_opt(cp+1, fep, ep, &exflags, &rootuid);
                    494:                                } else {
                    495:                                    if (isdigit(*cp)) {
                    496:                                        saddr = inet_addr(cp);
                    497:                                        if (saddr == -1 ||
                    498:                                            (hp = gethostbyaddr((caddr_t)&saddr,
                    499:                                             sizeof(saddr), AF_INET)) == NULL)
                    500:                                                goto err;
                    501:                                    } else if ((hp = gethostbyname(cp)) == NULL)
                    502:                                        goto err;
                    503:                                    grp = (struct grouplist *)
                    504:                                            malloc(sizeof(struct grouplist));
                    505:                                    if (grp == NULL)
                    506:                                            goto err;
                    507:                                    nhp = grp->gr_hp = (struct hostent *)
                    508:                                            malloc(sizeof(struct hostent));
                    509:                                    if (nhp == NULL)
                    510:                                            goto err;
                    511:                                    bcopy((caddr_t)hp, (caddr_t)nhp,
                    512:                                            sizeof(struct hostent));
                    513:                                    i = strlen(hp->h_name)+1;
                    514:                                    nhp->h_name = (char *)malloc(i);
                    515:                                    if (nhp->h_name == NULL)
                    516:                                            goto err;
                    517:                                    bcopy(hp->h_name, nhp->h_name, i);
                    518:                                    addrp = hp->h_addr_list;
                    519:                                    i = 1;
                    520:                                    while (*addrp++)
                    521:                                            i++;
                    522:                                    naddrp = nhp->h_addr_list = (char **)
                    523:                                            malloc(i*sizeof(char *));
                    524:                                    if (naddrp == NULL)
                    525:                                            goto err;
                    526:                                    addrp = hp->h_addr_list;
                    527:                                    while (*addrp) {
                    528:                                            *naddrp = (char *)
                    529:                                                malloc(hp->h_length);
                    530:                                            if (*naddrp == NULL)
                    531:                                                goto err;
                    532:                                            bcopy(*addrp, *naddrp,
                    533:                                                    hp->h_length);
                    534:                                            addrp++;
                    535:                                            naddrp++;
                    536:                                    }
                    537:                                    *naddrp = (char *)0;
                    538:                                    grp->gr_next = ep->ex_groups;
                    539:                                    ep->ex_groups = grp;
                    540:                                }
                    541:                        }
                    542:                        cp = endcp;
                    543:                        *cp = savedc;
                    544:                        nextfield(&cp, &endcp);
                    545:                        len = endcp-cp;
                    546:                }
                    547:                if (fep == NULL) {
                    548:                        args.fspec = 0;
                    549:                        args.exflags = exflags;
                    550:                        args.exroot = rootuid;
                    551:                        cp = (char *)0;
                    552:                        while (mount(MOUNT_UFS, ep->ex_dirp, MNT_UPDATE, &args) < 0) {
                    553:                                if (cp == NULL)
                    554:                                        cp = ep->ex_dirp + dirplen - 1;
                    555:                                else
                    556:                                        *cp = savedc;
                    557:                                /* back up over the last component */
                    558:                                while (*cp == '/' && cp > ep->ex_dirp)
                    559:                                        cp--;
                    560:                                while (*(cp - 1) != '/' && cp > ep->ex_dirp)
                    561:                                        cp--;
                    562:                                if (cp == ep->ex_dirp) {
                    563:                                        syslog(LOG_WARNING,
                    564:                                              "Can't export %s", ep->ex_dirp);
                    565:                                        free_exp(ep);
                    566:                                        goto nextline;
                    567:                                }
                    568:                                savedc = *cp;
                    569:                                *cp = '\0';
                    570:                        }
                    571:                        if (cp)
                    572:                                *cp = savedc;
                    573:                        ep->ex_rootuid = rootuid;
                    574:                        ep->ex_exflags = exflags;
                    575:                } else {
                    576:                        ep->ex_rootuid = fep->ex_rootuid;
                    577:                        ep->ex_exflags = fep->ex_exflags;
                    578:                }
                    579:                ep->ex_dev = sb.st_dev;
                    580:                ep->ex_next = exphead.ex_next;
                    581:                ep->ex_prev = &exphead;
                    582:                if (ep->ex_next != NULL)
                    583:                        ep->ex_next->ex_prev = ep;
                    584:                exphead.ex_next = ep;
                    585: nextline:
                    586:                ;
                    587:        }
                    588:        fclose(inf);
                    589:        return;
                    590: err:
                    591:        syslog(LOG_ERR, "Bad Exports File, mountd Failed");
                    592:        exit(2);
                    593: }
                    594: 
                    595: /*
                    596:  * Parse out the next white space separated field
                    597:  */
                    598: nextfield(cp, endcp)
                    599:        char **cp;
                    600:        char **endcp;
                    601: {
                    602:        register char *p;
                    603: 
                    604:        p = *cp;
                    605:        while (*p == ' ' || *p == '\t')
                    606:                p++;
                    607:        if (*p == '\n' || *p == '\0') {
                    608:                *cp = *endcp = p;
                    609:                return;
                    610:        }
                    611:        *cp = p++;
                    612:        while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
                    613:                p++;
                    614:        *endcp = p;
                    615: }
                    616: 
                    617: /*
                    618:  * Parse the option string
                    619:  */
                    620: do_opt(cpopt, fep, ep, exflagsp, rootuidp)
                    621:        register char *cpopt;
                    622:        struct exportlist *fep, *ep;
                    623:        int *exflagsp, *rootuidp;
                    624: {
                    625:        register char *cpoptarg, *cpoptend;
                    626: 
                    627:        while (cpopt && *cpopt) {
                    628:                if (cpoptend = index(cpopt, ','))
                    629:                        *cpoptend++ = '\0';
                    630:                if (cpoptarg = index(cpopt, '='))
                    631:                        *cpoptarg++ = '\0';
                    632:                if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) {
                    633:                        if (fep && (fep->ex_exflags & MNT_EXRDONLY) == 0)
                    634:                                syslog(LOG_WARNING, "ro failed for %s",
                    635:                                       ep->ex_dirp);
                    636:                        else
                    637:                                *exflagsp |= MNT_EXRDONLY;
                    638:                } else if (!strcmp(cpopt, "root") || !strcmp(cpopt, "r")) {
                    639:                        if (cpoptarg && isdigit(*cpoptarg)) {
                    640:                                *rootuidp = atoi(cpoptarg);
                    641:                                if (fep && fep->ex_rootuid != *rootuidp)
                    642:                                        syslog(LOG_WARNING,
                    643:                                               "uid failed for %s",
                    644:                                               ep->ex_dirp);
                    645:                        } else
                    646:                                syslog(LOG_WARNING,
                    647:                                       "uid failed for %s",
                    648:                                       ep->ex_dirp);
                    649:                } else
                    650:                        syslog(LOG_WARNING, "opt %s ignored for %s", cpopt,
                    651:                               ep->ex_dirp);
                    652:                cpopt = cpoptend;
                    653:        }
                    654: }
                    655: 
                    656: #define        STRSIZ  (RPCMNT_NAMELEN+RPCMNT_PATHLEN+50)
                    657: /*
                    658:  * Routines that maintain the remote mounttab
                    659:  */
                    660: void get_mountlist()
                    661: {
                    662:        register struct mountlist *mlp, **mlpp;
                    663:        register char *eos, *dirp;
                    664:        int len;
                    665:        char str[STRSIZ];
                    666:        FILE *mlfile;
                    667: 
                    668:        if (((mlfile = fopen(_PATH_RMOUNTLIST, "r")) == NULL) &&
                    669:            ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL)) {
                    670:                syslog(LOG_WARNING, "Can't open %s", _PATH_RMOUNTLIST);
                    671:                return;
                    672:        }
                    673:        mlpp = &mlhead;
                    674:        while (fgets(str, STRSIZ, mlfile) != NULL) {
                    675:                if ((dirp = index(str, '\t')) == NULL &&
                    676:                    (dirp = index(str, ' ')) == NULL)
                    677:                        continue;
                    678:                mlp = (struct mountlist *)malloc(sizeof (*mlp));
                    679:                len = dirp-str;
                    680:                if (len > RPCMNT_NAMELEN)
                    681:                        len = RPCMNT_NAMELEN;
                    682:                bcopy(str, mlp->ml_host, len);
                    683:                mlp->ml_host[len] = '\0';
                    684:                while (*dirp == '\t' || *dirp == ' ')
                    685:                        dirp++;
                    686:                if ((eos = index(dirp, '\t')) == NULL &&
                    687:                    (eos = index(dirp, ' ')) == NULL &&
                    688:                    (eos = index(dirp, '\n')) == NULL)
                    689:                        len = strlen(dirp);
                    690:                else
                    691:                        len = eos-dirp;
                    692:                if (len > RPCMNT_PATHLEN)
                    693:                        len = RPCMNT_PATHLEN;
                    694:                bcopy(dirp, mlp->ml_dirp, len);
                    695:                mlp->ml_dirp[len] = '\0';
                    696:                mlp->ml_next = (struct mountlist *)0;
                    697:                *mlpp = mlp;
                    698:                mlpp = &mlp->ml_next;
                    699:        }
                    700:        fclose(mlfile);
                    701: }
                    702: 
                    703: void del_mlist(hostp, dirp)
                    704:        register char *hostp, *dirp;
                    705: {
                    706:        register struct mountlist *mlp, **mlpp;
                    707:        FILE *mlfile;
                    708:        int fnd = 0;
                    709: 
                    710:        mlpp = &mlhead;
                    711:        mlp = mlhead;
                    712:        while (mlp) {
                    713:                if (!strcmp(mlp->ml_host, hostp) &&
                    714:                    (!dirp || !strcmp(mlp->ml_dirp, dirp))) {
                    715:                        fnd = 1;
                    716:                        *mlpp = mlp->ml_next;
                    717:                        free((caddr_t)mlp);
                    718:                }
                    719:                mlpp = &mlp->ml_next;
                    720:                mlp = mlp->ml_next;
                    721:        }
                    722:        if (fnd) {
                    723:                if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) {
                    724:                        syslog(LOG_WARNING, "Can't update %s", _PATH_RMOUNTLIST);
                    725:                        return;
                    726:                }
                    727:                mlp = mlhead;
                    728:                while (mlp) {
                    729:                        fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp);
                    730:                        mlp = mlp->ml_next;
                    731:                }
                    732:                fclose(mlfile);
                    733:        }
                    734: }
                    735: 
                    736: void add_mlist(hostp, dirp)
                    737:        register char *hostp, *dirp;
                    738: {
                    739:        register struct mountlist *mlp, **mlpp;
                    740:        FILE *mlfile;
                    741: 
                    742:        mlpp = &mlhead;
                    743:        mlp = mlhead;
                    744:        while (mlp) {
                    745:                if (!strcmp(mlp->ml_host, hostp) && !strcmp(mlp->ml_dirp, dirp))
                    746:                        return;
                    747:                mlpp = &mlp->ml_next;
                    748:                mlp = mlp->ml_next;
                    749:        }
                    750:        mlp = (struct mountlist *)malloc(sizeof (*mlp));
                    751:        strncpy(mlp->ml_host, hostp, RPCMNT_NAMELEN);
                    752:        mlp->ml_host[RPCMNT_NAMELEN] = '\0';
                    753:        strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN);
                    754:        mlp->ml_dirp[RPCMNT_PATHLEN] = '\0';
                    755:        mlp->ml_next = (struct mountlist *)0;
                    756:        *mlpp = mlp;
                    757:        if ((mlfile = fopen(_PATH_RMOUNTLIST, "a")) == NULL) {
                    758:                syslog(LOG_WARNING, "Can't update %s", _PATH_RMOUNTLIST);
                    759:                return;
                    760:        }
                    761:        fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp);
                    762:        fclose(mlfile);
                    763: }
                    764: 
                    765: /*
                    766:  * This function is called via. SIGTERM when the system is going down.
                    767:  * It sends a broadcast RPCMNT_UMNTALL.
                    768:  */
                    769: send_umntall()
                    770: {
                    771:        (void) clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL,
                    772:                xdr_void, (caddr_t)0, xdr_void, (caddr_t)0, umntall_each);
                    773:        exit();
                    774: }
                    775: 
                    776: umntall_each(resultsp, raddr)
                    777:        caddr_t resultsp;
                    778:        struct sockaddr_in *raddr;
                    779: {
                    780:        return (1);
                    781: }
                    782: 
                    783: /*
                    784:  * Free up an exports list component
                    785:  */
                    786: free_exp(ep)
                    787:        register struct exportlist *ep;
                    788: {
                    789:        register struct grouplist *grp;
                    790:        register char **addrp;
                    791:        struct grouplist *grp2;
                    792: 
                    793:        grp = ep->ex_groups;
                    794:        while (grp != NULL) {
                    795:                addrp = grp->gr_hp->h_addr_list;
                    796:                while (*addrp)
                    797:                        free(*addrp++);
                    798:                free((caddr_t)grp->gr_hp->h_addr_list);
                    799:                free(grp->gr_hp->h_name);
                    800:                free((caddr_t)grp->gr_hp);
                    801:                grp2 = grp;
                    802:                grp = grp->gr_next;
                    803:                free((caddr_t)grp2);
                    804:        }
                    805:        free((caddr_t)ep);
                    806: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.