138460Smckusick /* 238460Smckusick * Copyright (c) 1989 The Regents of the University of California. 338460Smckusick * All rights reserved. 438460Smckusick * 538460Smckusick * This code is derived from software contributed to Berkeley by 638460Smckusick * Rick Macklem at The University of Guelph. 738460Smckusick * 838460Smckusick * Redistribution and use in source and binary forms are permitted 938460Smckusick * provided that the above copyright notice and this paragraph are 1038460Smckusick * duplicated in all such forms and that any documentation, 1138460Smckusick * advertising materials, and other materials related to such 1238460Smckusick * distribution and use acknowledge that the software was developed 1338460Smckusick * by the University of California, Berkeley. The name of the 1438460Smckusick * University may not be used to endorse or promote products derived 1538460Smckusick * from this software without specific prior written permission. 1638460Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1738460Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1838460Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1938460Smckusick */ 2038460Smckusick 2138460Smckusick #ifndef lint 2238460Smckusick char copyright[] = 2338460Smckusick "@(#) Copyright (c) 1989 Regents of the University of California.\n\ 2438460Smckusick All rights reserved.\n"; 2538460Smckusick #endif not lint 2638460Smckusick 2738460Smckusick #ifndef lint 28*40368Smckusick static char sccsid[] = "@(#)mountd.c 5.4 (Berkeley) 03/08/90"; 2938460Smckusick #endif not lint 3038460Smckusick 3138460Smckusick #include <stdio.h> 3238460Smckusick #include <strings.h> 3338460Smckusick #include <syslog.h> 3438460Smckusick #include <signal.h> 3538460Smckusick #include <sys/param.h> 3638460Smckusick #include <sys/ioctl.h> 3738460Smckusick #include <sys/stat.h> 3839681Smckusick #include <sys/file.h> 3938460Smckusick #include <sys/mount.h> 4038460Smckusick #include <sys/socket.h> 4138460Smckusick #include <sys/errno.h> 4238460Smckusick #include <netdb.h> 4338460Smckusick #include <rpc/rpc.h> 4438460Smckusick #include <rpc/pmap_clnt.h> 4538460Smckusick #include <rpc/pmap_prot.h> 4638460Smckusick #include <nfs/rpcv2.h> 4738460Smckusick #include <nfs/nfsv2.h> 4839681Smckusick #include "pathnames.h" 4938460Smckusick 5038460Smckusick struct ufid { 5138460Smckusick u_short ufid_len; 5238460Smckusick ino_t ufid_ino; 5338460Smckusick long ufid_gen; 5438460Smckusick }; 5538460Smckusick /* 5638460Smckusick * Structures for keeping the mount list and export list 5738460Smckusick */ 5838460Smckusick struct mountlist { 5938460Smckusick char ml_host[RPCMNT_NAMELEN+1]; 6038460Smckusick char ml_dirp[RPCMNT_PATHLEN+1]; 6138460Smckusick }; 6238460Smckusick 6338460Smckusick struct exportlist { 6438460Smckusick struct exportlist *ex_next; 6538460Smckusick struct exportlist *ex_prev; 6638460Smckusick struct grouplist *ex_groups; 6738460Smckusick int ex_rootuid; 6838460Smckusick int ex_exflags; 6938460Smckusick char ex_dirp[RPCMNT_PATHLEN+1]; 7038460Smckusick }; 7138460Smckusick 7238460Smckusick struct grouplist { 7338460Smckusick struct grouplist *gr_next; 7439681Smckusick struct hostent *gr_hp; 7538460Smckusick }; 7638460Smckusick 7738460Smckusick /* Global defs */ 7838460Smckusick int xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist(); 7938460Smckusick int mntsrv(), get_exportlist(); 8038460Smckusick struct exportlist exphead; 8139681Smckusick int mlfile; 8238460Smckusick char exname[MAXPATHLEN]; 8338460Smckusick int def_rootuid = -2; 8438460Smckusick extern int errno; 8538460Smckusick #ifdef DEBUG 8638460Smckusick int debug = 1; 8738460Smckusick #else 8838460Smckusick int debug = 0; 8938460Smckusick #endif 9038460Smckusick 9138460Smckusick /* 9238460Smckusick * Mountd server for NFS mount protocol as described in: 9339681Smckusick * NFS: Network File System Protocol Specification, RFC1094, Appendix A 9438460Smckusick * The optional argument is the exports file name 9539681Smckusick * default: _PATH_EXPORTS 9638460Smckusick */ 9738460Smckusick main(argc, argv) 9838460Smckusick int argc; 9938460Smckusick char *argv[]; 10038460Smckusick { 10138460Smckusick SVCXPRT *transp; 10238460Smckusick 10338460Smckusick if (debug == 0) { 10438460Smckusick if (fork()) 10538460Smckusick exit(0); 10638460Smckusick { int s; 10738460Smckusick for (s = 0; s < 10; s++) 10838460Smckusick (void) close(s); 10938460Smckusick } 11038460Smckusick (void) open("/", O_RDONLY); 11138460Smckusick (void) dup2(0, 1); 11238460Smckusick (void) dup2(0, 2); 11338460Smckusick { int tt = open("/dev/tty", O_RDWR); 11438460Smckusick if (tt > 0) { 11538460Smckusick ioctl(tt, TIOCNOTTY, (char *)0); 11638460Smckusick close(tt); 11738460Smckusick } 11838460Smckusick } 11938460Smckusick (void) setpgrp(0, 0); 12038460Smckusick signal(SIGTSTP, SIG_IGN); 12138460Smckusick signal(SIGTTIN, SIG_IGN); 12238460Smckusick signal(SIGTTOU, SIG_IGN); 12338460Smckusick signal(SIGINT, SIG_IGN); 12438460Smckusick signal(SIGQUIT, SIG_IGN); 12538460Smckusick signal(SIGTERM, SIG_IGN); 12638460Smckusick } 12738460Smckusick openlog("mountd:", LOG_PID, LOG_DAEMON); 12838460Smckusick exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; 12938460Smckusick if (argc == 2) { 13038460Smckusick strncpy(exname, argv[1], MAXPATHLEN-1); 13138460Smckusick exname[MAXPATHLEN-1] = '\0'; 13238460Smckusick } else 13339681Smckusick strcpy(exname, _PATH_EXPORTS); 13438460Smckusick get_exportlist(); 13538460Smckusick signal(SIGHUP, get_exportlist); 13639681Smckusick if ((mlfile = open(_PATH_RMOUNTLIST, (O_RDWR|O_CREAT), 0600)) < 0) { 13739681Smckusick syslog(LOG_ERR, "Can't open mountlist file"); 13839681Smckusick exit(1); 13939681Smckusick } 14038460Smckusick if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) { 14138460Smckusick syslog(LOG_ERR, "Can't create socket"); 14238460Smckusick exit(1); 14338460Smckusick } 14438460Smckusick pmap_unset(RPCPROG_MNT, RPCMNT_VER1); 14538460Smckusick if (!svc_register(transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, IPPROTO_UDP)) { 14638460Smckusick syslog(LOG_ERR, "Can't register mount"); 14738460Smckusick exit(1); 14838460Smckusick } 14938460Smckusick svc_run(); 15038460Smckusick syslog(LOG_ERR, "Mountd died"); 15138460Smckusick } 15238460Smckusick 15338460Smckusick /* 15438460Smckusick * The mount rpc service 15538460Smckusick */ 15638460Smckusick mntsrv(rqstp, transp) 15738460Smckusick register struct svc_req *rqstp; 15838460Smckusick register SVCXPRT *transp; 15938460Smckusick { 16039681Smckusick register struct grouplist *grp; 16139681Smckusick register u_long **addrp; 16238460Smckusick register struct exportlist *ep; 16339681Smckusick struct mountlist ml; 16438460Smckusick nfsv2fh_t nfh; 16538460Smckusick struct authunix_parms *ucr; 16638460Smckusick struct stat stb; 16738460Smckusick struct hostent *hp; 16839681Smckusick u_long saddr; 16938460Smckusick char dirpath[RPCMNT_PATHLEN+1]; 17038460Smckusick int ok = 0; 17138460Smckusick int bad = ENOENT; 17238460Smckusick int omask; 17339681Smckusick uid_t uid = -2; 17438460Smckusick 17538460Smckusick /* Get authorization */ 17638460Smckusick switch (rqstp->rq_cred.oa_flavor) { 17738460Smckusick case AUTH_UNIX: 17838460Smckusick ucr = (struct authunix_parms *)rqstp->rq_clntcred; 17939681Smckusick uid = ucr->aup_uid; 18039681Smckusick break; 18138460Smckusick case AUTH_NULL: 18238460Smckusick default: 18339681Smckusick break; 18438460Smckusick } 18538460Smckusick 18639681Smckusick saddr = transp->xp_raddr.sin_addr.s_addr; 18739681Smckusick hp = (struct hostent *)0; 18838460Smckusick switch (rqstp->rq_proc) { 18939681Smckusick case NULLPROC: 19039681Smckusick if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) 19139681Smckusick syslog(LOG_ERR, "Can't send reply"); 19239681Smckusick return; 19338460Smckusick case RPCMNT_MOUNT: 19439681Smckusick if (uid != 0) { 19539681Smckusick svcerr_weakauth(transp); 19639681Smckusick return; 19739681Smckusick } 19838460Smckusick if (!svc_getargs(transp, xdr_dir, dirpath)) { 19938460Smckusick svcerr_decode(transp); 20038460Smckusick return; 20138460Smckusick } 20238460Smckusick 20338460Smckusick /* Check to see if it's a valid dirpath */ 20438460Smckusick if (stat(dirpath, &stb) < 0 || (stb.st_mode&S_IFMT) != 20538460Smckusick S_IFDIR) { 20638460Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 20738460Smckusick syslog(LOG_ERR, "Can't send reply"); 20838460Smckusick return; 20938460Smckusick } 21038460Smckusick 21138460Smckusick /* Check in the exports list */ 21238460Smckusick omask = sigblock(sigmask(SIGHUP)); 21338460Smckusick ep = exphead.ex_next; 21438460Smckusick while (ep != NULL) { 21538460Smckusick if (!strcmp(ep->ex_dirp, dirpath)) { 21638460Smckusick grp = ep->ex_groups; 21738460Smckusick if (grp == NULL) 21838460Smckusick break; 21939681Smckusick 22039681Smckusick /* Check for a host match */ 22139681Smckusick addrp = (u_long **)grp->gr_hp->h_addr_list; 22239681Smckusick for (;;) { 22339681Smckusick if (**addrp == saddr) 22438460Smckusick break; 22539681Smckusick if (*++addrp == NULL) 22639681Smckusick if (grp = grp->gr_next) { 22739681Smckusick addrp = (u_long **) 22839681Smckusick grp->gr_hp->h_addr_list; 22939681Smckusick } else { 23039681Smckusick bad = EACCES; 23139681Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 23239681Smckusick syslog(LOG_ERR, "Can't send reply"); 23339681Smckusick sigsetmask(omask); 23439681Smckusick return; 23539681Smckusick } 23638460Smckusick } 23739681Smckusick hp = grp->gr_hp; 23839681Smckusick break; 23938460Smckusick } 24038460Smckusick ep = ep->ex_next; 24138460Smckusick } 24238460Smckusick sigsetmask(omask); 24338460Smckusick if (ep == NULL) { 24438460Smckusick bad = EACCES; 24538460Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 24638460Smckusick syslog(LOG_ERR, "Can't send reply"); 24738460Smckusick return; 24838460Smckusick } 24938460Smckusick 25038460Smckusick /* Get the file handle */ 25138460Smckusick bzero((caddr_t)&nfh, sizeof(nfh)); 25238460Smckusick if (getfh(dirpath, (fhandle_t *)&nfh) < 0) { 25338460Smckusick bad = errno; 25438460Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 25538460Smckusick syslog(LOG_ERR, "Can't send reply"); 25638460Smckusick return; 25738460Smckusick } 25839681Smckusick #ifdef notnow 25939681Smckusick nfh.fh_generic.fh_fid.fid_gen = htonl(nfh.fh_generic.fh_fid.fid_gen); 26039681Smckusick #endif 26138460Smckusick if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&nfh)) 26238460Smckusick syslog(LOG_ERR, "Can't send reply"); 26339681Smckusick if (hp == NULL) 26439681Smckusick hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 26539681Smckusick if (hp) { 26639681Smckusick if (!fnd_mnt(hp->h_name, dirpath)) { 26739681Smckusick strcpy(ml.ml_host, hp->h_name); 26839681Smckusick strcpy(ml.ml_dirp, dirpath); 26939681Smckusick write(mlfile, (caddr_t)&ml, sizeof(ml)); 27039681Smckusick } 27138460Smckusick } 27238460Smckusick return; 27338460Smckusick case RPCMNT_DUMP: 27438460Smckusick if (!svc_sendreply(transp, xdr_mlist, (caddr_t)0)) 27538460Smckusick syslog(LOG_ERR, "Can't send reply"); 27638460Smckusick return; 27738460Smckusick case RPCMNT_UMOUNT: 27839681Smckusick if (uid != 0) { 27939681Smckusick svcerr_weakauth(transp); 28039681Smckusick return; 28139681Smckusick } 28238460Smckusick if (!svc_getargs(transp, xdr_dir, dirpath)) { 28338460Smckusick svcerr_decode(transp); 28438460Smckusick return; 28538460Smckusick } 28639681Smckusick hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 28739681Smckusick if (hp && fnd_mnt(hp->h_name, dirpath)) { 28839681Smckusick ml.ml_host[0] = '\0'; 28939681Smckusick write(mlfile, (caddr_t)&ml, sizeof(ml)); 29038460Smckusick } 29138460Smckusick if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) 29238460Smckusick syslog(LOG_ERR, "Can't send reply"); 29338460Smckusick return; 29438460Smckusick case RPCMNT_UMNTALL: 29539681Smckusick if (uid != 0) { 29639681Smckusick svcerr_weakauth(transp); 29739681Smckusick return; 29839681Smckusick } 29939681Smckusick hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 30039681Smckusick if (hp) { 30139681Smckusick lseek(mlfile, (off_t)0, L_SET); 30239681Smckusick while (read(mlfile, (caddr_t)&ml, sizeof(ml)) == 30339681Smckusick sizeof(ml)) { 30439681Smckusick if (!strcmp(hp->h_name, ml.ml_host)) { 30539681Smckusick lseek(mlfile, (off_t)-sizeof(ml), 30639681Smckusick L_INCR); 30739681Smckusick ml.ml_host[0] = '\0'; 30839681Smckusick write(mlfile, (caddr_t)&ml, sizeof(ml)); 30939681Smckusick } 31038460Smckusick } 31138460Smckusick } 31238460Smckusick if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) 31338460Smckusick syslog(LOG_ERR, "Can't send reply"); 31438460Smckusick return; 31538460Smckusick case RPCMNT_EXPORT: 31638460Smckusick if (!svc_sendreply(transp, xdr_explist, (caddr_t)0)) 31738460Smckusick syslog(LOG_ERR, "Can't send reply"); 31838460Smckusick return; 31938460Smckusick default: 32038460Smckusick svcerr_noproc(transp); 32138460Smckusick return; 32238460Smckusick } 32338460Smckusick } 32438460Smckusick 32538460Smckusick /* 32638460Smckusick * Xdr conversion for a dirpath string 32738460Smckusick */ 32838460Smckusick xdr_dir(xdrsp, dirp) 32938460Smckusick XDR *xdrsp; 33038460Smckusick char *dirp; 33138460Smckusick { 33238460Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 33338460Smckusick } 33438460Smckusick 33538460Smckusick /* 33638460Smckusick * Xdr routine to generate fhstatus 33738460Smckusick */ 33838460Smckusick xdr_fhs(xdrsp, nfh) 33938460Smckusick XDR *xdrsp; 34038460Smckusick nfsv2fh_t *nfh; 34138460Smckusick { 34238460Smckusick int ok = 0; 34338460Smckusick 34438460Smckusick if (!xdr_long(xdrsp, &ok)) 34538460Smckusick return (0); 34638460Smckusick return (xdr_opaque(xdrsp, (caddr_t)nfh, NFSX_FH)); 34738460Smckusick } 34838460Smckusick 34938460Smckusick xdr_mlist(xdrsp, cp) 35038460Smckusick XDR *xdrsp; 35138460Smckusick caddr_t cp; 35238460Smckusick { 35339681Smckusick struct mountlist ml; 35438460Smckusick int true = 1; 35538460Smckusick int false = 0; 35638460Smckusick char *strp; 35738460Smckusick 35839681Smckusick lseek(mlfile, (off_t)0, L_SET); 35939681Smckusick while (read(mlfile, (caddr_t)&ml, sizeof(ml)) == sizeof(ml)) { 36039681Smckusick if (ml.ml_host[0] != '\0') { 36139681Smckusick if (!xdr_bool(xdrsp, &true)) 36239681Smckusick return (0); 36339681Smckusick strp = &ml.ml_host[0]; 36439681Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) 36539681Smckusick return (0); 36639681Smckusick strp = &ml.ml_dirp[0]; 36739681Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) 36839681Smckusick return (0); 36939681Smckusick } 37038460Smckusick } 37138460Smckusick if (!xdr_bool(xdrsp, &false)) 37238460Smckusick return (0); 37338460Smckusick return (1); 37438460Smckusick } 37538460Smckusick 37638460Smckusick /* 37738460Smckusick * Xdr conversion for export list 37838460Smckusick */ 37938460Smckusick xdr_explist(xdrsp, cp) 38038460Smckusick XDR *xdrsp; 38138460Smckusick caddr_t cp; 38238460Smckusick { 38338460Smckusick register struct exportlist *ep; 38438460Smckusick register struct grouplist *grp; 38538460Smckusick int true = 1; 38638460Smckusick int false = 0; 38738460Smckusick char *strp; 38838460Smckusick int omask; 38938460Smckusick 39038460Smckusick omask = sigblock(sigmask(SIGHUP)); 39138460Smckusick ep = exphead.ex_next; 39238460Smckusick while (ep != NULL) { 39338460Smckusick if (!xdr_bool(xdrsp, &true)) 39438460Smckusick goto errout; 39538460Smckusick strp = &ep->ex_dirp[0]; 39638460Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) 39738460Smckusick goto errout; 39838460Smckusick grp = ep->ex_groups; 39938460Smckusick while (grp != NULL) { 40038460Smckusick if (!xdr_bool(xdrsp, &true)) 40138460Smckusick goto errout; 40239681Smckusick strp = grp->gr_hp->h_name; 40338460Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) 40438460Smckusick goto errout; 40538460Smckusick grp = grp->gr_next; 40638460Smckusick } 40738460Smckusick if (!xdr_bool(xdrsp, &false)) 40838460Smckusick goto errout; 40938460Smckusick ep = ep->ex_next; 41038460Smckusick } 41138460Smckusick sigsetmask(omask); 41238460Smckusick if (!xdr_bool(xdrsp, &false)) 41338460Smckusick return (0); 41438460Smckusick return (1); 41538460Smckusick errout: 41638460Smckusick sigsetmask(omask); 41738460Smckusick return (0); 41838460Smckusick } 41938460Smckusick 42038460Smckusick #define LINESIZ 10240 42138460Smckusick char line[LINESIZ]; 42238460Smckusick 42338460Smckusick /* 42438460Smckusick * Get the export list 42538460Smckusick */ 42638460Smckusick get_exportlist() 42738460Smckusick { 42839681Smckusick register struct hostent *hp, *nhp; 42939681Smckusick register char **addrp, **naddrp; 43039681Smckusick register int i; 43139681Smckusick register struct grouplist *grp, *grp2; 43238460Smckusick register struct exportlist *ep, *ep2; 433*40368Smckusick struct ufs_args args; 43438460Smckusick FILE *inf; 43538460Smckusick char *cp, *endcp; 43639681Smckusick char savedc; 43738460Smckusick int len; 43838460Smckusick int rootuid, exflags; 43938460Smckusick 44038460Smckusick /* 44138460Smckusick * First, get rid of the old list 44238460Smckusick */ 44338460Smckusick ep = exphead.ex_next; 44438460Smckusick while (ep != NULL) { 44538460Smckusick grp = ep->ex_groups; 44638460Smckusick while (grp != NULL) { 44739681Smckusick addrp = grp->gr_hp->h_addr_list; 44839681Smckusick while (*addrp) 44939681Smckusick free(*addrp++); 45039681Smckusick free((caddr_t)grp->gr_hp->h_addr_list); 45139681Smckusick free(grp->gr_hp->h_name); 45239681Smckusick free((caddr_t)grp->gr_hp); 45338460Smckusick grp2 = grp; 45438460Smckusick grp = grp->gr_next; 45538460Smckusick free((caddr_t)grp2); 45638460Smckusick } 45738460Smckusick ep2 = ep; 45838460Smckusick ep = ep->ex_next; 45938460Smckusick free((caddr_t)ep2); 46038460Smckusick } 46138460Smckusick 46238460Smckusick /* 46338460Smckusick * Read in the exports file and build the list, calling 46438460Smckusick * exportfs() as we go along 46538460Smckusick */ 46638460Smckusick exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; 46738460Smckusick if ((inf = fopen(exname, "r")) == NULL) { 46838460Smckusick syslog(LOG_ERR, "Can't open %s", exname); 46938460Smckusick exit(2); 47038460Smckusick } 47138460Smckusick while (fgets(line, LINESIZ, inf)) { 472*40368Smckusick exflags = M_EXPORTED; 47338460Smckusick rootuid = def_rootuid; 47438460Smckusick cp = line; 47538460Smckusick nextfield(&cp, &endcp); 47638460Smckusick len = endcp-cp; 47738460Smckusick if (len <= RPCMNT_PATHLEN && len > 0) { 47838460Smckusick ep = (struct exportlist *)malloc(sizeof(*ep)); 47938460Smckusick ep->ex_next = ep->ex_prev = (struct exportlist *)0; 48038460Smckusick ep->ex_groups = (struct grouplist *)0; 48138460Smckusick bcopy(cp, ep->ex_dirp, len); 48238460Smckusick ep->ex_dirp[len] = '\0'; 48338460Smckusick } else 48438460Smckusick goto err; 48538460Smckusick cp = endcp; 48638460Smckusick nextfield(&cp, &endcp); 48738460Smckusick len = endcp-cp; 48838460Smckusick while (len > 0) { 48939681Smckusick savedc = *endcp; 49039681Smckusick *endcp = '\0'; 49138460Smckusick if (len <= RPCMNT_NAMELEN) { 49238460Smckusick if (*cp == '-') { 49338460Smckusick cp++; 49438460Smckusick switch (*cp) { 49538460Smckusick case 'o': 49638460Smckusick exflags |= M_EXRDONLY; 49738460Smckusick break; 49838460Smckusick case 'r': 49938460Smckusick if (*++cp == '=') 50038460Smckusick rootuid = atoi(++cp); 50138460Smckusick break; 50238460Smckusick default: 50338460Smckusick syslog(LOG_WARNING, 50438460Smckusick "Bad -%c option in %s", 50538460Smckusick *cp, exname); 50638460Smckusick break; 50738460Smckusick }; 50839681Smckusick } else if (hp = gethostbyname(cp)) { 50939681Smckusick grp = (struct grouplist *) 51039681Smckusick malloc(sizeof(struct grouplist)); 51138460Smckusick if (grp == NULL) 51238460Smckusick goto err; 51339681Smckusick nhp = grp->gr_hp = (struct hostent *) 51439681Smckusick malloc(sizeof(struct hostent)); 51539681Smckusick if (nhp == NULL) 51639681Smckusick goto err; 51739681Smckusick bcopy((caddr_t)hp, (caddr_t)nhp, 51839681Smckusick sizeof(struct hostent)); 51939681Smckusick i = strlen(hp->h_name)+1; 52039681Smckusick nhp->h_name = (char *)malloc(i); 52139681Smckusick if (nhp->h_name == NULL) 52239681Smckusick goto err; 52339681Smckusick bcopy(hp->h_name, nhp->h_name, i); 52439681Smckusick addrp = hp->h_addr_list; 52539681Smckusick i = 1; 52639681Smckusick while (*addrp++) 52739681Smckusick i++; 52839681Smckusick naddrp = nhp->h_addr_list = (char **) 52939681Smckusick malloc(i*sizeof(char *)); 53039681Smckusick if (naddrp == NULL) 53139681Smckusick goto err; 53239681Smckusick addrp = hp->h_addr_list; 53339681Smckusick while (*addrp) { 53439681Smckusick *naddrp = (char *) 53539681Smckusick malloc(hp->h_length); 53639681Smckusick bcopy(*addrp, *naddrp, 53739681Smckusick hp->h_length); 53839681Smckusick addrp++; 53939681Smckusick naddrp++; 54039681Smckusick } 54139681Smckusick *naddrp = (char *)0; 54238460Smckusick grp->gr_next = ep->ex_groups; 54338460Smckusick ep->ex_groups = grp; 54438460Smckusick } 54538460Smckusick } 54638460Smckusick cp = endcp; 54739681Smckusick *cp = savedc; 54838460Smckusick nextfield(&cp, &endcp); 54938460Smckusick len = endcp-cp; 55038460Smckusick } 551*40368Smckusick args.fspec = 0; 552*40368Smckusick args.exflags = exflags; 553*40368Smckusick args.exroot = rootuid; 554*40368Smckusick if (mount(MOUNT_UFS, ep->ex_dirp, M_UPDATE, &args) < 0) { 55538460Smckusick syslog(LOG_WARNING, "Can't export %s", ep->ex_dirp); 55638460Smckusick free((caddr_t)ep); 55738460Smckusick } else { 55838460Smckusick ep->ex_rootuid = rootuid; 55938460Smckusick ep->ex_exflags = exflags; 56038460Smckusick ep->ex_next = exphead.ex_next; 56138460Smckusick ep->ex_prev = &exphead; 56238460Smckusick if (ep->ex_next != NULL) 56338460Smckusick ep->ex_next->ex_prev = ep; 56438460Smckusick exphead.ex_next = ep; 56538460Smckusick } 56638460Smckusick } 56738460Smckusick fclose(inf); 56838460Smckusick return; 56938460Smckusick err: 57039681Smckusick syslog(LOG_ERR, "Bad Exports File, mountd Failed"); 57138460Smckusick exit(2); 57238460Smckusick } 57338460Smckusick 57438460Smckusick /* 57538460Smckusick * Parse out the next white space separated field 57638460Smckusick */ 57738460Smckusick nextfield(cp, endcp) 57838460Smckusick char **cp; 57938460Smckusick char **endcp; 58038460Smckusick { 58138460Smckusick register char *p; 58238460Smckusick 58338460Smckusick p = *cp; 58438460Smckusick while (*p == ' ' || *p == '\t') 58538460Smckusick p++; 58638460Smckusick if (*p == '\n' || *p == '\0') { 58738460Smckusick *cp = *endcp = p; 58838460Smckusick return; 58938460Smckusick } 59038460Smckusick *cp = p++; 59138460Smckusick while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 59238460Smckusick p++; 59338460Smckusick *endcp = p; 59438460Smckusick } 59539681Smckusick 59639681Smckusick /* 59739681Smckusick * Search the remote mounts file for a match. 59839681Smckusick * Iff found 59939681Smckusick * - set file offset to record and return TRUE 60039681Smckusick * else 60139681Smckusick * - set file offset to an unused record if found or eof otherwise 60239681Smckusick * and return FALSE 60339681Smckusick */ 60439681Smckusick fnd_mnt(host, dirp) 60539681Smckusick char *host; 60639681Smckusick char *dirp; 60739681Smckusick { 60839681Smckusick struct mountlist ml; 60939681Smckusick off_t off, pos; 61039681Smckusick 61139681Smckusick off = -1; 61239681Smckusick pos = 0; 61339681Smckusick lseek(mlfile, (off_t)0, L_SET); 61439681Smckusick while (read(mlfile, (caddr_t)&ml, sizeof(ml)) == sizeof(ml)) { 61539681Smckusick if (!strcmp(host, ml.ml_host) && !strcmp(dirp, ml.ml_dirp)) { 61639681Smckusick lseek(mlfile, (off_t)-sizeof(ml), L_INCR); 61739681Smckusick return (TRUE); 61839681Smckusick } else if (ml.ml_host[0] == '\0') { 61939681Smckusick off = pos; 62039681Smckusick } 62139681Smckusick pos += sizeof(ml); 62239681Smckusick } 62339681Smckusick if (off != -1) 62439681Smckusick lseek(mlfile, off, L_SET); 62539681Smckusick else 62639681Smckusick lseek(mlfile, (off_t)0, L_XTND); 62739681Smckusick return (FALSE); 62839681Smckusick } 629