Annotation of 43BSDReno/sbin/mountd/mountd.c, revision 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.