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 * 8*42703Sbostic * %sccs.include.redist.c% 938460Smckusick */ 1038460Smckusick 1138460Smckusick #ifndef lint 1238460Smckusick char copyright[] = 1338460Smckusick "@(#) Copyright (c) 1989 Regents of the University of California.\n\ 1438460Smckusick All rights reserved.\n"; 1538460Smckusick #endif not lint 1638460Smckusick 1738460Smckusick #ifndef lint 18*42703Sbostic static char sccsid[] = "@(#)mountd.c 5.8 (Berkeley) 06/01/90"; 1938460Smckusick #endif not lint 2038460Smckusick 2138460Smckusick #include <sys/param.h> 2238460Smckusick #include <sys/ioctl.h> 2338460Smckusick #include <sys/stat.h> 2439681Smckusick #include <sys/file.h> 2538460Smckusick #include <sys/mount.h> 2638460Smckusick #include <sys/socket.h> 2738460Smckusick #include <sys/errno.h> 2842038Sbostic #include <sys/signal.h> 2942038Sbostic #include <stdio.h> 3042038Sbostic #include <string.h> 3142038Sbostic #include <syslog.h> 3238460Smckusick #include <netdb.h> 3338460Smckusick #include <rpc/rpc.h> 3438460Smckusick #include <rpc/pmap_clnt.h> 3538460Smckusick #include <rpc/pmap_prot.h> 3638460Smckusick #include <nfs/rpcv2.h> 3738460Smckusick #include <nfs/nfsv2.h> 3839681Smckusick #include "pathnames.h" 3938460Smckusick 4038460Smckusick struct ufid { 4138460Smckusick u_short ufid_len; 4238460Smckusick ino_t ufid_ino; 4338460Smckusick long ufid_gen; 4438460Smckusick }; 4538460Smckusick /* 4638460Smckusick * Structures for keeping the mount list and export list 4738460Smckusick */ 4838460Smckusick struct mountlist { 4938460Smckusick char ml_host[RPCMNT_NAMELEN+1]; 5038460Smckusick char ml_dirp[RPCMNT_PATHLEN+1]; 5138460Smckusick }; 5238460Smckusick 5338460Smckusick struct exportlist { 5438460Smckusick struct exportlist *ex_next; 5538460Smckusick struct exportlist *ex_prev; 5638460Smckusick struct grouplist *ex_groups; 5738460Smckusick int ex_rootuid; 5838460Smckusick int ex_exflags; 5938460Smckusick char ex_dirp[RPCMNT_PATHLEN+1]; 6038460Smckusick }; 6138460Smckusick 6238460Smckusick struct grouplist { 6338460Smckusick struct grouplist *gr_next; 6439681Smckusick struct hostent *gr_hp; 6538460Smckusick }; 6638460Smckusick 6738460Smckusick /* Global defs */ 6838460Smckusick int xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist(); 6938460Smckusick int mntsrv(), get_exportlist(); 7038460Smckusick struct exportlist exphead; 7139681Smckusick int mlfile; 7238460Smckusick char exname[MAXPATHLEN]; 7338460Smckusick int def_rootuid = -2; 7438460Smckusick extern int errno; 7538460Smckusick #ifdef DEBUG 7638460Smckusick int debug = 1; 7738460Smckusick #else 7838460Smckusick int debug = 0; 7938460Smckusick #endif 8038460Smckusick 8138460Smckusick /* 8238460Smckusick * Mountd server for NFS mount protocol as described in: 8339681Smckusick * NFS: Network File System Protocol Specification, RFC1094, Appendix A 8438460Smckusick * The optional argument is the exports file name 8539681Smckusick * default: _PATH_EXPORTS 8638460Smckusick */ 8738460Smckusick main(argc, argv) 8838460Smckusick int argc; 8938460Smckusick char *argv[]; 9038460Smckusick { 9138460Smckusick SVCXPRT *transp; 9238460Smckusick 9338460Smckusick if (debug == 0) { 9438460Smckusick if (fork()) 9538460Smckusick exit(0); 9638460Smckusick { int s; 9738460Smckusick for (s = 0; s < 10; s++) 9838460Smckusick (void) close(s); 9938460Smckusick } 10038460Smckusick (void) open("/", O_RDONLY); 10138460Smckusick (void) dup2(0, 1); 10238460Smckusick (void) dup2(0, 2); 10338460Smckusick { int tt = open("/dev/tty", O_RDWR); 10438460Smckusick if (tt > 0) { 10538460Smckusick ioctl(tt, TIOCNOTTY, (char *)0); 10638460Smckusick close(tt); 10738460Smckusick } 10838460Smckusick } 10938460Smckusick (void) setpgrp(0, 0); 11038460Smckusick signal(SIGTSTP, SIG_IGN); 11138460Smckusick signal(SIGTTIN, SIG_IGN); 11238460Smckusick signal(SIGTTOU, SIG_IGN); 11338460Smckusick signal(SIGINT, SIG_IGN); 11438460Smckusick signal(SIGQUIT, SIG_IGN); 11538460Smckusick signal(SIGTERM, SIG_IGN); 11638460Smckusick } 11738460Smckusick openlog("mountd:", LOG_PID, LOG_DAEMON); 11838460Smckusick exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; 11938460Smckusick if (argc == 2) { 12038460Smckusick strncpy(exname, argv[1], MAXPATHLEN-1); 12138460Smckusick exname[MAXPATHLEN-1] = '\0'; 12238460Smckusick } else 12339681Smckusick strcpy(exname, _PATH_EXPORTS); 12438460Smckusick get_exportlist(); 12538460Smckusick signal(SIGHUP, get_exportlist); 12640494Smckusick { FILE *pidfile = fopen(_PATH_MOUNTDPID, "w"); 12740494Smckusick if (pidfile != NULL) { 12840494Smckusick fprintf(pidfile, "%d\n", getpid()); 12940494Smckusick fclose(pidfile); 13040494Smckusick } 13140494Smckusick } 13239681Smckusick if ((mlfile = open(_PATH_RMOUNTLIST, (O_RDWR|O_CREAT), 0600)) < 0) { 13339681Smckusick syslog(LOG_ERR, "Can't open mountlist file"); 13439681Smckusick exit(1); 13539681Smckusick } 13638460Smckusick if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) { 13738460Smckusick syslog(LOG_ERR, "Can't create socket"); 13838460Smckusick exit(1); 13938460Smckusick } 14038460Smckusick pmap_unset(RPCPROG_MNT, RPCMNT_VER1); 14138460Smckusick if (!svc_register(transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, IPPROTO_UDP)) { 14238460Smckusick syslog(LOG_ERR, "Can't register mount"); 14338460Smckusick exit(1); 14438460Smckusick } 14538460Smckusick svc_run(); 14638460Smckusick syslog(LOG_ERR, "Mountd died"); 14738460Smckusick } 14838460Smckusick 14938460Smckusick /* 15038460Smckusick * The mount rpc service 15138460Smckusick */ 15238460Smckusick mntsrv(rqstp, transp) 15338460Smckusick register struct svc_req *rqstp; 15438460Smckusick register SVCXPRT *transp; 15538460Smckusick { 15639681Smckusick register struct grouplist *grp; 15739681Smckusick register u_long **addrp; 15838460Smckusick register struct exportlist *ep; 15939681Smckusick struct mountlist ml; 16038460Smckusick nfsv2fh_t nfh; 16138460Smckusick struct authunix_parms *ucr; 16238460Smckusick struct stat stb; 16338460Smckusick struct hostent *hp; 16439681Smckusick u_long saddr; 16538460Smckusick char dirpath[RPCMNT_PATHLEN+1]; 16638460Smckusick int ok = 0; 16738460Smckusick int bad = ENOENT; 16838460Smckusick int omask; 16939681Smckusick uid_t uid = -2; 17038460Smckusick 17138460Smckusick /* Get authorization */ 17238460Smckusick switch (rqstp->rq_cred.oa_flavor) { 17338460Smckusick case AUTH_UNIX: 17438460Smckusick ucr = (struct authunix_parms *)rqstp->rq_clntcred; 17539681Smckusick uid = ucr->aup_uid; 17639681Smckusick break; 17738460Smckusick case AUTH_NULL: 17838460Smckusick default: 17939681Smckusick break; 18038460Smckusick } 18138460Smckusick 18239681Smckusick saddr = transp->xp_raddr.sin_addr.s_addr; 18339681Smckusick hp = (struct hostent *)0; 18438460Smckusick switch (rqstp->rq_proc) { 18539681Smckusick case NULLPROC: 18639681Smckusick if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) 18739681Smckusick syslog(LOG_ERR, "Can't send reply"); 18839681Smckusick return; 18938460Smckusick case RPCMNT_MOUNT: 19039681Smckusick if (uid != 0) { 19139681Smckusick svcerr_weakauth(transp); 19239681Smckusick return; 19339681Smckusick } 19438460Smckusick if (!svc_getargs(transp, xdr_dir, dirpath)) { 19538460Smckusick svcerr_decode(transp); 19638460Smckusick return; 19738460Smckusick } 19838460Smckusick 19938460Smckusick /* Check to see if it's a valid dirpath */ 20038460Smckusick if (stat(dirpath, &stb) < 0 || (stb.st_mode&S_IFMT) != 20138460Smckusick S_IFDIR) { 20238460Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 20338460Smckusick syslog(LOG_ERR, "Can't send reply"); 20438460Smckusick return; 20538460Smckusick } 20638460Smckusick 20738460Smckusick /* Check in the exports list */ 20838460Smckusick omask = sigblock(sigmask(SIGHUP)); 20938460Smckusick ep = exphead.ex_next; 21038460Smckusick while (ep != NULL) { 21138460Smckusick if (!strcmp(ep->ex_dirp, dirpath)) { 21238460Smckusick grp = ep->ex_groups; 21338460Smckusick if (grp == NULL) 21438460Smckusick break; 21539681Smckusick 21639681Smckusick /* Check for a host match */ 21739681Smckusick addrp = (u_long **)grp->gr_hp->h_addr_list; 21839681Smckusick for (;;) { 21939681Smckusick if (**addrp == saddr) 22038460Smckusick break; 22139681Smckusick if (*++addrp == NULL) 22239681Smckusick if (grp = grp->gr_next) { 22339681Smckusick addrp = (u_long **) 22439681Smckusick grp->gr_hp->h_addr_list; 22539681Smckusick } else { 22639681Smckusick bad = EACCES; 22739681Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 22839681Smckusick syslog(LOG_ERR, "Can't send reply"); 22939681Smckusick sigsetmask(omask); 23039681Smckusick return; 23139681Smckusick } 23238460Smckusick } 23339681Smckusick hp = grp->gr_hp; 23439681Smckusick break; 23538460Smckusick } 23638460Smckusick ep = ep->ex_next; 23738460Smckusick } 23838460Smckusick sigsetmask(omask); 23938460Smckusick if (ep == NULL) { 24038460Smckusick bad = EACCES; 24138460Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 24238460Smckusick syslog(LOG_ERR, "Can't send reply"); 24338460Smckusick return; 24438460Smckusick } 24538460Smckusick 24638460Smckusick /* Get the file handle */ 24738460Smckusick bzero((caddr_t)&nfh, sizeof(nfh)); 24838460Smckusick if (getfh(dirpath, (fhandle_t *)&nfh) < 0) { 24938460Smckusick bad = errno; 25038460Smckusick if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 25138460Smckusick syslog(LOG_ERR, "Can't send reply"); 25238460Smckusick return; 25338460Smckusick } 25439681Smckusick #ifdef notnow 25539681Smckusick nfh.fh_generic.fh_fid.fid_gen = htonl(nfh.fh_generic.fh_fid.fid_gen); 25639681Smckusick #endif 25738460Smckusick if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&nfh)) 25838460Smckusick syslog(LOG_ERR, "Can't send reply"); 25939681Smckusick if (hp == NULL) 26039681Smckusick hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 26139681Smckusick if (hp) { 26239681Smckusick if (!fnd_mnt(hp->h_name, dirpath)) { 26339681Smckusick strcpy(ml.ml_host, hp->h_name); 26439681Smckusick strcpy(ml.ml_dirp, dirpath); 26539681Smckusick write(mlfile, (caddr_t)&ml, sizeof(ml)); 26639681Smckusick } 26738460Smckusick } 26838460Smckusick return; 26938460Smckusick case RPCMNT_DUMP: 27038460Smckusick if (!svc_sendreply(transp, xdr_mlist, (caddr_t)0)) 27138460Smckusick syslog(LOG_ERR, "Can't send reply"); 27238460Smckusick return; 27338460Smckusick case RPCMNT_UMOUNT: 27439681Smckusick if (uid != 0) { 27539681Smckusick svcerr_weakauth(transp); 27639681Smckusick return; 27739681Smckusick } 27838460Smckusick if (!svc_getargs(transp, xdr_dir, dirpath)) { 27938460Smckusick svcerr_decode(transp); 28038460Smckusick return; 28138460Smckusick } 28239681Smckusick hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 28339681Smckusick if (hp && fnd_mnt(hp->h_name, dirpath)) { 28439681Smckusick ml.ml_host[0] = '\0'; 28539681Smckusick write(mlfile, (caddr_t)&ml, sizeof(ml)); 28638460Smckusick } 28738460Smckusick if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) 28838460Smckusick syslog(LOG_ERR, "Can't send reply"); 28938460Smckusick return; 29038460Smckusick case RPCMNT_UMNTALL: 29139681Smckusick if (uid != 0) { 29239681Smckusick svcerr_weakauth(transp); 29339681Smckusick return; 29439681Smckusick } 29539681Smckusick hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 29639681Smckusick if (hp) { 29739681Smckusick lseek(mlfile, (off_t)0, L_SET); 29839681Smckusick while (read(mlfile, (caddr_t)&ml, sizeof(ml)) == 29939681Smckusick sizeof(ml)) { 30039681Smckusick if (!strcmp(hp->h_name, ml.ml_host)) { 30139681Smckusick lseek(mlfile, (off_t)-sizeof(ml), 30239681Smckusick L_INCR); 30339681Smckusick ml.ml_host[0] = '\0'; 30439681Smckusick write(mlfile, (caddr_t)&ml, sizeof(ml)); 30539681Smckusick } 30638460Smckusick } 30738460Smckusick } 30838460Smckusick if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) 30938460Smckusick syslog(LOG_ERR, "Can't send reply"); 31038460Smckusick return; 31138460Smckusick case RPCMNT_EXPORT: 31238460Smckusick if (!svc_sendreply(transp, xdr_explist, (caddr_t)0)) 31338460Smckusick syslog(LOG_ERR, "Can't send reply"); 31438460Smckusick return; 31538460Smckusick default: 31638460Smckusick svcerr_noproc(transp); 31738460Smckusick return; 31838460Smckusick } 31938460Smckusick } 32038460Smckusick 32138460Smckusick /* 32238460Smckusick * Xdr conversion for a dirpath string 32338460Smckusick */ 32438460Smckusick xdr_dir(xdrsp, dirp) 32538460Smckusick XDR *xdrsp; 32638460Smckusick char *dirp; 32738460Smckusick { 32838460Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 32938460Smckusick } 33038460Smckusick 33138460Smckusick /* 33238460Smckusick * Xdr routine to generate fhstatus 33338460Smckusick */ 33438460Smckusick xdr_fhs(xdrsp, nfh) 33538460Smckusick XDR *xdrsp; 33638460Smckusick nfsv2fh_t *nfh; 33738460Smckusick { 33838460Smckusick int ok = 0; 33938460Smckusick 34038460Smckusick if (!xdr_long(xdrsp, &ok)) 34138460Smckusick return (0); 34238460Smckusick return (xdr_opaque(xdrsp, (caddr_t)nfh, NFSX_FH)); 34338460Smckusick } 34438460Smckusick 34538460Smckusick xdr_mlist(xdrsp, cp) 34638460Smckusick XDR *xdrsp; 34738460Smckusick caddr_t cp; 34838460Smckusick { 34939681Smckusick struct mountlist ml; 35038460Smckusick int true = 1; 35138460Smckusick int false = 0; 35238460Smckusick char *strp; 35338460Smckusick 35439681Smckusick lseek(mlfile, (off_t)0, L_SET); 35539681Smckusick while (read(mlfile, (caddr_t)&ml, sizeof(ml)) == sizeof(ml)) { 35639681Smckusick if (ml.ml_host[0] != '\0') { 35739681Smckusick if (!xdr_bool(xdrsp, &true)) 35839681Smckusick return (0); 35939681Smckusick strp = &ml.ml_host[0]; 36039681Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) 36139681Smckusick return (0); 36239681Smckusick strp = &ml.ml_dirp[0]; 36339681Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) 36439681Smckusick return (0); 36539681Smckusick } 36638460Smckusick } 36738460Smckusick if (!xdr_bool(xdrsp, &false)) 36838460Smckusick return (0); 36938460Smckusick return (1); 37038460Smckusick } 37138460Smckusick 37238460Smckusick /* 37338460Smckusick * Xdr conversion for export list 37438460Smckusick */ 37538460Smckusick xdr_explist(xdrsp, cp) 37638460Smckusick XDR *xdrsp; 37738460Smckusick caddr_t cp; 37838460Smckusick { 37938460Smckusick register struct exportlist *ep; 38038460Smckusick register struct grouplist *grp; 38138460Smckusick int true = 1; 38238460Smckusick int false = 0; 38338460Smckusick char *strp; 38438460Smckusick int omask; 38538460Smckusick 38638460Smckusick omask = sigblock(sigmask(SIGHUP)); 38738460Smckusick ep = exphead.ex_next; 38838460Smckusick while (ep != NULL) { 38938460Smckusick if (!xdr_bool(xdrsp, &true)) 39038460Smckusick goto errout; 39138460Smckusick strp = &ep->ex_dirp[0]; 39238460Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) 39338460Smckusick goto errout; 39438460Smckusick grp = ep->ex_groups; 39538460Smckusick while (grp != NULL) { 39638460Smckusick if (!xdr_bool(xdrsp, &true)) 39738460Smckusick goto errout; 39839681Smckusick strp = grp->gr_hp->h_name; 39938460Smckusick if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) 40038460Smckusick goto errout; 40138460Smckusick grp = grp->gr_next; 40238460Smckusick } 40338460Smckusick if (!xdr_bool(xdrsp, &false)) 40438460Smckusick goto errout; 40538460Smckusick ep = ep->ex_next; 40638460Smckusick } 40738460Smckusick sigsetmask(omask); 40838460Smckusick if (!xdr_bool(xdrsp, &false)) 40938460Smckusick return (0); 41038460Smckusick return (1); 41138460Smckusick errout: 41238460Smckusick sigsetmask(omask); 41338460Smckusick return (0); 41438460Smckusick } 41538460Smckusick 41638460Smckusick #define LINESIZ 10240 41738460Smckusick char line[LINESIZ]; 41838460Smckusick 41938460Smckusick /* 42038460Smckusick * Get the export list 42138460Smckusick */ 42238460Smckusick get_exportlist() 42338460Smckusick { 42439681Smckusick register struct hostent *hp, *nhp; 42539681Smckusick register char **addrp, **naddrp; 42639681Smckusick register int i; 42739681Smckusick register struct grouplist *grp, *grp2; 42838460Smckusick register struct exportlist *ep, *ep2; 42940368Smckusick struct ufs_args args; 43038460Smckusick FILE *inf; 43138460Smckusick char *cp, *endcp; 43239681Smckusick char savedc; 43338460Smckusick int len; 43438460Smckusick int rootuid, exflags; 43538460Smckusick 43638460Smckusick /* 43738460Smckusick * First, get rid of the old list 43838460Smckusick */ 43938460Smckusick ep = exphead.ex_next; 44038460Smckusick while (ep != NULL) { 44138460Smckusick grp = ep->ex_groups; 44238460Smckusick while (grp != NULL) { 44339681Smckusick addrp = grp->gr_hp->h_addr_list; 44439681Smckusick while (*addrp) 44539681Smckusick free(*addrp++); 44639681Smckusick free((caddr_t)grp->gr_hp->h_addr_list); 44739681Smckusick free(grp->gr_hp->h_name); 44839681Smckusick free((caddr_t)grp->gr_hp); 44938460Smckusick grp2 = grp; 45038460Smckusick grp = grp->gr_next; 45138460Smckusick free((caddr_t)grp2); 45238460Smckusick } 45338460Smckusick ep2 = ep; 45438460Smckusick ep = ep->ex_next; 45538460Smckusick free((caddr_t)ep2); 45638460Smckusick } 45738460Smckusick 45838460Smckusick /* 45938460Smckusick * Read in the exports file and build the list, calling 46038460Smckusick * exportfs() as we go along 46138460Smckusick */ 46238460Smckusick exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; 46338460Smckusick if ((inf = fopen(exname, "r")) == NULL) { 46438460Smckusick syslog(LOG_ERR, "Can't open %s", exname); 46538460Smckusick exit(2); 46638460Smckusick } 46738460Smckusick while (fgets(line, LINESIZ, inf)) { 46841404Smckusick exflags = MNT_EXPORTED; 46938460Smckusick rootuid = def_rootuid; 47038460Smckusick cp = line; 47138460Smckusick nextfield(&cp, &endcp); 47238460Smckusick len = endcp-cp; 47338460Smckusick if (len <= RPCMNT_PATHLEN && len > 0) { 47438460Smckusick ep = (struct exportlist *)malloc(sizeof(*ep)); 47538460Smckusick ep->ex_next = ep->ex_prev = (struct exportlist *)0; 47638460Smckusick ep->ex_groups = (struct grouplist *)0; 47738460Smckusick bcopy(cp, ep->ex_dirp, len); 47838460Smckusick ep->ex_dirp[len] = '\0'; 47938460Smckusick } else 48038460Smckusick goto err; 48138460Smckusick cp = endcp; 48238460Smckusick nextfield(&cp, &endcp); 48338460Smckusick len = endcp-cp; 48438460Smckusick while (len > 0) { 48539681Smckusick savedc = *endcp; 48639681Smckusick *endcp = '\0'; 48738460Smckusick if (len <= RPCMNT_NAMELEN) { 48838460Smckusick if (*cp == '-') { 48938460Smckusick cp++; 49038460Smckusick switch (*cp) { 49138460Smckusick case 'o': 49241404Smckusick exflags |= MNT_EXRDONLY; 49338460Smckusick break; 49438460Smckusick case 'r': 49538460Smckusick if (*++cp == '=') 49638460Smckusick rootuid = atoi(++cp); 49738460Smckusick break; 49838460Smckusick default: 49938460Smckusick syslog(LOG_WARNING, 50038460Smckusick "Bad -%c option in %s", 50138460Smckusick *cp, exname); 50238460Smckusick break; 50338460Smckusick }; 50439681Smckusick } else if (hp = gethostbyname(cp)) { 50539681Smckusick grp = (struct grouplist *) 50639681Smckusick malloc(sizeof(struct grouplist)); 50738460Smckusick if (grp == NULL) 50838460Smckusick goto err; 50939681Smckusick nhp = grp->gr_hp = (struct hostent *) 51039681Smckusick malloc(sizeof(struct hostent)); 51139681Smckusick if (nhp == NULL) 51239681Smckusick goto err; 51339681Smckusick bcopy((caddr_t)hp, (caddr_t)nhp, 51439681Smckusick sizeof(struct hostent)); 51539681Smckusick i = strlen(hp->h_name)+1; 51639681Smckusick nhp->h_name = (char *)malloc(i); 51739681Smckusick if (nhp->h_name == NULL) 51839681Smckusick goto err; 51939681Smckusick bcopy(hp->h_name, nhp->h_name, i); 52039681Smckusick addrp = hp->h_addr_list; 52139681Smckusick i = 1; 52239681Smckusick while (*addrp++) 52339681Smckusick i++; 52439681Smckusick naddrp = nhp->h_addr_list = (char **) 52539681Smckusick malloc(i*sizeof(char *)); 52639681Smckusick if (naddrp == NULL) 52739681Smckusick goto err; 52839681Smckusick addrp = hp->h_addr_list; 52939681Smckusick while (*addrp) { 53039681Smckusick *naddrp = (char *) 53139681Smckusick malloc(hp->h_length); 53239681Smckusick bcopy(*addrp, *naddrp, 53339681Smckusick hp->h_length); 53439681Smckusick addrp++; 53539681Smckusick naddrp++; 53639681Smckusick } 53739681Smckusick *naddrp = (char *)0; 53838460Smckusick grp->gr_next = ep->ex_groups; 53938460Smckusick ep->ex_groups = grp; 54038460Smckusick } 54138460Smckusick } 54238460Smckusick cp = endcp; 54339681Smckusick *cp = savedc; 54438460Smckusick nextfield(&cp, &endcp); 54538460Smckusick len = endcp-cp; 54638460Smckusick } 54740368Smckusick args.fspec = 0; 54840368Smckusick args.exflags = exflags; 54940368Smckusick args.exroot = rootuid; 55041404Smckusick if (mount(MOUNT_UFS, ep->ex_dirp, MNT_UPDATE, &args) < 0) { 55138460Smckusick syslog(LOG_WARNING, "Can't export %s", ep->ex_dirp); 55238460Smckusick free((caddr_t)ep); 55338460Smckusick } else { 55438460Smckusick ep->ex_rootuid = rootuid; 55538460Smckusick ep->ex_exflags = exflags; 55638460Smckusick ep->ex_next = exphead.ex_next; 55738460Smckusick ep->ex_prev = &exphead; 55838460Smckusick if (ep->ex_next != NULL) 55938460Smckusick ep->ex_next->ex_prev = ep; 56038460Smckusick exphead.ex_next = ep; 56138460Smckusick } 56238460Smckusick } 56338460Smckusick fclose(inf); 56438460Smckusick return; 56538460Smckusick err: 56639681Smckusick syslog(LOG_ERR, "Bad Exports File, mountd Failed"); 56738460Smckusick exit(2); 56838460Smckusick } 56938460Smckusick 57038460Smckusick /* 57138460Smckusick * Parse out the next white space separated field 57238460Smckusick */ 57338460Smckusick nextfield(cp, endcp) 57438460Smckusick char **cp; 57538460Smckusick char **endcp; 57638460Smckusick { 57738460Smckusick register char *p; 57838460Smckusick 57938460Smckusick p = *cp; 58038460Smckusick while (*p == ' ' || *p == '\t') 58138460Smckusick p++; 58238460Smckusick if (*p == '\n' || *p == '\0') { 58338460Smckusick *cp = *endcp = p; 58438460Smckusick return; 58538460Smckusick } 58638460Smckusick *cp = p++; 58738460Smckusick while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 58838460Smckusick p++; 58938460Smckusick *endcp = p; 59038460Smckusick } 59139681Smckusick 59239681Smckusick /* 59339681Smckusick * Search the remote mounts file for a match. 59439681Smckusick * Iff found 59539681Smckusick * - set file offset to record and return TRUE 59639681Smckusick * else 59739681Smckusick * - set file offset to an unused record if found or eof otherwise 59839681Smckusick * and return FALSE 59939681Smckusick */ 60039681Smckusick fnd_mnt(host, dirp) 60139681Smckusick char *host; 60239681Smckusick char *dirp; 60339681Smckusick { 60439681Smckusick struct mountlist ml; 60539681Smckusick off_t off, pos; 60639681Smckusick 60739681Smckusick off = -1; 60839681Smckusick pos = 0; 60939681Smckusick lseek(mlfile, (off_t)0, L_SET); 61039681Smckusick while (read(mlfile, (caddr_t)&ml, sizeof(ml)) == sizeof(ml)) { 61139681Smckusick if (!strcmp(host, ml.ml_host) && !strcmp(dirp, ml.ml_dirp)) { 61239681Smckusick lseek(mlfile, (off_t)-sizeof(ml), L_INCR); 61339681Smckusick return (TRUE); 61439681Smckusick } else if (ml.ml_host[0] == '\0') { 61539681Smckusick off = pos; 61639681Smckusick } 61739681Smckusick pos += sizeof(ml); 61839681Smckusick } 61939681Smckusick if (off != -1) 62039681Smckusick lseek(mlfile, off, L_SET); 62139681Smckusick else 62239681Smckusick lseek(mlfile, (off_t)0, L_XTND); 62339681Smckusick return (FALSE); 62439681Smckusick } 625