18fae3551SRodney W. Grimes /* 28fae3551SRodney W. Grimes * Copyright (c) 1989, 1993 38fae3551SRodney W. Grimes * The Regents of the University of California. All rights reserved. 48fae3551SRodney W. Grimes * 58fae3551SRodney W. Grimes * This code is derived from software contributed to Berkeley by 68fae3551SRodney W. Grimes * Herb Hasler and Rick Macklem at The University of Guelph. 78fae3551SRodney W. Grimes * 88fae3551SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 98fae3551SRodney W. Grimes * modification, are permitted provided that the following conditions 108fae3551SRodney W. Grimes * are met: 118fae3551SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 128fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 138fae3551SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 148fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 158fae3551SRodney W. Grimes * documentation and/or other materials provided with the distribution. 168fae3551SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 178fae3551SRodney W. Grimes * must display the following acknowledgement: 188fae3551SRodney W. Grimes * This product includes software developed by the University of 198fae3551SRodney W. Grimes * California, Berkeley and its contributors. 208fae3551SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 218fae3551SRodney W. Grimes * may be used to endorse or promote products derived from this software 228fae3551SRodney W. Grimes * without specific prior written permission. 238fae3551SRodney W. Grimes * 248fae3551SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 258fae3551SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 268fae3551SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 278fae3551SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 288fae3551SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 298fae3551SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 308fae3551SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 318fae3551SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 328fae3551SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 338fae3551SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 348fae3551SRodney W. Grimes * SUCH DAMAGE. 358fae3551SRodney W. Grimes */ 368fae3551SRodney W. Grimes 378fae3551SRodney W. Grimes #ifndef lint 388fae3551SRodney W. Grimes static char copyright[] = 398fae3551SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 408fae3551SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 41d599144dSGarrett Wollman #endif /*not lint*/ 428fae3551SRodney W. Grimes 438fae3551SRodney W. Grimes #ifndef lint 4487564113SPeter Wemm /*static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95"; */ 45d599144dSGarrett Wollman static const char rcsid[] = 46e90cdb54SGuido van Rooij "$Id: mountd.c,v 1.22 1997/07/16 09:27:53 dfr Exp $"; 47d599144dSGarrett Wollman #endif /*not lint*/ 488fae3551SRodney W. Grimes 498fae3551SRodney W. Grimes #include <sys/param.h> 508fae3551SRodney W. Grimes #include <sys/file.h> 518fae3551SRodney W. Grimes #include <sys/ioctl.h> 528fae3551SRodney W. Grimes #include <sys/mount.h> 538fae3551SRodney W. Grimes #include <sys/socket.h> 548fae3551SRodney W. Grimes #include <sys/stat.h> 558fae3551SRodney W. Grimes #include <sys/syslog.h> 568fae3551SRodney W. Grimes #include <sys/ucred.h> 57394da4c1SGuido van Rooij #include <sys/sysctl.h> 588fae3551SRodney W. Grimes 598fae3551SRodney W. Grimes #include <rpc/rpc.h> 608fae3551SRodney W. Grimes #include <rpc/pmap_clnt.h> 618fae3551SRodney W. Grimes #include <rpc/pmap_prot.h> 628fae3551SRodney W. Grimes #ifdef ISO 638fae3551SRodney W. Grimes #include <netiso/iso.h> 648fae3551SRodney W. Grimes #endif 658fae3551SRodney W. Grimes #include <nfs/rpcv2.h> 66a62dc406SDoug Rabson #include <nfs/nfsproto.h> 67394da4c1SGuido van Rooij #include <nfs/nfs.h> 6887564113SPeter Wemm #include <ufs/ufs/ufsmount.h> 6987564113SPeter Wemm #include <msdosfs/msdosfsmount.h> 7087564113SPeter Wemm #include <isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */ 718fae3551SRodney W. Grimes 728fae3551SRodney W. Grimes #include <arpa/inet.h> 738fae3551SRodney W. Grimes 748fae3551SRodney W. Grimes #include <ctype.h> 758fae3551SRodney W. Grimes #include <errno.h> 768fae3551SRodney W. Grimes #include <grp.h> 778fae3551SRodney W. Grimes #include <netdb.h> 788fae3551SRodney W. Grimes #include <pwd.h> 798fae3551SRodney W. Grimes #include <signal.h> 808fae3551SRodney W. Grimes #include <stdio.h> 818fae3551SRodney W. Grimes #include <stdlib.h> 828fae3551SRodney W. Grimes #include <string.h> 838fae3551SRodney W. Grimes #include <unistd.h> 848fae3551SRodney W. Grimes #include "pathnames.h" 858fae3551SRodney W. Grimes 868fae3551SRodney W. Grimes #ifdef DEBUG 878fae3551SRodney W. Grimes #include <stdarg.h> 888fae3551SRodney W. Grimes #endif 898fae3551SRodney W. Grimes 908fae3551SRodney W. Grimes /* 918fae3551SRodney W. Grimes * Structures for keeping the mount list and export list 928fae3551SRodney W. Grimes */ 938fae3551SRodney W. Grimes struct mountlist { 948fae3551SRodney W. Grimes struct mountlist *ml_next; 958fae3551SRodney W. Grimes char ml_host[RPCMNT_NAMELEN+1]; 968fae3551SRodney W. Grimes char ml_dirp[RPCMNT_PATHLEN+1]; 978fae3551SRodney W. Grimes }; 988fae3551SRodney W. Grimes 998fae3551SRodney W. Grimes struct dirlist { 1008fae3551SRodney W. Grimes struct dirlist *dp_left; 1018fae3551SRodney W. Grimes struct dirlist *dp_right; 1028fae3551SRodney W. Grimes int dp_flag; 1038fae3551SRodney W. Grimes struct hostlist *dp_hosts; /* List of hosts this dir exported to */ 1048fae3551SRodney W. Grimes char dp_dirp[1]; /* Actually malloc'd to size of dir */ 1058fae3551SRodney W. Grimes }; 1068fae3551SRodney W. Grimes /* dp_flag bits */ 1078fae3551SRodney W. Grimes #define DP_DEFSET 0x1 108a62dc406SDoug Rabson #define DP_HOSTSET 0x2 109a62dc406SDoug Rabson #define DP_KERB 0x4 1108fae3551SRodney W. Grimes 1118fae3551SRodney W. Grimes struct exportlist { 1128fae3551SRodney W. Grimes struct exportlist *ex_next; 1138fae3551SRodney W. Grimes struct dirlist *ex_dirl; 1148fae3551SRodney W. Grimes struct dirlist *ex_defdir; 1158fae3551SRodney W. Grimes int ex_flag; 1168fae3551SRodney W. Grimes fsid_t ex_fs; 1178fae3551SRodney W. Grimes char *ex_fsdir; 118cb3923e0SDoug Rabson char *ex_indexfile; 1198fae3551SRodney W. Grimes }; 1208fae3551SRodney W. Grimes /* ex_flag bits */ 1218fae3551SRodney W. Grimes #define EX_LINKED 0x1 1228fae3551SRodney W. Grimes 1238fae3551SRodney W. Grimes struct netmsk { 1248fae3551SRodney W. Grimes u_long nt_net; 1258fae3551SRodney W. Grimes u_long nt_mask; 1268fae3551SRodney W. Grimes char *nt_name; 1278fae3551SRodney W. Grimes }; 1288fae3551SRodney W. Grimes 1298fae3551SRodney W. Grimes union grouptypes { 1308fae3551SRodney W. Grimes struct hostent *gt_hostent; 1318fae3551SRodney W. Grimes struct netmsk gt_net; 1328fae3551SRodney W. Grimes #ifdef ISO 1338fae3551SRodney W. Grimes struct sockaddr_iso *gt_isoaddr; 1348fae3551SRodney W. Grimes #endif 1358fae3551SRodney W. Grimes }; 1368fae3551SRodney W. Grimes 1378fae3551SRodney W. Grimes struct grouplist { 1388fae3551SRodney W. Grimes int gr_type; 1398fae3551SRodney W. Grimes union grouptypes gr_ptr; 1408fae3551SRodney W. Grimes struct grouplist *gr_next; 1418fae3551SRodney W. Grimes }; 1428fae3551SRodney W. Grimes /* Group types */ 1438fae3551SRodney W. Grimes #define GT_NULL 0x0 1448fae3551SRodney W. Grimes #define GT_HOST 0x1 1458fae3551SRodney W. Grimes #define GT_NET 0x2 1468fae3551SRodney W. Grimes #define GT_ISO 0x4 1478b5a6d67SBill Paul #define GT_IGNORE 0x5 1488fae3551SRodney W. Grimes 1498fae3551SRodney W. Grimes struct hostlist { 150a62dc406SDoug Rabson int ht_flag; /* Uses DP_xx bits */ 1518fae3551SRodney W. Grimes struct grouplist *ht_grp; 1528fae3551SRodney W. Grimes struct hostlist *ht_next; 1538fae3551SRodney W. Grimes }; 1548fae3551SRodney W. Grimes 155a62dc406SDoug Rabson struct fhreturn { 156a62dc406SDoug Rabson int fhr_flag; 157a62dc406SDoug Rabson int fhr_vers; 158a62dc406SDoug Rabson nfsfh_t fhr_fh; 159a62dc406SDoug Rabson }; 160a62dc406SDoug Rabson 1618fae3551SRodney W. Grimes /* Global defs */ 1628fae3551SRodney W. Grimes char *add_expdir __P((struct dirlist **, char *, int)); 1638fae3551SRodney W. Grimes void add_dlist __P((struct dirlist **, struct dirlist *, 164a62dc406SDoug Rabson struct grouplist *, int)); 1658fae3551SRodney W. Grimes void add_mlist __P((char *, char *)); 1668fae3551SRodney W. Grimes int check_dirpath __P((char *)); 1678fae3551SRodney W. Grimes int check_options __P((struct dirlist *)); 168a62dc406SDoug Rabson int chk_host __P((struct dirlist *, u_long, int *, int *)); 1698fae3551SRodney W. Grimes void del_mlist __P((char *, char *)); 1708fae3551SRodney W. Grimes struct dirlist *dirp_search __P((struct dirlist *, char *)); 1718fae3551SRodney W. Grimes int do_mount __P((struct exportlist *, struct grouplist *, int, 1728fae3551SRodney W. Grimes struct ucred *, char *, int, struct statfs *)); 1738fae3551SRodney W. Grimes int do_opt __P((char **, char **, struct exportlist *, struct grouplist *, 1748fae3551SRodney W. Grimes int *, int *, struct ucred *)); 1758fae3551SRodney W. Grimes struct exportlist *ex_search __P((fsid_t *)); 1768fae3551SRodney W. Grimes struct exportlist *get_exp __P((void)); 1778fae3551SRodney W. Grimes void free_dir __P((struct dirlist *)); 1788fae3551SRodney W. Grimes void free_exp __P((struct exportlist *)); 1798fae3551SRodney W. Grimes void free_grp __P((struct grouplist *)); 1808fae3551SRodney W. Grimes void free_host __P((struct hostlist *)); 1818fae3551SRodney W. Grimes void get_exportlist __P((void)); 1828b5a6d67SBill Paul int get_host __P((char *, struct grouplist *, struct grouplist *)); 183a62dc406SDoug Rabson int get_num __P((char *)); 1848fae3551SRodney W. Grimes struct hostlist *get_ht __P((void)); 1858fae3551SRodney W. Grimes int get_line __P((void)); 1868fae3551SRodney W. Grimes void get_mountlist __P((void)); 1878fae3551SRodney W. Grimes int get_net __P((char *, struct netmsk *, int)); 1888fae3551SRodney W. Grimes void getexp_err __P((struct exportlist *, struct grouplist *)); 1898fae3551SRodney W. Grimes struct grouplist *get_grp __P((void)); 1908fae3551SRodney W. Grimes void hang_dirp __P((struct dirlist *, struct grouplist *, 1918fae3551SRodney W. Grimes struct exportlist *, int)); 1928fae3551SRodney W. Grimes void mntsrv __P((struct svc_req *, SVCXPRT *)); 1938fae3551SRodney W. Grimes void nextfield __P((char **, char **)); 1948fae3551SRodney W. Grimes void out_of_mem __P((void)); 1958fae3551SRodney W. Grimes void parsecred __P((char *, struct ucred *)); 1968fae3551SRodney W. Grimes int put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int *)); 1978fae3551SRodney W. Grimes int scan_tree __P((struct dirlist *, u_long)); 1988fae3551SRodney W. Grimes void send_umntall __P((void)); 1998fae3551SRodney W. Grimes int umntall_each __P((caddr_t, struct sockaddr_in *)); 2008fae3551SRodney W. Grimes int xdr_dir __P((XDR *, char *)); 2018fae3551SRodney W. Grimes int xdr_explist __P((XDR *, caddr_t)); 202a62dc406SDoug Rabson int xdr_fhs __P((XDR *, caddr_t)); 2038fae3551SRodney W. Grimes int xdr_mlist __P((XDR *, caddr_t)); 2048fae3551SRodney W. Grimes 2058fae3551SRodney W. Grimes /* C library */ 2068fae3551SRodney W. Grimes int getnetgrent(); 2078fae3551SRodney W. Grimes void endnetgrent(); 2088fae3551SRodney W. Grimes void setnetgrent(); 2098fae3551SRodney W. Grimes 2108fae3551SRodney W. Grimes #ifdef ISO 2118fae3551SRodney W. Grimes struct iso_addr *iso_addr(); 2128fae3551SRodney W. Grimes #endif 2138fae3551SRodney W. Grimes 2148fae3551SRodney W. Grimes struct exportlist *exphead; 2158fae3551SRodney W. Grimes struct mountlist *mlhead; 2168fae3551SRodney W. Grimes struct grouplist *grphead; 2178fae3551SRodney W. Grimes char exname[MAXPATHLEN]; 2188fae3551SRodney W. Grimes struct ucred def_anon = { 2198fae3551SRodney W. Grimes 1, 2208fae3551SRodney W. Grimes (uid_t) -2, 2218fae3551SRodney W. Grimes 1, 2228fae3551SRodney W. Grimes { (gid_t) -2 } 2238fae3551SRodney W. Grimes }; 2242a66cfc5SDoug Rabson int force_v2 = 0; 225a62dc406SDoug Rabson int resvport_only = 1; 226a62dc406SDoug Rabson int dir_only = 1; 2278fae3551SRodney W. Grimes int opt_flags; 2288fae3551SRodney W. Grimes /* Bits for above */ 2298fae3551SRodney W. Grimes #define OP_MAPROOT 0x01 2308fae3551SRodney W. Grimes #define OP_MAPALL 0x02 2318fae3551SRodney W. Grimes #define OP_KERB 0x04 2328fae3551SRodney W. Grimes #define OP_MASK 0x08 2338fae3551SRodney W. Grimes #define OP_NET 0x10 2348fae3551SRodney W. Grimes #define OP_ISO 0x20 2358fae3551SRodney W. Grimes #define OP_ALLDIRS 0x40 2368fae3551SRodney W. Grimes 2378fae3551SRodney W. Grimes #ifdef DEBUG 2388fae3551SRodney W. Grimes int debug = 1; 2398fae3551SRodney W. Grimes void SYSLOG __P((int, const char *, ...)); 2408fae3551SRodney W. Grimes #define syslog SYSLOG 2418fae3551SRodney W. Grimes #else 2428fae3551SRodney W. Grimes int debug = 0; 2438fae3551SRodney W. Grimes #endif 2448fae3551SRodney W. Grimes 2458fae3551SRodney W. Grimes /* 2468fae3551SRodney W. Grimes * Mountd server for NFS mount protocol as described in: 2478fae3551SRodney W. Grimes * NFS: Network File System Protocol Specification, RFC1094, Appendix A 2488fae3551SRodney W. Grimes * The optional arguments are the exports file name 2498fae3551SRodney W. Grimes * default: _PATH_EXPORTS 2508fae3551SRodney W. Grimes * and "-n" to allow nonroot mount. 2518fae3551SRodney W. Grimes */ 2528fae3551SRodney W. Grimes int 2538fae3551SRodney W. Grimes main(argc, argv) 2548fae3551SRodney W. Grimes int argc; 2558fae3551SRodney W. Grimes char **argv; 2568fae3551SRodney W. Grimes { 257d3628763SRodney W. Grimes SVCXPRT *udptransp, *tcptransp; 2588fae3551SRodney W. Grimes int c; 2591f45d4d4SBruce Evans int mib[3]; 260a62dc406SDoug Rabson #ifdef __FreeBSD__ 26187564113SPeter Wemm struct vfsconf vfc; 26287564113SPeter Wemm int error; 263d599144dSGarrett Wollman 26487564113SPeter Wemm error = getvfsbyname("nfs", &vfc); 26587564113SPeter Wemm if (error && vfsisloadable("nfs")) { 266d599144dSGarrett Wollman if(vfsload("nfs")) 267d599144dSGarrett Wollman err(1, "vfsload(nfs)"); 268d599144dSGarrett Wollman endvfsent(); /* flush cache */ 26987564113SPeter Wemm error = getvfsbyname("nfs", &vfc); 270d599144dSGarrett Wollman } 27187564113SPeter Wemm if (error) 272d599144dSGarrett Wollman errx(1, "NFS support is not available in the running kernel"); 273a62dc406SDoug Rabson #endif /* __FreeBSD__ */ 2748fae3551SRodney W. Grimes 2752a66cfc5SDoug Rabson while ((c = getopt(argc, argv, "2dnr")) != -1) 2768fae3551SRodney W. Grimes switch (c) { 2772a66cfc5SDoug Rabson case '2': 2782a66cfc5SDoug Rabson force_v2 = 1; 2792a66cfc5SDoug Rabson break; 280a62dc406SDoug Rabson case 'n': 281a62dc406SDoug Rabson resvport_only = 0; 282a62dc406SDoug Rabson break; 283a62dc406SDoug Rabson case 'r': 284a62dc406SDoug Rabson dir_only = 0; 285a62dc406SDoug Rabson break; 2866444ef3bSPoul-Henning Kamp case 'd': 2876444ef3bSPoul-Henning Kamp debug = debug ? 0 : 1; 2886444ef3bSPoul-Henning Kamp break; 2898fae3551SRodney W. Grimes default: 29087564113SPeter Wemm fprintf(stderr, "Usage: mountd [-d] [-r] [-n] [export_file]\n"); 2918fae3551SRodney W. Grimes exit(1); 2928fae3551SRodney W. Grimes }; 2938fae3551SRodney W. Grimes argc -= optind; 2948fae3551SRodney W. Grimes argv += optind; 2958fae3551SRodney W. Grimes grphead = (struct grouplist *)NULL; 2968fae3551SRodney W. Grimes exphead = (struct exportlist *)NULL; 2978fae3551SRodney W. Grimes mlhead = (struct mountlist *)NULL; 2988fae3551SRodney W. Grimes if (argc == 1) { 2998fae3551SRodney W. Grimes strncpy(exname, *argv, MAXPATHLEN-1); 3008fae3551SRodney W. Grimes exname[MAXPATHLEN-1] = '\0'; 3018fae3551SRodney W. Grimes } else 3028fae3551SRodney W. Grimes strcpy(exname, _PATH_EXPORTS); 3038fae3551SRodney W. Grimes openlog("mountd", LOG_PID, LOG_DAEMON); 3048fae3551SRodney W. Grimes if (debug) 3058fae3551SRodney W. Grimes fprintf(stderr,"Getting export list.\n"); 3068fae3551SRodney W. Grimes get_exportlist(); 3078fae3551SRodney W. Grimes if (debug) 3088fae3551SRodney W. Grimes fprintf(stderr,"Getting mount list.\n"); 3098fae3551SRodney W. Grimes get_mountlist(); 3108fae3551SRodney W. Grimes if (debug) 3118fae3551SRodney W. Grimes fprintf(stderr,"Here we go.\n"); 3128fae3551SRodney W. Grimes if (debug == 0) { 3138fae3551SRodney W. Grimes daemon(0, 0); 3148fae3551SRodney W. Grimes signal(SIGINT, SIG_IGN); 3158fae3551SRodney W. Grimes signal(SIGQUIT, SIG_IGN); 3168fae3551SRodney W. Grimes } 3178fae3551SRodney W. Grimes signal(SIGHUP, (void (*) __P((int))) get_exportlist); 3188fae3551SRodney W. Grimes signal(SIGTERM, (void (*) __P((int))) send_umntall); 3198fae3551SRodney W. Grimes { FILE *pidfile = fopen(_PATH_MOUNTDPID, "w"); 3208fae3551SRodney W. Grimes if (pidfile != NULL) { 3218fae3551SRodney W. Grimes fprintf(pidfile, "%d\n", getpid()); 3228fae3551SRodney W. Grimes fclose(pidfile); 3238fae3551SRodney W. Grimes } 3248fae3551SRodney W. Grimes } 325394da4c1SGuido van Rooij 326c6e5e158SGuido van Rooij if (!resvport_only) { 327394da4c1SGuido van Rooij mib[0] = CTL_VFS; 328394da4c1SGuido van Rooij mib[1] = MOUNT_NFS; 329394da4c1SGuido van Rooij mib[2] = NFS_NFSPRIVPORT; 3301f45d4d4SBruce Evans if (sysctl(mib, 3, NULL, NULL, &resvport_only, 3311f45d4d4SBruce Evans sizeof(resvport_only)) != 0 && errno != ENOENT) { 332394da4c1SGuido van Rooij syslog(LOG_ERR, "sysctl: %m"); 333394da4c1SGuido van Rooij exit(1); 334394da4c1SGuido van Rooij } 335c6e5e158SGuido van Rooij } 336394da4c1SGuido van Rooij 337d3628763SRodney W. Grimes if ((udptransp = svcudp_create(RPC_ANYSOCK)) == NULL || 338d3628763SRodney W. Grimes (tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) { 3398fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't create socket"); 3408fae3551SRodney W. Grimes exit(1); 3418fae3551SRodney W. Grimes } 342a62dc406SDoug Rabson pmap_unset(RPCPROG_MNT, 1); 343a62dc406SDoug Rabson pmap_unset(RPCPROG_MNT, 3); 3442a66cfc5SDoug Rabson if (!force_v2) 3452a66cfc5SDoug Rabson if (!svc_register(udptransp, RPCPROG_MNT, 3, mntsrv, IPPROTO_UDP) || 346a62dc406SDoug Rabson !svc_register(tcptransp, RPCPROG_MNT, 3, mntsrv, IPPROTO_TCP)) { 3478fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't register mount"); 3488fae3551SRodney W. Grimes exit(1); 3498fae3551SRodney W. Grimes } 3502a66cfc5SDoug Rabson if (!svc_register(udptransp, RPCPROG_MNT, 1, mntsrv, IPPROTO_UDP) || 3512a66cfc5SDoug Rabson !svc_register(tcptransp, RPCPROG_MNT, 1, mntsrv, IPPROTO_TCP)) { 3522a66cfc5SDoug Rabson syslog(LOG_ERR, "Can't register mount"); 3532a66cfc5SDoug Rabson exit(1); 3542a66cfc5SDoug Rabson } 3558fae3551SRodney W. Grimes svc_run(); 3568fae3551SRodney W. Grimes syslog(LOG_ERR, "Mountd died"); 3578fae3551SRodney W. Grimes exit(1); 3588fae3551SRodney W. Grimes } 3598fae3551SRodney W. Grimes 3608fae3551SRodney W. Grimes /* 3618fae3551SRodney W. Grimes * The mount rpc service 3628fae3551SRodney W. Grimes */ 3638fae3551SRodney W. Grimes void 3648fae3551SRodney W. Grimes mntsrv(rqstp, transp) 3658fae3551SRodney W. Grimes struct svc_req *rqstp; 3668fae3551SRodney W. Grimes SVCXPRT *transp; 3678fae3551SRodney W. Grimes { 3688fae3551SRodney W. Grimes struct exportlist *ep; 3698fae3551SRodney W. Grimes struct dirlist *dp; 370a62dc406SDoug Rabson struct fhreturn fhr; 3718fae3551SRodney W. Grimes struct stat stb; 3728fae3551SRodney W. Grimes struct statfs fsb; 3738fae3551SRodney W. Grimes struct hostent *hp; 3748fae3551SRodney W. Grimes u_long saddr; 375a62dc406SDoug Rabson u_short sport; 3768fae3551SRodney W. Grimes char rpcpath[RPCMNT_PATHLEN + 1], dirpath[MAXPATHLEN]; 377e90cdb54SGuido van Rooij int bad = 0, defset, hostset; 378a62dc406SDoug Rabson sigset_t sighup_mask; 3798fae3551SRodney W. Grimes 380a62dc406SDoug Rabson sigemptyset(&sighup_mask); 381a62dc406SDoug Rabson sigaddset(&sighup_mask, SIGHUP); 3828fae3551SRodney W. Grimes saddr = transp->xp_raddr.sin_addr.s_addr; 383a62dc406SDoug Rabson sport = ntohs(transp->xp_raddr.sin_port); 3848fae3551SRodney W. Grimes hp = (struct hostent *)NULL; 3858fae3551SRodney W. Grimes switch (rqstp->rq_proc) { 3868fae3551SRodney W. Grimes case NULLPROC: 3878fae3551SRodney W. Grimes if (!svc_sendreply(transp, xdr_void, (caddr_t)NULL)) 3888fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 3898fae3551SRodney W. Grimes return; 3908fae3551SRodney W. Grimes case RPCMNT_MOUNT: 391a62dc406SDoug Rabson if (sport >= IPPORT_RESERVED && resvport_only) { 3928fae3551SRodney W. Grimes svcerr_weakauth(transp); 3938fae3551SRodney W. Grimes return; 3948fae3551SRodney W. Grimes } 3958fae3551SRodney W. Grimes if (!svc_getargs(transp, xdr_dir, rpcpath)) { 3968fae3551SRodney W. Grimes svcerr_decode(transp); 3978fae3551SRodney W. Grimes return; 3988fae3551SRodney W. Grimes } 3998fae3551SRodney W. Grimes 4008fae3551SRodney W. Grimes /* 4018fae3551SRodney W. Grimes * Get the real pathname and make sure it is a directory 402a62dc406SDoug Rabson * or a regular file if the -r option was specified 403a62dc406SDoug Rabson * and it exists. 4048fae3551SRodney W. Grimes */ 4058fae3551SRodney W. Grimes if (realpath(rpcpath, dirpath) == 0 || 4068fae3551SRodney W. Grimes stat(dirpath, &stb) < 0 || 407a62dc406SDoug Rabson (!S_ISDIR(stb.st_mode) && 408a62dc406SDoug Rabson (dir_only || !S_ISREG(stb.st_mode))) || 4098fae3551SRodney W. Grimes statfs(dirpath, &fsb) < 0) { 4108fae3551SRodney W. Grimes chdir("/"); /* Just in case realpath doesn't */ 4118fae3551SRodney W. Grimes if (debug) 4128fae3551SRodney W. Grimes fprintf(stderr, "stat failed on %s\n", dirpath); 413e90cdb54SGuido van Rooij bad = ENOENT; /* We will send error reply later */ 4148fae3551SRodney W. Grimes } 4158fae3551SRodney W. Grimes 4168fae3551SRodney W. Grimes /* Check in the exports list */ 417a62dc406SDoug Rabson sigprocmask(SIG_BLOCK, &sighup_mask, NULL); 4188fae3551SRodney W. Grimes ep = ex_search(&fsb.f_fsid); 419a62dc406SDoug Rabson hostset = defset = 0; 420a62dc406SDoug Rabson if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset) || 4218fae3551SRodney W. Grimes ((dp = dirp_search(ep->ex_dirl, dirpath)) && 422a62dc406SDoug Rabson chk_host(dp, saddr, &defset, &hostset)) || 4238fae3551SRodney W. Grimes (defset && scan_tree(ep->ex_defdir, saddr) == 0 && 4248fae3551SRodney W. Grimes scan_tree(ep->ex_dirl, saddr) == 0))) { 425e90cdb54SGuido van Rooij if (bad) { 426e90cdb54SGuido van Rooij if (!svc_sendreply(transp, xdr_long, 427e90cdb54SGuido van Rooij (caddr_t)&bad)) 428e90cdb54SGuido van Rooij syslog(LOG_ERR, "Can't send reply"); 429e90cdb54SGuido van Rooij sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); 430e90cdb54SGuido van Rooij return; 431e90cdb54SGuido van Rooij } 432a62dc406SDoug Rabson if (hostset & DP_HOSTSET) 433a62dc406SDoug Rabson fhr.fhr_flag = hostset; 434a62dc406SDoug Rabson else 435a62dc406SDoug Rabson fhr.fhr_flag = defset; 436a62dc406SDoug Rabson fhr.fhr_vers = rqstp->rq_vers; 4378fae3551SRodney W. Grimes /* Get the file handle */ 43887564113SPeter Wemm memset(&fhr.fhr_fh, 0, sizeof(nfsfh_t)); 439a62dc406SDoug Rabson if (getfh(dirpath, (fhandle_t *)&fhr.fhr_fh) < 0) { 4408fae3551SRodney W. Grimes bad = errno; 4418fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't get fh for %s", dirpath); 4428fae3551SRodney W. Grimes if (!svc_sendreply(transp, xdr_long, 4438fae3551SRodney W. Grimes (caddr_t)&bad)) 4448fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 445a62dc406SDoug Rabson sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); 4468fae3551SRodney W. Grimes return; 4478fae3551SRodney W. Grimes } 448a62dc406SDoug Rabson if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&fhr)) 4498fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 4508fae3551SRodney W. Grimes if (hp == NULL) 4518fae3551SRodney W. Grimes hp = gethostbyaddr((caddr_t)&saddr, 4528fae3551SRodney W. Grimes sizeof(saddr), AF_INET); 4538fae3551SRodney W. Grimes if (hp) 4548fae3551SRodney W. Grimes add_mlist(hp->h_name, dirpath); 4558fae3551SRodney W. Grimes else 4568fae3551SRodney W. Grimes add_mlist(inet_ntoa(transp->xp_raddr.sin_addr), 4578fae3551SRodney W. Grimes dirpath); 4588fae3551SRodney W. Grimes if (debug) 4598fae3551SRodney W. Grimes fprintf(stderr,"Mount successfull.\n"); 460e90cdb54SGuido van Rooij } else 4618fae3551SRodney W. Grimes bad = EACCES; 462e90cdb54SGuido van Rooij 463e90cdb54SGuido van Rooij if (bad && !svc_sendreply(transp, xdr_long, (caddr_t)&bad)) 4648fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 465a62dc406SDoug Rabson sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); 4668fae3551SRodney W. Grimes return; 4678fae3551SRodney W. Grimes case RPCMNT_DUMP: 4688fae3551SRodney W. Grimes if (!svc_sendreply(transp, xdr_mlist, (caddr_t)NULL)) 4698fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 4708fae3551SRodney W. Grimes return; 4718fae3551SRodney W. Grimes case RPCMNT_UMOUNT: 472a62dc406SDoug Rabson if (sport >= IPPORT_RESERVED && resvport_only) { 4738fae3551SRodney W. Grimes svcerr_weakauth(transp); 4748fae3551SRodney W. Grimes return; 4758fae3551SRodney W. Grimes } 4768fae3551SRodney W. Grimes if (!svc_getargs(transp, xdr_dir, dirpath)) { 4778fae3551SRodney W. Grimes svcerr_decode(transp); 4788fae3551SRodney W. Grimes return; 4798fae3551SRodney W. Grimes } 4808fae3551SRodney W. Grimes if (!svc_sendreply(transp, xdr_void, (caddr_t)NULL)) 4818fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 4828fae3551SRodney W. Grimes hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 4838fae3551SRodney W. Grimes if (hp) 4848fae3551SRodney W. Grimes del_mlist(hp->h_name, dirpath); 4858fae3551SRodney W. Grimes del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), dirpath); 4868fae3551SRodney W. Grimes return; 4878fae3551SRodney W. Grimes case RPCMNT_UMNTALL: 488a62dc406SDoug Rabson if (sport >= IPPORT_RESERVED && resvport_only) { 4898fae3551SRodney W. Grimes svcerr_weakauth(transp); 4908fae3551SRodney W. Grimes return; 4918fae3551SRodney W. Grimes } 4928fae3551SRodney W. Grimes if (!svc_sendreply(transp, xdr_void, (caddr_t)NULL)) 4938fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 4948fae3551SRodney W. Grimes hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); 4958fae3551SRodney W. Grimes if (hp) 4968fae3551SRodney W. Grimes del_mlist(hp->h_name, (char *)NULL); 4978fae3551SRodney W. Grimes del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), (char *)NULL); 4988fae3551SRodney W. Grimes return; 4998fae3551SRodney W. Grimes case RPCMNT_EXPORT: 5008fae3551SRodney W. Grimes if (!svc_sendreply(transp, xdr_explist, (caddr_t)NULL)) 5018fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't send reply"); 5028fae3551SRodney W. Grimes return; 5038fae3551SRodney W. Grimes default: 5048fae3551SRodney W. Grimes svcerr_noproc(transp); 5058fae3551SRodney W. Grimes return; 5068fae3551SRodney W. Grimes } 5078fae3551SRodney W. Grimes } 5088fae3551SRodney W. Grimes 5098fae3551SRodney W. Grimes /* 5108fae3551SRodney W. Grimes * Xdr conversion for a dirpath string 5118fae3551SRodney W. Grimes */ 5128fae3551SRodney W. Grimes int 5138fae3551SRodney W. Grimes xdr_dir(xdrsp, dirp) 5148fae3551SRodney W. Grimes XDR *xdrsp; 5158fae3551SRodney W. Grimes char *dirp; 5168fae3551SRodney W. Grimes { 5178fae3551SRodney W. Grimes return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 5188fae3551SRodney W. Grimes } 5198fae3551SRodney W. Grimes 5208fae3551SRodney W. Grimes /* 521a62dc406SDoug Rabson * Xdr routine to generate file handle reply 5228fae3551SRodney W. Grimes */ 5238fae3551SRodney W. Grimes int 524a62dc406SDoug Rabson xdr_fhs(xdrsp, cp) 5258fae3551SRodney W. Grimes XDR *xdrsp; 526a62dc406SDoug Rabson caddr_t cp; 5278fae3551SRodney W. Grimes { 528a62dc406SDoug Rabson register struct fhreturn *fhrp = (struct fhreturn *)cp; 529a62dc406SDoug Rabson u_long ok = 0, len, auth; 5308fae3551SRodney W. Grimes 5318fae3551SRodney W. Grimes if (!xdr_long(xdrsp, &ok)) 5328fae3551SRodney W. Grimes return (0); 533a62dc406SDoug Rabson switch (fhrp->fhr_vers) { 534a62dc406SDoug Rabson case 1: 535a62dc406SDoug Rabson return (xdr_opaque(xdrsp, (caddr_t)&fhrp->fhr_fh, NFSX_V2FH)); 536a62dc406SDoug Rabson case 3: 537a62dc406SDoug Rabson len = NFSX_V3FH; 538a62dc406SDoug Rabson if (!xdr_long(xdrsp, &len)) 539a62dc406SDoug Rabson return (0); 540a62dc406SDoug Rabson if (!xdr_opaque(xdrsp, (caddr_t)&fhrp->fhr_fh, len)) 541a62dc406SDoug Rabson return (0); 542a62dc406SDoug Rabson if (fhrp->fhr_flag & DP_KERB) 543a62dc406SDoug Rabson auth = RPCAUTH_KERB4; 544a62dc406SDoug Rabson else 545a62dc406SDoug Rabson auth = RPCAUTH_UNIX; 546a62dc406SDoug Rabson len = 1; 547a62dc406SDoug Rabson if (!xdr_long(xdrsp, &len)) 548a62dc406SDoug Rabson return (0); 549a62dc406SDoug Rabson return (xdr_long(xdrsp, &auth)); 550a62dc406SDoug Rabson }; 551a62dc406SDoug Rabson return (0); 5528fae3551SRodney W. Grimes } 5538fae3551SRodney W. Grimes 5548fae3551SRodney W. Grimes int 5558fae3551SRodney W. Grimes xdr_mlist(xdrsp, cp) 5568fae3551SRodney W. Grimes XDR *xdrsp; 5578fae3551SRodney W. Grimes caddr_t cp; 5588fae3551SRodney W. Grimes { 5598fae3551SRodney W. Grimes struct mountlist *mlp; 5608fae3551SRodney W. Grimes int true = 1; 5618fae3551SRodney W. Grimes int false = 0; 5628fae3551SRodney W. Grimes char *strp; 5638fae3551SRodney W. Grimes 5648fae3551SRodney W. Grimes mlp = mlhead; 5658fae3551SRodney W. Grimes while (mlp) { 5668fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &true)) 5678fae3551SRodney W. Grimes return (0); 5688fae3551SRodney W. Grimes strp = &mlp->ml_host[0]; 5698fae3551SRodney W. Grimes if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) 5708fae3551SRodney W. Grimes return (0); 5718fae3551SRodney W. Grimes strp = &mlp->ml_dirp[0]; 5728fae3551SRodney W. Grimes if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) 5738fae3551SRodney W. Grimes return (0); 5748fae3551SRodney W. Grimes mlp = mlp->ml_next; 5758fae3551SRodney W. Grimes } 5768fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &false)) 5778fae3551SRodney W. Grimes return (0); 5788fae3551SRodney W. Grimes return (1); 5798fae3551SRodney W. Grimes } 5808fae3551SRodney W. Grimes 5818fae3551SRodney W. Grimes /* 5828fae3551SRodney W. Grimes * Xdr conversion for export list 5838fae3551SRodney W. Grimes */ 5848fae3551SRodney W. Grimes int 5858fae3551SRodney W. Grimes xdr_explist(xdrsp, cp) 5868fae3551SRodney W. Grimes XDR *xdrsp; 5878fae3551SRodney W. Grimes caddr_t cp; 5888fae3551SRodney W. Grimes { 5898fae3551SRodney W. Grimes struct exportlist *ep; 5908fae3551SRodney W. Grimes int false = 0; 591a62dc406SDoug Rabson int putdef; 592a62dc406SDoug Rabson sigset_t sighup_mask; 5938fae3551SRodney W. Grimes 594a62dc406SDoug Rabson sigemptyset(&sighup_mask); 595a62dc406SDoug Rabson sigaddset(&sighup_mask, SIGHUP); 596a62dc406SDoug Rabson sigprocmask(SIG_BLOCK, &sighup_mask, NULL); 5978fae3551SRodney W. Grimes ep = exphead; 5988fae3551SRodney W. Grimes while (ep) { 5998fae3551SRodney W. Grimes putdef = 0; 6008fae3551SRodney W. Grimes if (put_exlist(ep->ex_dirl, xdrsp, ep->ex_defdir, &putdef)) 6018fae3551SRodney W. Grimes goto errout; 6028fae3551SRodney W. Grimes if (ep->ex_defdir && putdef == 0 && 6038fae3551SRodney W. Grimes put_exlist(ep->ex_defdir, xdrsp, (struct dirlist *)NULL, 6048fae3551SRodney W. Grimes &putdef)) 6058fae3551SRodney W. Grimes goto errout; 6068fae3551SRodney W. Grimes ep = ep->ex_next; 6078fae3551SRodney W. Grimes } 608a62dc406SDoug Rabson sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); 6098fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &false)) 6108fae3551SRodney W. Grimes return (0); 6118fae3551SRodney W. Grimes return (1); 6128fae3551SRodney W. Grimes errout: 613a62dc406SDoug Rabson sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); 6148fae3551SRodney W. Grimes return (0); 6158fae3551SRodney W. Grimes } 6168fae3551SRodney W. Grimes 6178fae3551SRodney W. Grimes /* 6188fae3551SRodney W. Grimes * Called from xdr_explist() to traverse the tree and export the 6198fae3551SRodney W. Grimes * directory paths. 6208fae3551SRodney W. Grimes */ 6218fae3551SRodney W. Grimes int 6228fae3551SRodney W. Grimes put_exlist(dp, xdrsp, adp, putdefp) 6238fae3551SRodney W. Grimes struct dirlist *dp; 6248fae3551SRodney W. Grimes XDR *xdrsp; 6258fae3551SRodney W. Grimes struct dirlist *adp; 6268fae3551SRodney W. Grimes int *putdefp; 6278fae3551SRodney W. Grimes { 6288fae3551SRodney W. Grimes struct grouplist *grp; 6298fae3551SRodney W. Grimes struct hostlist *hp; 6308fae3551SRodney W. Grimes int true = 1; 6318fae3551SRodney W. Grimes int false = 0; 6328fae3551SRodney W. Grimes int gotalldir = 0; 6338fae3551SRodney W. Grimes char *strp; 6348fae3551SRodney W. Grimes 6358fae3551SRodney W. Grimes if (dp) { 6368fae3551SRodney W. Grimes if (put_exlist(dp->dp_left, xdrsp, adp, putdefp)) 6378fae3551SRodney W. Grimes return (1); 6388fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &true)) 6398fae3551SRodney W. Grimes return (1); 6408fae3551SRodney W. Grimes strp = dp->dp_dirp; 6418fae3551SRodney W. Grimes if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) 6428fae3551SRodney W. Grimes return (1); 6438fae3551SRodney W. Grimes if (adp && !strcmp(dp->dp_dirp, adp->dp_dirp)) { 6448fae3551SRodney W. Grimes gotalldir = 1; 6458fae3551SRodney W. Grimes *putdefp = 1; 6468fae3551SRodney W. Grimes } 6478fae3551SRodney W. Grimes if ((dp->dp_flag & DP_DEFSET) == 0 && 6488fae3551SRodney W. Grimes (gotalldir == 0 || (adp->dp_flag & DP_DEFSET) == 0)) { 6498fae3551SRodney W. Grimes hp = dp->dp_hosts; 6508fae3551SRodney W. Grimes while (hp) { 6518fae3551SRodney W. Grimes grp = hp->ht_grp; 6528fae3551SRodney W. Grimes if (grp->gr_type == GT_HOST) { 6538fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &true)) 6548fae3551SRodney W. Grimes return (1); 6558fae3551SRodney W. Grimes strp = grp->gr_ptr.gt_hostent->h_name; 6568fae3551SRodney W. Grimes if (!xdr_string(xdrsp, &strp, 6578fae3551SRodney W. Grimes RPCMNT_NAMELEN)) 6588fae3551SRodney W. Grimes return (1); 6598fae3551SRodney W. Grimes } else if (grp->gr_type == GT_NET) { 6608fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &true)) 6618fae3551SRodney W. Grimes return (1); 6628fae3551SRodney W. Grimes strp = grp->gr_ptr.gt_net.nt_name; 6638fae3551SRodney W. Grimes if (!xdr_string(xdrsp, &strp, 6648fae3551SRodney W. Grimes RPCMNT_NAMELEN)) 6658fae3551SRodney W. Grimes return (1); 6668fae3551SRodney W. Grimes } 6678fae3551SRodney W. Grimes hp = hp->ht_next; 6688fae3551SRodney W. Grimes if (gotalldir && hp == (struct hostlist *)NULL) { 6698fae3551SRodney W. Grimes hp = adp->dp_hosts; 6708fae3551SRodney W. Grimes gotalldir = 0; 6718fae3551SRodney W. Grimes } 6728fae3551SRodney W. Grimes } 6738fae3551SRodney W. Grimes } 6748fae3551SRodney W. Grimes if (!xdr_bool(xdrsp, &false)) 6758fae3551SRodney W. Grimes return (1); 6768fae3551SRodney W. Grimes if (put_exlist(dp->dp_right, xdrsp, adp, putdefp)) 6778fae3551SRodney W. Grimes return (1); 6788fae3551SRodney W. Grimes } 6798fae3551SRodney W. Grimes return (0); 6808fae3551SRodney W. Grimes } 6818fae3551SRodney W. Grimes 6828fae3551SRodney W. Grimes #define LINESIZ 10240 6838fae3551SRodney W. Grimes char line[LINESIZ]; 6848fae3551SRodney W. Grimes FILE *exp_file; 6858fae3551SRodney W. Grimes 6868fae3551SRodney W. Grimes /* 6878fae3551SRodney W. Grimes * Get the export list 6888fae3551SRodney W. Grimes */ 6898fae3551SRodney W. Grimes void 6908fae3551SRodney W. Grimes get_exportlist() 6918fae3551SRodney W. Grimes { 6928fae3551SRodney W. Grimes struct exportlist *ep, *ep2; 6938fae3551SRodney W. Grimes struct grouplist *grp, *tgrp; 6948fae3551SRodney W. Grimes struct exportlist **epp; 6958fae3551SRodney W. Grimes struct dirlist *dirhead; 6968fae3551SRodney W. Grimes struct statfs fsb, *fsp; 6978fae3551SRodney W. Grimes struct hostent *hpe; 6988fae3551SRodney W. Grimes struct ucred anon; 6998fae3551SRodney W. Grimes char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc; 7008fae3551SRodney W. Grimes int len, has_host, exflags, got_nondir, dirplen, num, i, netgrp; 7018fae3551SRodney W. Grimes 7028fae3551SRodney W. Grimes /* 7038fae3551SRodney W. Grimes * First, get rid of the old list 7048fae3551SRodney W. Grimes */ 7058fae3551SRodney W. Grimes ep = exphead; 7068fae3551SRodney W. Grimes while (ep) { 7078fae3551SRodney W. Grimes ep2 = ep; 7088fae3551SRodney W. Grimes ep = ep->ex_next; 7098fae3551SRodney W. Grimes free_exp(ep2); 7108fae3551SRodney W. Grimes } 7118fae3551SRodney W. Grimes exphead = (struct exportlist *)NULL; 7128fae3551SRodney W. Grimes 7138fae3551SRodney W. Grimes grp = grphead; 7148fae3551SRodney W. Grimes while (grp) { 7158fae3551SRodney W. Grimes tgrp = grp; 7168fae3551SRodney W. Grimes grp = grp->gr_next; 7178fae3551SRodney W. Grimes free_grp(tgrp); 7188fae3551SRodney W. Grimes } 7198fae3551SRodney W. Grimes grphead = (struct grouplist *)NULL; 7208fae3551SRodney W. Grimes 7218fae3551SRodney W. Grimes /* 7228fae3551SRodney W. Grimes * And delete exports that are in the kernel for all local 7238fae3551SRodney W. Grimes * file systems. 7248fae3551SRodney W. Grimes * XXX: Should know how to handle all local exportable file systems 72587564113SPeter Wemm * instead of just "ufs". 7268fae3551SRodney W. Grimes */ 7278fae3551SRodney W. Grimes num = getmntinfo(&fsp, MNT_NOWAIT); 7288fae3551SRodney W. Grimes for (i = 0; i < num; i++) { 7298fae3551SRodney W. Grimes union { 7308fae3551SRodney W. Grimes struct ufs_args ua; 7318fae3551SRodney W. Grimes struct iso_args ia; 7328fae3551SRodney W. Grimes struct mfs_args ma; 733a62dc406SDoug Rabson struct msdosfs_args da; 734a62dc406SDoug Rabson } targs; 735a62dc406SDoug Rabson 73687564113SPeter Wemm if (!strcmp(fsp->f_fstypename, "mfs") || 73787564113SPeter Wemm !strcmp(fsp->f_fstypename, "ufs") || 73887564113SPeter Wemm !strcmp(fsp->f_fstypename, "msdos") || 73987564113SPeter Wemm !strcmp(fsp->f_fstypename, "cd9660")) { 740a62dc406SDoug Rabson targs.ua.fspec = NULL; 741a62dc406SDoug Rabson targs.ua.export.ex_flags = MNT_DELEXPORT; 742a62dc406SDoug Rabson if (mount(fsp->f_fstypename, fsp->f_mntonname, 7438fae3551SRodney W. Grimes fsp->f_flags | MNT_UPDATE, 7448fae3551SRodney W. Grimes (caddr_t)&targs) < 0) 7458fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't delete exports for %s", 7468fae3551SRodney W. Grimes fsp->f_mntonname); 7478fae3551SRodney W. Grimes } 7488fae3551SRodney W. Grimes fsp++; 7498fae3551SRodney W. Grimes } 7508fae3551SRodney W. Grimes 7518fae3551SRodney W. Grimes /* 7528fae3551SRodney W. Grimes * Read in the exports file and build the list, calling 7538fae3551SRodney W. Grimes * mount() as we go along to push the export rules into the kernel. 7548fae3551SRodney W. Grimes */ 7558fae3551SRodney W. Grimes if ((exp_file = fopen(exname, "r")) == NULL) { 7568fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't open %s", exname); 7578fae3551SRodney W. Grimes exit(2); 7588fae3551SRodney W. Grimes } 7598fae3551SRodney W. Grimes dirhead = (struct dirlist *)NULL; 7608fae3551SRodney W. Grimes while (get_line()) { 7618fae3551SRodney W. Grimes if (debug) 7628fae3551SRodney W. Grimes fprintf(stderr,"Got line %s\n",line); 7638fae3551SRodney W. Grimes cp = line; 7648fae3551SRodney W. Grimes nextfield(&cp, &endcp); 7658fae3551SRodney W. Grimes if (*cp == '#') 7668fae3551SRodney W. Grimes goto nextline; 7678fae3551SRodney W. Grimes 7688fae3551SRodney W. Grimes /* 7698fae3551SRodney W. Grimes * Set defaults. 7708fae3551SRodney W. Grimes */ 7718fae3551SRodney W. Grimes has_host = FALSE; 7728fae3551SRodney W. Grimes anon = def_anon; 7738fae3551SRodney W. Grimes exflags = MNT_EXPORTED; 7748fae3551SRodney W. Grimes got_nondir = 0; 7758fae3551SRodney W. Grimes opt_flags = 0; 7768fae3551SRodney W. Grimes ep = (struct exportlist *)NULL; 7778fae3551SRodney W. Grimes 7788fae3551SRodney W. Grimes /* 7798fae3551SRodney W. Grimes * Create new exports list entry 7808fae3551SRodney W. Grimes */ 7818fae3551SRodney W. Grimes len = endcp-cp; 7828fae3551SRodney W. Grimes tgrp = grp = get_grp(); 7838fae3551SRodney W. Grimes while (len > 0) { 7848fae3551SRodney W. Grimes if (len > RPCMNT_NAMELEN) { 7858fae3551SRodney W. Grimes getexp_err(ep, tgrp); 7868fae3551SRodney W. Grimes goto nextline; 7878fae3551SRodney W. Grimes } 7888fae3551SRodney W. Grimes if (*cp == '-') { 7898fae3551SRodney W. Grimes if (ep == (struct exportlist *)NULL) { 7908fae3551SRodney W. Grimes getexp_err(ep, tgrp); 7918fae3551SRodney W. Grimes goto nextline; 7928fae3551SRodney W. Grimes } 7938fae3551SRodney W. Grimes if (debug) 7948fae3551SRodney W. Grimes fprintf(stderr, "doing opt %s\n", cp); 7958fae3551SRodney W. Grimes got_nondir = 1; 7968fae3551SRodney W. Grimes if (do_opt(&cp, &endcp, ep, grp, &has_host, 7978fae3551SRodney W. Grimes &exflags, &anon)) { 7988fae3551SRodney W. Grimes getexp_err(ep, tgrp); 7998fae3551SRodney W. Grimes goto nextline; 8008fae3551SRodney W. Grimes } 8018fae3551SRodney W. Grimes } else if (*cp == '/') { 8028fae3551SRodney W. Grimes savedc = *endcp; 8038fae3551SRodney W. Grimes *endcp = '\0'; 8048fae3551SRodney W. Grimes if (check_dirpath(cp) && 8058fae3551SRodney W. Grimes statfs(cp, &fsb) >= 0) { 8068fae3551SRodney W. Grimes if (got_nondir) { 8078fae3551SRodney W. Grimes syslog(LOG_ERR, "Dirs must be first"); 8088fae3551SRodney W. Grimes getexp_err(ep, tgrp); 8098fae3551SRodney W. Grimes goto nextline; 8108fae3551SRodney W. Grimes } 8118fae3551SRodney W. Grimes if (ep) { 8128fae3551SRodney W. Grimes if (ep->ex_fs.val[0] != fsb.f_fsid.val[0] || 8138fae3551SRodney W. Grimes ep->ex_fs.val[1] != fsb.f_fsid.val[1]) { 8148fae3551SRodney W. Grimes getexp_err(ep, tgrp); 8158fae3551SRodney W. Grimes goto nextline; 8168fae3551SRodney W. Grimes } 8178fae3551SRodney W. Grimes } else { 8188fae3551SRodney W. Grimes /* 8198fae3551SRodney W. Grimes * See if this directory is already 8208fae3551SRodney W. Grimes * in the list. 8218fae3551SRodney W. Grimes */ 8228fae3551SRodney W. Grimes ep = ex_search(&fsb.f_fsid); 8238fae3551SRodney W. Grimes if (ep == (struct exportlist *)NULL) { 8248fae3551SRodney W. Grimes ep = get_exp(); 8258fae3551SRodney W. Grimes ep->ex_fs = fsb.f_fsid; 8268fae3551SRodney W. Grimes ep->ex_fsdir = (char *) 8278fae3551SRodney W. Grimes malloc(strlen(fsb.f_mntonname) + 1); 8288fae3551SRodney W. Grimes if (ep->ex_fsdir) 8298fae3551SRodney W. Grimes strcpy(ep->ex_fsdir, 8308fae3551SRodney W. Grimes fsb.f_mntonname); 8318fae3551SRodney W. Grimes else 8328fae3551SRodney W. Grimes out_of_mem(); 8338fae3551SRodney W. Grimes if (debug) 8348fae3551SRodney W. Grimes fprintf(stderr, 8358fae3551SRodney W. Grimes "Making new ep fs=0x%x,0x%x\n", 8368fae3551SRodney W. Grimes fsb.f_fsid.val[0], 8378fae3551SRodney W. Grimes fsb.f_fsid.val[1]); 8388fae3551SRodney W. Grimes } else if (debug) 8398fae3551SRodney W. Grimes fprintf(stderr, 8408fae3551SRodney W. Grimes "Found ep fs=0x%x,0x%x\n", 8418fae3551SRodney W. Grimes fsb.f_fsid.val[0], 8428fae3551SRodney W. Grimes fsb.f_fsid.val[1]); 8438fae3551SRodney W. Grimes } 8448fae3551SRodney W. Grimes 8458fae3551SRodney W. Grimes /* 8468fae3551SRodney W. Grimes * Add dirpath to export mount point. 8478fae3551SRodney W. Grimes */ 8488fae3551SRodney W. Grimes dirp = add_expdir(&dirhead, cp, len); 8498fae3551SRodney W. Grimes dirplen = len; 8508fae3551SRodney W. Grimes } else { 8518fae3551SRodney W. Grimes getexp_err(ep, tgrp); 8528fae3551SRodney W. Grimes goto nextline; 8538fae3551SRodney W. Grimes } 8548fae3551SRodney W. Grimes *endcp = savedc; 8558fae3551SRodney W. Grimes } else { 8568fae3551SRodney W. Grimes savedc = *endcp; 8578fae3551SRodney W. Grimes *endcp = '\0'; 8588fae3551SRodney W. Grimes got_nondir = 1; 8598fae3551SRodney W. Grimes if (ep == (struct exportlist *)NULL) { 8608fae3551SRodney W. Grimes getexp_err(ep, tgrp); 8618fae3551SRodney W. Grimes goto nextline; 8628fae3551SRodney W. Grimes } 8638fae3551SRodney W. Grimes 8648fae3551SRodney W. Grimes /* 8658fae3551SRodney W. Grimes * Get the host or netgroup. 8668fae3551SRodney W. Grimes */ 8678fae3551SRodney W. Grimes setnetgrent(cp); 8688fae3551SRodney W. Grimes netgrp = getnetgrent(&hst, &usr, &dom); 8698fae3551SRodney W. Grimes do { 8708fae3551SRodney W. Grimes if (has_host) { 8718fae3551SRodney W. Grimes grp->gr_next = get_grp(); 8728fae3551SRodney W. Grimes grp = grp->gr_next; 8738fae3551SRodney W. Grimes } 8748fae3551SRodney W. Grimes if (netgrp) { 8758b5a6d67SBill Paul if (get_host(hst, grp, tgrp)) { 8768fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad netgroup %s", cp); 8778fae3551SRodney W. Grimes getexp_err(ep, tgrp); 878a62dc406SDoug Rabson endnetgrent(); 8798fae3551SRodney W. Grimes goto nextline; 8808fae3551SRodney W. Grimes } 8818b5a6d67SBill Paul } else if (get_host(cp, grp, tgrp)) { 8828fae3551SRodney W. Grimes getexp_err(ep, tgrp); 8838fae3551SRodney W. Grimes goto nextline; 8848fae3551SRodney W. Grimes } 8858fae3551SRodney W. Grimes has_host = TRUE; 8868fae3551SRodney W. Grimes } while (netgrp && getnetgrent(&hst, &usr, &dom)); 8878fae3551SRodney W. Grimes endnetgrent(); 8888fae3551SRodney W. Grimes *endcp = savedc; 8898fae3551SRodney W. Grimes } 8908fae3551SRodney W. Grimes cp = endcp; 8918fae3551SRodney W. Grimes nextfield(&cp, &endcp); 8928fae3551SRodney W. Grimes len = endcp - cp; 8938fae3551SRodney W. Grimes } 8948fae3551SRodney W. Grimes if (check_options(dirhead)) { 8958fae3551SRodney W. Grimes getexp_err(ep, tgrp); 8968fae3551SRodney W. Grimes goto nextline; 8978fae3551SRodney W. Grimes } 8988fae3551SRodney W. Grimes if (!has_host) { 8998fae3551SRodney W. Grimes grp->gr_type = GT_HOST; 9008fae3551SRodney W. Grimes if (debug) 9018fae3551SRodney W. Grimes fprintf(stderr,"Adding a default entry\n"); 9028fae3551SRodney W. Grimes /* add a default group and make the grp list NULL */ 9038fae3551SRodney W. Grimes hpe = (struct hostent *)malloc(sizeof(struct hostent)); 9048fae3551SRodney W. Grimes if (hpe == (struct hostent *)NULL) 9058fae3551SRodney W. Grimes out_of_mem(); 9061cc09cceSJoerg Wunsch hpe->h_name = strdup("Default"); 9078fae3551SRodney W. Grimes hpe->h_addrtype = AF_INET; 9088fae3551SRodney W. Grimes hpe->h_length = sizeof (u_long); 9098fae3551SRodney W. Grimes hpe->h_addr_list = (char **)NULL; 9108fae3551SRodney W. Grimes grp->gr_ptr.gt_hostent = hpe; 9118fae3551SRodney W. Grimes 9128fae3551SRodney W. Grimes /* 9138fae3551SRodney W. Grimes * Don't allow a network export coincide with a list of 9148fae3551SRodney W. Grimes * host(s) on the same line. 9158fae3551SRodney W. Grimes */ 9168fae3551SRodney W. Grimes } else if ((opt_flags & OP_NET) && tgrp->gr_next) { 9178fae3551SRodney W. Grimes getexp_err(ep, tgrp); 9188fae3551SRodney W. Grimes goto nextline; 9198fae3551SRodney W. Grimes } 9208fae3551SRodney W. Grimes 9218fae3551SRodney W. Grimes /* 9228fae3551SRodney W. Grimes * Loop through hosts, pushing the exports into the kernel. 9238fae3551SRodney W. Grimes * After loop, tgrp points to the start of the list and 9248fae3551SRodney W. Grimes * grp points to the last entry in the list. 9258fae3551SRodney W. Grimes */ 9268fae3551SRodney W. Grimes grp = tgrp; 9278fae3551SRodney W. Grimes do { 9288fae3551SRodney W. Grimes if (do_mount(ep, grp, exflags, &anon, dirp, 9298fae3551SRodney W. Grimes dirplen, &fsb)) { 9308fae3551SRodney W. Grimes getexp_err(ep, tgrp); 9318fae3551SRodney W. Grimes goto nextline; 9328fae3551SRodney W. Grimes } 9338fae3551SRodney W. Grimes } while (grp->gr_next && (grp = grp->gr_next)); 9348fae3551SRodney W. Grimes 9358fae3551SRodney W. Grimes /* 9368fae3551SRodney W. Grimes * Success. Update the data structures. 9378fae3551SRodney W. Grimes */ 9388fae3551SRodney W. Grimes if (has_host) { 939a62dc406SDoug Rabson hang_dirp(dirhead, tgrp, ep, opt_flags); 9408fae3551SRodney W. Grimes grp->gr_next = grphead; 9418fae3551SRodney W. Grimes grphead = tgrp; 9428fae3551SRodney W. Grimes } else { 9438fae3551SRodney W. Grimes hang_dirp(dirhead, (struct grouplist *)NULL, ep, 944a62dc406SDoug Rabson opt_flags); 9458fae3551SRodney W. Grimes free_grp(grp); 9468fae3551SRodney W. Grimes } 9478fae3551SRodney W. Grimes dirhead = (struct dirlist *)NULL; 9488fae3551SRodney W. Grimes if ((ep->ex_flag & EX_LINKED) == 0) { 9498fae3551SRodney W. Grimes ep2 = exphead; 9508fae3551SRodney W. Grimes epp = &exphead; 9518fae3551SRodney W. Grimes 9528fae3551SRodney W. Grimes /* 9538fae3551SRodney W. Grimes * Insert in the list in alphabetical order. 9548fae3551SRodney W. Grimes */ 9558fae3551SRodney W. Grimes while (ep2 && strcmp(ep2->ex_fsdir, ep->ex_fsdir) < 0) { 9568fae3551SRodney W. Grimes epp = &ep2->ex_next; 9578fae3551SRodney W. Grimes ep2 = ep2->ex_next; 9588fae3551SRodney W. Grimes } 9598fae3551SRodney W. Grimes if (ep2) 9608fae3551SRodney W. Grimes ep->ex_next = ep2; 9618fae3551SRodney W. Grimes *epp = ep; 9628fae3551SRodney W. Grimes ep->ex_flag |= EX_LINKED; 9638fae3551SRodney W. Grimes } 9648fae3551SRodney W. Grimes nextline: 9658fae3551SRodney W. Grimes if (dirhead) { 9668fae3551SRodney W. Grimes free_dir(dirhead); 9678fae3551SRodney W. Grimes dirhead = (struct dirlist *)NULL; 9688fae3551SRodney W. Grimes } 9698fae3551SRodney W. Grimes } 9708fae3551SRodney W. Grimes fclose(exp_file); 9718fae3551SRodney W. Grimes } 9728fae3551SRodney W. Grimes 9738fae3551SRodney W. Grimes /* 9748fae3551SRodney W. Grimes * Allocate an export list element 9758fae3551SRodney W. Grimes */ 9768fae3551SRodney W. Grimes struct exportlist * 9778fae3551SRodney W. Grimes get_exp() 9788fae3551SRodney W. Grimes { 9798fae3551SRodney W. Grimes struct exportlist *ep; 9808fae3551SRodney W. Grimes 9818fae3551SRodney W. Grimes ep = (struct exportlist *)malloc(sizeof (struct exportlist)); 9828fae3551SRodney W. Grimes if (ep == (struct exportlist *)NULL) 9838fae3551SRodney W. Grimes out_of_mem(); 98487564113SPeter Wemm memset(ep, 0, sizeof(struct exportlist)); 9858fae3551SRodney W. Grimes return (ep); 9868fae3551SRodney W. Grimes } 9878fae3551SRodney W. Grimes 9888fae3551SRodney W. Grimes /* 9898fae3551SRodney W. Grimes * Allocate a group list element 9908fae3551SRodney W. Grimes */ 9918fae3551SRodney W. Grimes struct grouplist * 9928fae3551SRodney W. Grimes get_grp() 9938fae3551SRodney W. Grimes { 9948fae3551SRodney W. Grimes struct grouplist *gp; 9958fae3551SRodney W. Grimes 9968fae3551SRodney W. Grimes gp = (struct grouplist *)malloc(sizeof (struct grouplist)); 9978fae3551SRodney W. Grimes if (gp == (struct grouplist *)NULL) 9988fae3551SRodney W. Grimes out_of_mem(); 99987564113SPeter Wemm memset(gp, 0, sizeof(struct grouplist)); 10008fae3551SRodney W. Grimes return (gp); 10018fae3551SRodney W. Grimes } 10028fae3551SRodney W. Grimes 10038fae3551SRodney W. Grimes /* 10048fae3551SRodney W. Grimes * Clean up upon an error in get_exportlist(). 10058fae3551SRodney W. Grimes */ 10068fae3551SRodney W. Grimes void 10078fae3551SRodney W. Grimes getexp_err(ep, grp) 10088fae3551SRodney W. Grimes struct exportlist *ep; 10098fae3551SRodney W. Grimes struct grouplist *grp; 10108fae3551SRodney W. Grimes { 10118fae3551SRodney W. Grimes struct grouplist *tgrp; 10128fae3551SRodney W. Grimes 10138fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad exports list line %s", line); 10148fae3551SRodney W. Grimes if (ep && (ep->ex_flag & EX_LINKED) == 0) 10158fae3551SRodney W. Grimes free_exp(ep); 10168fae3551SRodney W. Grimes while (grp) { 10178fae3551SRodney W. Grimes tgrp = grp; 10188fae3551SRodney W. Grimes grp = grp->gr_next; 10198fae3551SRodney W. Grimes free_grp(tgrp); 10208fae3551SRodney W. Grimes } 10218fae3551SRodney W. Grimes } 10228fae3551SRodney W. Grimes 10238fae3551SRodney W. Grimes /* 10248fae3551SRodney W. Grimes * Search the export list for a matching fs. 10258fae3551SRodney W. Grimes */ 10268fae3551SRodney W. Grimes struct exportlist * 10278fae3551SRodney W. Grimes ex_search(fsid) 10288fae3551SRodney W. Grimes fsid_t *fsid; 10298fae3551SRodney W. Grimes { 10308fae3551SRodney W. Grimes struct exportlist *ep; 10318fae3551SRodney W. Grimes 10328fae3551SRodney W. Grimes ep = exphead; 10338fae3551SRodney W. Grimes while (ep) { 10348fae3551SRodney W. Grimes if (ep->ex_fs.val[0] == fsid->val[0] && 10358fae3551SRodney W. Grimes ep->ex_fs.val[1] == fsid->val[1]) 10368fae3551SRodney W. Grimes return (ep); 10378fae3551SRodney W. Grimes ep = ep->ex_next; 10388fae3551SRodney W. Grimes } 10398fae3551SRodney W. Grimes return (ep); 10408fae3551SRodney W. Grimes } 10418fae3551SRodney W. Grimes 10428fae3551SRodney W. Grimes /* 10438fae3551SRodney W. Grimes * Add a directory path to the list. 10448fae3551SRodney W. Grimes */ 10458fae3551SRodney W. Grimes char * 10468fae3551SRodney W. Grimes add_expdir(dpp, cp, len) 10478fae3551SRodney W. Grimes struct dirlist **dpp; 10488fae3551SRodney W. Grimes char *cp; 10498fae3551SRodney W. Grimes int len; 10508fae3551SRodney W. Grimes { 10518fae3551SRodney W. Grimes struct dirlist *dp; 10528fae3551SRodney W. Grimes 10538fae3551SRodney W. Grimes dp = (struct dirlist *)malloc(sizeof (struct dirlist) + len); 10548fae3551SRodney W. Grimes dp->dp_left = *dpp; 10558fae3551SRodney W. Grimes dp->dp_right = (struct dirlist *)NULL; 10568fae3551SRodney W. Grimes dp->dp_flag = 0; 10578fae3551SRodney W. Grimes dp->dp_hosts = (struct hostlist *)NULL; 10588fae3551SRodney W. Grimes strcpy(dp->dp_dirp, cp); 10598fae3551SRodney W. Grimes *dpp = dp; 10608fae3551SRodney W. Grimes return (dp->dp_dirp); 10618fae3551SRodney W. Grimes } 10628fae3551SRodney W. Grimes 10638fae3551SRodney W. Grimes /* 10648fae3551SRodney W. Grimes * Hang the dir list element off the dirpath binary tree as required 10658fae3551SRodney W. Grimes * and update the entry for host. 10668fae3551SRodney W. Grimes */ 10678fae3551SRodney W. Grimes void 1068a62dc406SDoug Rabson hang_dirp(dp, grp, ep, flags) 10698fae3551SRodney W. Grimes struct dirlist *dp; 10708fae3551SRodney W. Grimes struct grouplist *grp; 10718fae3551SRodney W. Grimes struct exportlist *ep; 1072a62dc406SDoug Rabson int flags; 10738fae3551SRodney W. Grimes { 10748fae3551SRodney W. Grimes struct hostlist *hp; 10758fae3551SRodney W. Grimes struct dirlist *dp2; 10768fae3551SRodney W. Grimes 1077a62dc406SDoug Rabson if (flags & OP_ALLDIRS) { 10788fae3551SRodney W. Grimes if (ep->ex_defdir) 10798fae3551SRodney W. Grimes free((caddr_t)dp); 10808fae3551SRodney W. Grimes else 10818fae3551SRodney W. Grimes ep->ex_defdir = dp; 1082a62dc406SDoug Rabson if (grp == (struct grouplist *)NULL) { 10838fae3551SRodney W. Grimes ep->ex_defdir->dp_flag |= DP_DEFSET; 1084a62dc406SDoug Rabson if (flags & OP_KERB) 1085a62dc406SDoug Rabson ep->ex_defdir->dp_flag |= DP_KERB; 1086a62dc406SDoug Rabson } else while (grp) { 10878fae3551SRodney W. Grimes hp = get_ht(); 1088a62dc406SDoug Rabson if (flags & OP_KERB) 1089a62dc406SDoug Rabson hp->ht_flag |= DP_KERB; 10908fae3551SRodney W. Grimes hp->ht_grp = grp; 10918fae3551SRodney W. Grimes hp->ht_next = ep->ex_defdir->dp_hosts; 10928fae3551SRodney W. Grimes ep->ex_defdir->dp_hosts = hp; 10938fae3551SRodney W. Grimes grp = grp->gr_next; 10948fae3551SRodney W. Grimes } 10958fae3551SRodney W. Grimes } else { 10968fae3551SRodney W. Grimes 10978fae3551SRodney W. Grimes /* 10988fae3551SRodney W. Grimes * Loop throught the directories adding them to the tree. 10998fae3551SRodney W. Grimes */ 11008fae3551SRodney W. Grimes while (dp) { 11018fae3551SRodney W. Grimes dp2 = dp->dp_left; 1102a62dc406SDoug Rabson add_dlist(&ep->ex_dirl, dp, grp, flags); 11038fae3551SRodney W. Grimes dp = dp2; 11048fae3551SRodney W. Grimes } 11058fae3551SRodney W. Grimes } 11068fae3551SRodney W. Grimes } 11078fae3551SRodney W. Grimes 11088fae3551SRodney W. Grimes /* 11098fae3551SRodney W. Grimes * Traverse the binary tree either updating a node that is already there 11108fae3551SRodney W. Grimes * for the new directory or adding the new node. 11118fae3551SRodney W. Grimes */ 11128fae3551SRodney W. Grimes void 1113a62dc406SDoug Rabson add_dlist(dpp, newdp, grp, flags) 11148fae3551SRodney W. Grimes struct dirlist **dpp; 11158fae3551SRodney W. Grimes struct dirlist *newdp; 11168fae3551SRodney W. Grimes struct grouplist *grp; 1117a62dc406SDoug Rabson int flags; 11188fae3551SRodney W. Grimes { 11198fae3551SRodney W. Grimes struct dirlist *dp; 11208fae3551SRodney W. Grimes struct hostlist *hp; 11218fae3551SRodney W. Grimes int cmp; 11228fae3551SRodney W. Grimes 11238fae3551SRodney W. Grimes dp = *dpp; 11248fae3551SRodney W. Grimes if (dp) { 11258fae3551SRodney W. Grimes cmp = strcmp(dp->dp_dirp, newdp->dp_dirp); 11268fae3551SRodney W. Grimes if (cmp > 0) { 1127a62dc406SDoug Rabson add_dlist(&dp->dp_left, newdp, grp, flags); 11288fae3551SRodney W. Grimes return; 11298fae3551SRodney W. Grimes } else if (cmp < 0) { 1130a62dc406SDoug Rabson add_dlist(&dp->dp_right, newdp, grp, flags); 11318fae3551SRodney W. Grimes return; 11328fae3551SRodney W. Grimes } else 11338fae3551SRodney W. Grimes free((caddr_t)newdp); 11348fae3551SRodney W. Grimes } else { 11358fae3551SRodney W. Grimes dp = newdp; 11368fae3551SRodney W. Grimes dp->dp_left = (struct dirlist *)NULL; 11378fae3551SRodney W. Grimes *dpp = dp; 11388fae3551SRodney W. Grimes } 11398fae3551SRodney W. Grimes if (grp) { 11408fae3551SRodney W. Grimes 11418fae3551SRodney W. Grimes /* 11428fae3551SRodney W. Grimes * Hang all of the host(s) off of the directory point. 11438fae3551SRodney W. Grimes */ 11448fae3551SRodney W. Grimes do { 11458fae3551SRodney W. Grimes hp = get_ht(); 1146a62dc406SDoug Rabson if (flags & OP_KERB) 1147a62dc406SDoug Rabson hp->ht_flag |= DP_KERB; 11488fae3551SRodney W. Grimes hp->ht_grp = grp; 11498fae3551SRodney W. Grimes hp->ht_next = dp->dp_hosts; 11508fae3551SRodney W. Grimes dp->dp_hosts = hp; 11518fae3551SRodney W. Grimes grp = grp->gr_next; 11528fae3551SRodney W. Grimes } while (grp); 1153a62dc406SDoug Rabson } else { 11548fae3551SRodney W. Grimes dp->dp_flag |= DP_DEFSET; 1155a62dc406SDoug Rabson if (flags & OP_KERB) 1156a62dc406SDoug Rabson dp->dp_flag |= DP_KERB; 1157a62dc406SDoug Rabson } 11588fae3551SRodney W. Grimes } 11598fae3551SRodney W. Grimes 11608fae3551SRodney W. Grimes /* 11618fae3551SRodney W. Grimes * Search for a dirpath on the export point. 11628fae3551SRodney W. Grimes */ 11638fae3551SRodney W. Grimes struct dirlist * 11648fae3551SRodney W. Grimes dirp_search(dp, dirpath) 11658fae3551SRodney W. Grimes struct dirlist *dp; 11668fae3551SRodney W. Grimes char *dirpath; 11678fae3551SRodney W. Grimes { 11688fae3551SRodney W. Grimes int cmp; 11698fae3551SRodney W. Grimes 11708fae3551SRodney W. Grimes if (dp) { 11718fae3551SRodney W. Grimes cmp = strcmp(dp->dp_dirp, dirpath); 11728fae3551SRodney W. Grimes if (cmp > 0) 11738fae3551SRodney W. Grimes return (dirp_search(dp->dp_left, dirpath)); 11748fae3551SRodney W. Grimes else if (cmp < 0) 11758fae3551SRodney W. Grimes return (dirp_search(dp->dp_right, dirpath)); 11768fae3551SRodney W. Grimes else 11778fae3551SRodney W. Grimes return (dp); 11788fae3551SRodney W. Grimes } 11798fae3551SRodney W. Grimes return (dp); 11808fae3551SRodney W. Grimes } 11818fae3551SRodney W. Grimes 11828fae3551SRodney W. Grimes /* 11838fae3551SRodney W. Grimes * Scan for a host match in a directory tree. 11848fae3551SRodney W. Grimes */ 11858fae3551SRodney W. Grimes int 1186a62dc406SDoug Rabson chk_host(dp, saddr, defsetp, hostsetp) 11878fae3551SRodney W. Grimes struct dirlist *dp; 11888fae3551SRodney W. Grimes u_long saddr; 11898fae3551SRodney W. Grimes int *defsetp; 1190a62dc406SDoug Rabson int *hostsetp; 11918fae3551SRodney W. Grimes { 11928fae3551SRodney W. Grimes struct hostlist *hp; 11938fae3551SRodney W. Grimes struct grouplist *grp; 11948fae3551SRodney W. Grimes u_long **addrp; 11958fae3551SRodney W. Grimes 11968fae3551SRodney W. Grimes if (dp) { 11978fae3551SRodney W. Grimes if (dp->dp_flag & DP_DEFSET) 1198a62dc406SDoug Rabson *defsetp = dp->dp_flag; 11998fae3551SRodney W. Grimes hp = dp->dp_hosts; 12008fae3551SRodney W. Grimes while (hp) { 12018fae3551SRodney W. Grimes grp = hp->ht_grp; 12028fae3551SRodney W. Grimes switch (grp->gr_type) { 12038fae3551SRodney W. Grimes case GT_HOST: 12048fae3551SRodney W. Grimes addrp = (u_long **) 12058fae3551SRodney W. Grimes grp->gr_ptr.gt_hostent->h_addr_list; 12068fae3551SRodney W. Grimes while (*addrp) { 1207a62dc406SDoug Rabson if (**addrp == saddr) { 1208a62dc406SDoug Rabson *hostsetp = (hp->ht_flag | DP_HOSTSET); 12098fae3551SRodney W. Grimes return (1); 1210a62dc406SDoug Rabson } 12118fae3551SRodney W. Grimes addrp++; 12128fae3551SRodney W. Grimes } 12138fae3551SRodney W. Grimes break; 12148fae3551SRodney W. Grimes case GT_NET: 12158fae3551SRodney W. Grimes if ((saddr & grp->gr_ptr.gt_net.nt_mask) == 1216a62dc406SDoug Rabson grp->gr_ptr.gt_net.nt_net) { 1217a62dc406SDoug Rabson *hostsetp = (hp->ht_flag | DP_HOSTSET); 12188fae3551SRodney W. Grimes return (1); 1219a62dc406SDoug Rabson } 12208fae3551SRodney W. Grimes break; 12218fae3551SRodney W. Grimes }; 12228fae3551SRodney W. Grimes hp = hp->ht_next; 12238fae3551SRodney W. Grimes } 12248fae3551SRodney W. Grimes } 12258fae3551SRodney W. Grimes return (0); 12268fae3551SRodney W. Grimes } 12278fae3551SRodney W. Grimes 12288fae3551SRodney W. Grimes /* 12298fae3551SRodney W. Grimes * Scan tree for a host that matches the address. 12308fae3551SRodney W. Grimes */ 12318fae3551SRodney W. Grimes int 12328fae3551SRodney W. Grimes scan_tree(dp, saddr) 12338fae3551SRodney W. Grimes struct dirlist *dp; 12348fae3551SRodney W. Grimes u_long saddr; 12358fae3551SRodney W. Grimes { 1236a62dc406SDoug Rabson int defset, hostset; 12378fae3551SRodney W. Grimes 12388fae3551SRodney W. Grimes if (dp) { 12398fae3551SRodney W. Grimes if (scan_tree(dp->dp_left, saddr)) 12408fae3551SRodney W. Grimes return (1); 1241a62dc406SDoug Rabson if (chk_host(dp, saddr, &defset, &hostset)) 12428fae3551SRodney W. Grimes return (1); 12438fae3551SRodney W. Grimes if (scan_tree(dp->dp_right, saddr)) 12448fae3551SRodney W. Grimes return (1); 12458fae3551SRodney W. Grimes } 12468fae3551SRodney W. Grimes return (0); 12478fae3551SRodney W. Grimes } 12488fae3551SRodney W. Grimes 12498fae3551SRodney W. Grimes /* 12508fae3551SRodney W. Grimes * Traverse the dirlist tree and free it up. 12518fae3551SRodney W. Grimes */ 12528fae3551SRodney W. Grimes void 12538fae3551SRodney W. Grimes free_dir(dp) 12548fae3551SRodney W. Grimes struct dirlist *dp; 12558fae3551SRodney W. Grimes { 12568fae3551SRodney W. Grimes 12578fae3551SRodney W. Grimes if (dp) { 12588fae3551SRodney W. Grimes free_dir(dp->dp_left); 12598fae3551SRodney W. Grimes free_dir(dp->dp_right); 12608fae3551SRodney W. Grimes free_host(dp->dp_hosts); 12618fae3551SRodney W. Grimes free((caddr_t)dp); 12628fae3551SRodney W. Grimes } 12638fae3551SRodney W. Grimes } 12648fae3551SRodney W. Grimes 12658fae3551SRodney W. Grimes /* 12668fae3551SRodney W. Grimes * Parse the option string and update fields. 12678fae3551SRodney W. Grimes * Option arguments may either be -<option>=<value> or 12688fae3551SRodney W. Grimes * -<option> <value> 12698fae3551SRodney W. Grimes */ 12708fae3551SRodney W. Grimes int 12718fae3551SRodney W. Grimes do_opt(cpp, endcpp, ep, grp, has_hostp, exflagsp, cr) 12728fae3551SRodney W. Grimes char **cpp, **endcpp; 12738fae3551SRodney W. Grimes struct exportlist *ep; 12748fae3551SRodney W. Grimes struct grouplist *grp; 12758fae3551SRodney W. Grimes int *has_hostp; 12768fae3551SRodney W. Grimes int *exflagsp; 12778fae3551SRodney W. Grimes struct ucred *cr; 12788fae3551SRodney W. Grimes { 12798fae3551SRodney W. Grimes char *cpoptarg, *cpoptend; 12808fae3551SRodney W. Grimes char *cp, *endcp, *cpopt, savedc, savedc2; 12818fae3551SRodney W. Grimes int allflag, usedarg; 12828fae3551SRodney W. Grimes 12838fae3551SRodney W. Grimes cpopt = *cpp; 12848fae3551SRodney W. Grimes cpopt++; 12858fae3551SRodney W. Grimes cp = *endcpp; 12868fae3551SRodney W. Grimes savedc = *cp; 12878fae3551SRodney W. Grimes *cp = '\0'; 12888fae3551SRodney W. Grimes while (cpopt && *cpopt) { 12898fae3551SRodney W. Grimes allflag = 1; 12908fae3551SRodney W. Grimes usedarg = -2; 129187564113SPeter Wemm if (cpoptend = strchr(cpopt, ',')) { 12928fae3551SRodney W. Grimes *cpoptend++ = '\0'; 129387564113SPeter Wemm if (cpoptarg = strchr(cpopt, '=')) 12948fae3551SRodney W. Grimes *cpoptarg++ = '\0'; 12958fae3551SRodney W. Grimes } else { 129687564113SPeter Wemm if (cpoptarg = strchr(cpopt, '=')) 12978fae3551SRodney W. Grimes *cpoptarg++ = '\0'; 12988fae3551SRodney W. Grimes else { 12998fae3551SRodney W. Grimes *cp = savedc; 13008fae3551SRodney W. Grimes nextfield(&cp, &endcp); 13018fae3551SRodney W. Grimes **endcpp = '\0'; 13028fae3551SRodney W. Grimes if (endcp > cp && *cp != '-') { 13038fae3551SRodney W. Grimes cpoptarg = cp; 13048fae3551SRodney W. Grimes savedc2 = *endcp; 13058fae3551SRodney W. Grimes *endcp = '\0'; 13068fae3551SRodney W. Grimes usedarg = 0; 13078fae3551SRodney W. Grimes } 13088fae3551SRodney W. Grimes } 13098fae3551SRodney W. Grimes } 13108fae3551SRodney W. Grimes if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) { 13118fae3551SRodney W. Grimes *exflagsp |= MNT_EXRDONLY; 13128fae3551SRodney W. Grimes } else if (cpoptarg && (!strcmp(cpopt, "maproot") || 13138fae3551SRodney W. Grimes !(allflag = strcmp(cpopt, "mapall")) || 13148fae3551SRodney W. Grimes !strcmp(cpopt, "root") || !strcmp(cpopt, "r"))) { 13158fae3551SRodney W. Grimes usedarg++; 13168fae3551SRodney W. Grimes parsecred(cpoptarg, cr); 13178fae3551SRodney W. Grimes if (allflag == 0) { 13188fae3551SRodney W. Grimes *exflagsp |= MNT_EXPORTANON; 13198fae3551SRodney W. Grimes opt_flags |= OP_MAPALL; 13208fae3551SRodney W. Grimes } else 13218fae3551SRodney W. Grimes opt_flags |= OP_MAPROOT; 13228fae3551SRodney W. Grimes } else if (!strcmp(cpopt, "kerb") || !strcmp(cpopt, "k")) { 13238fae3551SRodney W. Grimes *exflagsp |= MNT_EXKERB; 13248fae3551SRodney W. Grimes opt_flags |= OP_KERB; 13258fae3551SRodney W. Grimes } else if (cpoptarg && (!strcmp(cpopt, "mask") || 13268fae3551SRodney W. Grimes !strcmp(cpopt, "m"))) { 13278fae3551SRodney W. Grimes if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 1)) { 13288fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad mask: %s", cpoptarg); 13298fae3551SRodney W. Grimes return (1); 13308fae3551SRodney W. Grimes } 13318fae3551SRodney W. Grimes usedarg++; 13328fae3551SRodney W. Grimes opt_flags |= OP_MASK; 13338fae3551SRodney W. Grimes } else if (cpoptarg && (!strcmp(cpopt, "network") || 13348fae3551SRodney W. Grimes !strcmp(cpopt, "n"))) { 13358fae3551SRodney W. Grimes if (grp->gr_type != GT_NULL) { 13368fae3551SRodney W. Grimes syslog(LOG_ERR, "Network/host conflict"); 13378fae3551SRodney W. Grimes return (1); 13388fae3551SRodney W. Grimes } else if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 0)) { 13398fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad net: %s", cpoptarg); 13408fae3551SRodney W. Grimes return (1); 13418fae3551SRodney W. Grimes } 13428fae3551SRodney W. Grimes grp->gr_type = GT_NET; 13438fae3551SRodney W. Grimes *has_hostp = 1; 13448fae3551SRodney W. Grimes usedarg++; 13458fae3551SRodney W. Grimes opt_flags |= OP_NET; 13468fae3551SRodney W. Grimes } else if (!strcmp(cpopt, "alldirs")) { 13478fae3551SRodney W. Grimes opt_flags |= OP_ALLDIRS; 1348cb3923e0SDoug Rabson } else if (!strcmp(cpopt, "public")) { 1349cb3923e0SDoug Rabson *exflagsp |= MNT_EXPUBLIC; 1350cb3923e0SDoug Rabson } else if (!strcmp(cpopt, "webnfs")) { 1351cb3923e0SDoug Rabson *exflagsp |= (MNT_EXPUBLIC|MNT_EXRDONLY|MNT_EXPORTANON); 1352cb3923e0SDoug Rabson opt_flags |= OP_MAPALL; 1353cb3923e0SDoug Rabson } else if (cpoptarg && !strcmp(cpopt, "index")) { 1354cb3923e0SDoug Rabson ep->ex_indexfile = strdup(cpoptarg); 13558fae3551SRodney W. Grimes #ifdef ISO 13568fae3551SRodney W. Grimes } else if (cpoptarg && !strcmp(cpopt, "iso")) { 13578fae3551SRodney W. Grimes if (get_isoaddr(cpoptarg, grp)) { 13588fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad iso addr: %s", cpoptarg); 13598fae3551SRodney W. Grimes return (1); 13608fae3551SRodney W. Grimes } 13618fae3551SRodney W. Grimes *has_hostp = 1; 13628fae3551SRodney W. Grimes usedarg++; 13638fae3551SRodney W. Grimes opt_flags |= OP_ISO; 13648fae3551SRodney W. Grimes #endif /* ISO */ 13658fae3551SRodney W. Grimes } else { 13668fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad opt %s", cpopt); 13678fae3551SRodney W. Grimes return (1); 13688fae3551SRodney W. Grimes } 13698fae3551SRodney W. Grimes if (usedarg >= 0) { 13708fae3551SRodney W. Grimes *endcp = savedc2; 13718fae3551SRodney W. Grimes **endcpp = savedc; 13728fae3551SRodney W. Grimes if (usedarg > 0) { 13738fae3551SRodney W. Grimes *cpp = cp; 13748fae3551SRodney W. Grimes *endcpp = endcp; 13758fae3551SRodney W. Grimes } 13768fae3551SRodney W. Grimes return (0); 13778fae3551SRodney W. Grimes } 13788fae3551SRodney W. Grimes cpopt = cpoptend; 13798fae3551SRodney W. Grimes } 13808fae3551SRodney W. Grimes **endcpp = savedc; 13818fae3551SRodney W. Grimes return (0); 13828fae3551SRodney W. Grimes } 13838fae3551SRodney W. Grimes 13848fae3551SRodney W. Grimes /* 13858fae3551SRodney W. Grimes * Translate a character string to the corresponding list of network 13868fae3551SRodney W. Grimes * addresses for a hostname. 13878fae3551SRodney W. Grimes */ 13888fae3551SRodney W. Grimes int 13898b5a6d67SBill Paul get_host(cp, grp, tgrp) 13908fae3551SRodney W. Grimes char *cp; 13918fae3551SRodney W. Grimes struct grouplist *grp; 13928b5a6d67SBill Paul struct grouplist *tgrp; 13938fae3551SRodney W. Grimes { 13948b5a6d67SBill Paul struct grouplist *checkgrp; 13958fae3551SRodney W. Grimes struct hostent *hp, *nhp; 13968fae3551SRodney W. Grimes char **addrp, **naddrp; 13978fae3551SRodney W. Grimes struct hostent t_host; 13988fae3551SRodney W. Grimes int i; 13998fae3551SRodney W. Grimes u_long saddr; 14008fae3551SRodney W. Grimes char *aptr[2]; 14018fae3551SRodney W. Grimes 14028fae3551SRodney W. Grimes if (grp->gr_type != GT_NULL) 14038fae3551SRodney W. Grimes return (1); 14048fae3551SRodney W. Grimes if ((hp = gethostbyname(cp)) == NULL) { 14058fae3551SRodney W. Grimes if (isdigit(*cp)) { 14068fae3551SRodney W. Grimes saddr = inet_addr(cp); 14078fae3551SRodney W. Grimes if (saddr == -1) { 1408a62dc406SDoug Rabson syslog(LOG_ERR, "Inet_addr failed for %s", cp); 14098fae3551SRodney W. Grimes return (1); 14108fae3551SRodney W. Grimes } 14118fae3551SRodney W. Grimes if ((hp = gethostbyaddr((caddr_t)&saddr, sizeof (saddr), 14128fae3551SRodney W. Grimes AF_INET)) == NULL) { 14138fae3551SRodney W. Grimes hp = &t_host; 14148fae3551SRodney W. Grimes hp->h_name = cp; 14158fae3551SRodney W. Grimes hp->h_addrtype = AF_INET; 14168fae3551SRodney W. Grimes hp->h_length = sizeof (u_long); 14178fae3551SRodney W. Grimes hp->h_addr_list = aptr; 14188fae3551SRodney W. Grimes aptr[0] = (char *)&saddr; 14198fae3551SRodney W. Grimes aptr[1] = (char *)NULL; 14208fae3551SRodney W. Grimes } 14218fae3551SRodney W. Grimes } else { 1422a62dc406SDoug Rabson syslog(LOG_ERR, "Gethostbyname failed for %s", cp); 14238fae3551SRodney W. Grimes return (1); 14248fae3551SRodney W. Grimes } 14258fae3551SRodney W. Grimes } 14268b5a6d67SBill Paul /* 14278b5a6d67SBill Paul * Sanity check: make sure we don't already have an entry 14288b5a6d67SBill Paul * for this host in the grouplist. 14298b5a6d67SBill Paul */ 14308b5a6d67SBill Paul checkgrp = tgrp; 14318b5a6d67SBill Paul while (checkgrp) { 1432273804e2SBill Paul if (checkgrp->gr_type == GT_HOST && 1433273804e2SBill Paul checkgrp->gr_ptr.gt_hostent != NULL && 14348b5a6d67SBill Paul !strcmp(checkgrp->gr_ptr.gt_hostent->h_name, hp->h_name)) { 14358b5a6d67SBill Paul grp->gr_type = GT_IGNORE; 14368b5a6d67SBill Paul return(0); 14378b5a6d67SBill Paul } 14388b5a6d67SBill Paul checkgrp = checkgrp->gr_next; 14398b5a6d67SBill Paul } 14408b5a6d67SBill Paul 14418fae3551SRodney W. Grimes grp->gr_type = GT_HOST; 14428fae3551SRodney W. Grimes nhp = grp->gr_ptr.gt_hostent = (struct hostent *) 14438fae3551SRodney W. Grimes malloc(sizeof(struct hostent)); 14448fae3551SRodney W. Grimes if (nhp == (struct hostent *)NULL) 14458fae3551SRodney W. Grimes out_of_mem(); 144687564113SPeter Wemm memmove(nhp, hp, sizeof(struct hostent)); 14478fae3551SRodney W. Grimes i = strlen(hp->h_name)+1; 14488fae3551SRodney W. Grimes nhp->h_name = (char *)malloc(i); 14498fae3551SRodney W. Grimes if (nhp->h_name == (char *)NULL) 14508fae3551SRodney W. Grimes out_of_mem(); 145187564113SPeter Wemm memmove(nhp->h_name, hp->h_name, i); 14528fae3551SRodney W. Grimes addrp = hp->h_addr_list; 14538fae3551SRodney W. Grimes i = 1; 14548fae3551SRodney W. Grimes while (*addrp++) 14558fae3551SRodney W. Grimes i++; 14568fae3551SRodney W. Grimes naddrp = nhp->h_addr_list = (char **) 14578fae3551SRodney W. Grimes malloc(i*sizeof(char *)); 14588fae3551SRodney W. Grimes if (naddrp == (char **)NULL) 14598fae3551SRodney W. Grimes out_of_mem(); 14608fae3551SRodney W. Grimes addrp = hp->h_addr_list; 14618fae3551SRodney W. Grimes while (*addrp) { 14628fae3551SRodney W. Grimes *naddrp = (char *) 14638fae3551SRodney W. Grimes malloc(hp->h_length); 14648fae3551SRodney W. Grimes if (*naddrp == (char *)NULL) 14658fae3551SRodney W. Grimes out_of_mem(); 146687564113SPeter Wemm memmove(*naddrp, *addrp, hp->h_length); 14678fae3551SRodney W. Grimes addrp++; 14688fae3551SRodney W. Grimes naddrp++; 14698fae3551SRodney W. Grimes } 14708fae3551SRodney W. Grimes *naddrp = (char *)NULL; 14718fae3551SRodney W. Grimes if (debug) 14728fae3551SRodney W. Grimes fprintf(stderr, "got host %s\n", hp->h_name); 14738fae3551SRodney W. Grimes return (0); 14748fae3551SRodney W. Grimes } 14758fae3551SRodney W. Grimes 14768fae3551SRodney W. Grimes /* 14778fae3551SRodney W. Grimes * Free up an exports list component 14788fae3551SRodney W. Grimes */ 14798fae3551SRodney W. Grimes void 14808fae3551SRodney W. Grimes free_exp(ep) 14818fae3551SRodney W. Grimes struct exportlist *ep; 14828fae3551SRodney W. Grimes { 14838fae3551SRodney W. Grimes 14848fae3551SRodney W. Grimes if (ep->ex_defdir) { 14858fae3551SRodney W. Grimes free_host(ep->ex_defdir->dp_hosts); 14868fae3551SRodney W. Grimes free((caddr_t)ep->ex_defdir); 14878fae3551SRodney W. Grimes } 14888fae3551SRodney W. Grimes if (ep->ex_fsdir) 14898fae3551SRodney W. Grimes free(ep->ex_fsdir); 1490cb3923e0SDoug Rabson if (ep->ex_indexfile) 1491cb3923e0SDoug Rabson free(ep->ex_indexfile); 14928fae3551SRodney W. Grimes free_dir(ep->ex_dirl); 14938fae3551SRodney W. Grimes free((caddr_t)ep); 14948fae3551SRodney W. Grimes } 14958fae3551SRodney W. Grimes 14968fae3551SRodney W. Grimes /* 14978fae3551SRodney W. Grimes * Free hosts. 14988fae3551SRodney W. Grimes */ 14998fae3551SRodney W. Grimes void 15008fae3551SRodney W. Grimes free_host(hp) 15018fae3551SRodney W. Grimes struct hostlist *hp; 15028fae3551SRodney W. Grimes { 15038fae3551SRodney W. Grimes struct hostlist *hp2; 15048fae3551SRodney W. Grimes 15058fae3551SRodney W. Grimes while (hp) { 15068fae3551SRodney W. Grimes hp2 = hp; 15078fae3551SRodney W. Grimes hp = hp->ht_next; 15088fae3551SRodney W. Grimes free((caddr_t)hp2); 15098fae3551SRodney W. Grimes } 15108fae3551SRodney W. Grimes } 15118fae3551SRodney W. Grimes 15128fae3551SRodney W. Grimes struct hostlist * 15138fae3551SRodney W. Grimes get_ht() 15148fae3551SRodney W. Grimes { 15158fae3551SRodney W. Grimes struct hostlist *hp; 15168fae3551SRodney W. Grimes 15178fae3551SRodney W. Grimes hp = (struct hostlist *)malloc(sizeof (struct hostlist)); 15188fae3551SRodney W. Grimes if (hp == (struct hostlist *)NULL) 15198fae3551SRodney W. Grimes out_of_mem(); 15208fae3551SRodney W. Grimes hp->ht_next = (struct hostlist *)NULL; 1521a62dc406SDoug Rabson hp->ht_flag = 0; 15228fae3551SRodney W. Grimes return (hp); 15238fae3551SRodney W. Grimes } 15248fae3551SRodney W. Grimes 15258fae3551SRodney W. Grimes #ifdef ISO 15268fae3551SRodney W. Grimes /* 15278fae3551SRodney W. Grimes * Translate an iso address. 15288fae3551SRodney W. Grimes */ 15298fae3551SRodney W. Grimes get_isoaddr(cp, grp) 15308fae3551SRodney W. Grimes char *cp; 15318fae3551SRodney W. Grimes struct grouplist *grp; 15328fae3551SRodney W. Grimes { 15338fae3551SRodney W. Grimes struct iso_addr *isop; 15348fae3551SRodney W. Grimes struct sockaddr_iso *isoaddr; 15358fae3551SRodney W. Grimes 15368fae3551SRodney W. Grimes if (grp->gr_type != GT_NULL) 15378fae3551SRodney W. Grimes return (1); 15388fae3551SRodney W. Grimes if ((isop = iso_addr(cp)) == NULL) { 15398fae3551SRodney W. Grimes syslog(LOG_ERR, 15408fae3551SRodney W. Grimes "iso_addr failed, ignored"); 15418fae3551SRodney W. Grimes return (1); 15428fae3551SRodney W. Grimes } 15438fae3551SRodney W. Grimes isoaddr = (struct sockaddr_iso *) 15448fae3551SRodney W. Grimes malloc(sizeof (struct sockaddr_iso)); 15458fae3551SRodney W. Grimes if (isoaddr == (struct sockaddr_iso *)NULL) 15468fae3551SRodney W. Grimes out_of_mem(); 154787564113SPeter Wemm memset(isoaddr, 0, sizeof(struct sockaddr_iso)); 154887564113SPeter Wemm memmove(&isoaddr->siso_addr, isop, sizeof(struct iso_addr)); 15498fae3551SRodney W. Grimes isoaddr->siso_len = sizeof(struct sockaddr_iso); 15508fae3551SRodney W. Grimes isoaddr->siso_family = AF_ISO; 15518fae3551SRodney W. Grimes grp->gr_type = GT_ISO; 15528fae3551SRodney W. Grimes grp->gr_ptr.gt_isoaddr = isoaddr; 15538fae3551SRodney W. Grimes return (0); 15548fae3551SRodney W. Grimes } 15558fae3551SRodney W. Grimes #endif /* ISO */ 15568fae3551SRodney W. Grimes 15578fae3551SRodney W. Grimes /* 15588fae3551SRodney W. Grimes * Out of memory, fatal 15598fae3551SRodney W. Grimes */ 15608fae3551SRodney W. Grimes void 15618fae3551SRodney W. Grimes out_of_mem() 15628fae3551SRodney W. Grimes { 15638fae3551SRodney W. Grimes 15648fae3551SRodney W. Grimes syslog(LOG_ERR, "Out of memory"); 15658fae3551SRodney W. Grimes exit(2); 15668fae3551SRodney W. Grimes } 15678fae3551SRodney W. Grimes 15688fae3551SRodney W. Grimes /* 15698fae3551SRodney W. Grimes * Do the mount syscall with the update flag to push the export info into 15708fae3551SRodney W. Grimes * the kernel. 15718fae3551SRodney W. Grimes */ 15728fae3551SRodney W. Grimes int 15738fae3551SRodney W. Grimes do_mount(ep, grp, exflags, anoncrp, dirp, dirplen, fsb) 15748fae3551SRodney W. Grimes struct exportlist *ep; 15758fae3551SRodney W. Grimes struct grouplist *grp; 15768fae3551SRodney W. Grimes int exflags; 15778fae3551SRodney W. Grimes struct ucred *anoncrp; 15788fae3551SRodney W. Grimes char *dirp; 15798fae3551SRodney W. Grimes int dirplen; 15808fae3551SRodney W. Grimes struct statfs *fsb; 15818fae3551SRodney W. Grimes { 15828fae3551SRodney W. Grimes char *cp = (char *)NULL; 15838fae3551SRodney W. Grimes u_long **addrp; 15848fae3551SRodney W. Grimes int done; 15858fae3551SRodney W. Grimes char savedc = '\0'; 15868fae3551SRodney W. Grimes struct sockaddr_in sin, imask; 15878fae3551SRodney W. Grimes union { 15888fae3551SRodney W. Grimes struct ufs_args ua; 15898fae3551SRodney W. Grimes struct iso_args ia; 15908fae3551SRodney W. Grimes struct mfs_args ma; 1591a62dc406SDoug Rabson #ifdef __NetBSD__ 1592a62dc406SDoug Rabson struct msdosfs_args da; 1593a62dc406SDoug Rabson #endif 15948fae3551SRodney W. Grimes } args; 15958fae3551SRodney W. Grimes u_long net; 15968fae3551SRodney W. Grimes 15978fae3551SRodney W. Grimes args.ua.fspec = 0; 15988fae3551SRodney W. Grimes args.ua.export.ex_flags = exflags; 15998fae3551SRodney W. Grimes args.ua.export.ex_anon = *anoncrp; 1600cb3923e0SDoug Rabson args.ua.export.ex_indexfile = ep->ex_indexfile; 160187564113SPeter Wemm memset(&sin, 0, sizeof(sin)); 160287564113SPeter Wemm memset(&imask, 0, sizeof(imask)); 16038fae3551SRodney W. Grimes sin.sin_family = AF_INET; 16048fae3551SRodney W. Grimes sin.sin_len = sizeof(sin); 16058fae3551SRodney W. Grimes imask.sin_family = AF_INET; 16068fae3551SRodney W. Grimes imask.sin_len = sizeof(sin); 16078fae3551SRodney W. Grimes if (grp->gr_type == GT_HOST) 16088fae3551SRodney W. Grimes addrp = (u_long **)grp->gr_ptr.gt_hostent->h_addr_list; 16098fae3551SRodney W. Grimes else 16108fae3551SRodney W. Grimes addrp = (u_long **)NULL; 16118fae3551SRodney W. Grimes done = FALSE; 16128fae3551SRodney W. Grimes while (!done) { 16138fae3551SRodney W. Grimes switch (grp->gr_type) { 16148fae3551SRodney W. Grimes case GT_HOST: 16158fae3551SRodney W. Grimes if (addrp) { 16168fae3551SRodney W. Grimes sin.sin_addr.s_addr = **addrp; 16178fae3551SRodney W. Grimes args.ua.export.ex_addrlen = sizeof(sin); 16188fae3551SRodney W. Grimes } else 16198fae3551SRodney W. Grimes args.ua.export.ex_addrlen = 0; 16208fae3551SRodney W. Grimes args.ua.export.ex_addr = (struct sockaddr *)&sin; 16218fae3551SRodney W. Grimes args.ua.export.ex_masklen = 0; 16228fae3551SRodney W. Grimes break; 16238fae3551SRodney W. Grimes case GT_NET: 16248fae3551SRodney W. Grimes if (grp->gr_ptr.gt_net.nt_mask) 16258fae3551SRodney W. Grimes imask.sin_addr.s_addr = grp->gr_ptr.gt_net.nt_mask; 16268fae3551SRodney W. Grimes else { 16278fae3551SRodney W. Grimes net = ntohl(grp->gr_ptr.gt_net.nt_net); 16288fae3551SRodney W. Grimes if (IN_CLASSA(net)) 16298fae3551SRodney W. Grimes imask.sin_addr.s_addr = inet_addr("255.0.0.0"); 16308fae3551SRodney W. Grimes else if (IN_CLASSB(net)) 16318fae3551SRodney W. Grimes imask.sin_addr.s_addr = 16328fae3551SRodney W. Grimes inet_addr("255.255.0.0"); 16338fae3551SRodney W. Grimes else 16348fae3551SRodney W. Grimes imask.sin_addr.s_addr = 16358fae3551SRodney W. Grimes inet_addr("255.255.255.0"); 16368fae3551SRodney W. Grimes grp->gr_ptr.gt_net.nt_mask = imask.sin_addr.s_addr; 16378fae3551SRodney W. Grimes } 16388fae3551SRodney W. Grimes sin.sin_addr.s_addr = grp->gr_ptr.gt_net.nt_net; 16398fae3551SRodney W. Grimes args.ua.export.ex_addr = (struct sockaddr *)&sin; 16408fae3551SRodney W. Grimes args.ua.export.ex_addrlen = sizeof (sin); 16418fae3551SRodney W. Grimes args.ua.export.ex_mask = (struct sockaddr *)&imask; 16428fae3551SRodney W. Grimes args.ua.export.ex_masklen = sizeof (imask); 16438fae3551SRodney W. Grimes break; 16448fae3551SRodney W. Grimes #ifdef ISO 16458fae3551SRodney W. Grimes case GT_ISO: 16468fae3551SRodney W. Grimes args.ua.export.ex_addr = 16478fae3551SRodney W. Grimes (struct sockaddr *)grp->gr_ptr.gt_isoaddr; 16488fae3551SRodney W. Grimes args.ua.export.ex_addrlen = 16498fae3551SRodney W. Grimes sizeof(struct sockaddr_iso); 16508fae3551SRodney W. Grimes args.ua.export.ex_masklen = 0; 16518fae3551SRodney W. Grimes break; 16528fae3551SRodney W. Grimes #endif /* ISO */ 16538b5a6d67SBill Paul case GT_IGNORE: 16548b5a6d67SBill Paul return(0); 16558b5a6d67SBill Paul break; 16568fae3551SRodney W. Grimes default: 16578fae3551SRodney W. Grimes syslog(LOG_ERR, "Bad grouptype"); 16588fae3551SRodney W. Grimes if (cp) 16598fae3551SRodney W. Grimes *cp = savedc; 16608fae3551SRodney W. Grimes return (1); 16618fae3551SRodney W. Grimes }; 16628fae3551SRodney W. Grimes 16638fae3551SRodney W. Grimes /* 16648fae3551SRodney W. Grimes * XXX: 16658fae3551SRodney W. Grimes * Maybe I should just use the fsb->f_mntonname path instead 16668fae3551SRodney W. Grimes * of looping back up the dirp to the mount point?? 16678fae3551SRodney W. Grimes * Also, needs to know how to export all types of local 166887564113SPeter Wemm * exportable file systems and not just "ufs". 16698fae3551SRodney W. Grimes */ 1670a62dc406SDoug Rabson while (mount(fsb->f_fstypename, dirp, 16718fae3551SRodney W. Grimes fsb->f_flags | MNT_UPDATE, (caddr_t)&args) < 0) { 16728fae3551SRodney W. Grimes if (cp) 16738fae3551SRodney W. Grimes *cp-- = savedc; 16748fae3551SRodney W. Grimes else 16758fae3551SRodney W. Grimes cp = dirp + dirplen - 1; 16768fae3551SRodney W. Grimes if (errno == EPERM) { 16778fae3551SRodney W. Grimes syslog(LOG_ERR, 16788fae3551SRodney W. Grimes "Can't change attributes for %s.\n", dirp); 16798fae3551SRodney W. Grimes return (1); 16808fae3551SRodney W. Grimes } 16818fae3551SRodney W. Grimes if (opt_flags & OP_ALLDIRS) { 16823980ac4fSGarrett Wollman syslog(LOG_ERR, "Could not remount %s: %m", 16833980ac4fSGarrett Wollman dirp); 16848fae3551SRodney W. Grimes return (1); 16858fae3551SRodney W. Grimes } 16868fae3551SRodney W. Grimes /* back up over the last component */ 16878fae3551SRodney W. Grimes while (*cp == '/' && cp > dirp) 16888fae3551SRodney W. Grimes cp--; 16898fae3551SRodney W. Grimes while (*(cp - 1) != '/' && cp > dirp) 16908fae3551SRodney W. Grimes cp--; 16918fae3551SRodney W. Grimes if (cp == dirp) { 16928fae3551SRodney W. Grimes if (debug) 16938fae3551SRodney W. Grimes fprintf(stderr,"mnt unsucc\n"); 16948fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't export %s", dirp); 16958fae3551SRodney W. Grimes return (1); 16968fae3551SRodney W. Grimes } 16978fae3551SRodney W. Grimes savedc = *cp; 16988fae3551SRodney W. Grimes *cp = '\0'; 16998fae3551SRodney W. Grimes } 17008fae3551SRodney W. Grimes if (addrp) { 17018fae3551SRodney W. Grimes ++addrp; 17028fae3551SRodney W. Grimes if (*addrp == (u_long *)NULL) 17038fae3551SRodney W. Grimes done = TRUE; 17048fae3551SRodney W. Grimes } else 17058fae3551SRodney W. Grimes done = TRUE; 17068fae3551SRodney W. Grimes } 17078fae3551SRodney W. Grimes if (cp) 17088fae3551SRodney W. Grimes *cp = savedc; 17098fae3551SRodney W. Grimes return (0); 17108fae3551SRodney W. Grimes } 17118fae3551SRodney W. Grimes 17128fae3551SRodney W. Grimes /* 17138fae3551SRodney W. Grimes * Translate a net address. 17148fae3551SRodney W. Grimes */ 17158fae3551SRodney W. Grimes int 17168fae3551SRodney W. Grimes get_net(cp, net, maskflg) 17178fae3551SRodney W. Grimes char *cp; 17188fae3551SRodney W. Grimes struct netmsk *net; 17198fae3551SRodney W. Grimes int maskflg; 17208fae3551SRodney W. Grimes { 17218fae3551SRodney W. Grimes struct netent *np; 17228fae3551SRodney W. Grimes long netaddr; 17238fae3551SRodney W. Grimes struct in_addr inetaddr, inetaddr2; 17248fae3551SRodney W. Grimes char *name; 17258fae3551SRodney W. Grimes 17260f4b7baaSPaul Traina if (isdigit(*cp) && ((netaddr = inet_network(cp)) != -1)) { 17278fae3551SRodney W. Grimes inetaddr = inet_makeaddr(netaddr, 0); 17288fae3551SRodney W. Grimes /* 17298fae3551SRodney W. Grimes * Due to arbritrary subnet masks, you don't know how many 17308fae3551SRodney W. Grimes * bits to shift the address to make it into a network, 17318fae3551SRodney W. Grimes * however you do know how to make a network address into 17328fae3551SRodney W. Grimes * a host with host == 0 and then compare them. 17338fae3551SRodney W. Grimes * (What a pest) 17348fae3551SRodney W. Grimes */ 17358fae3551SRodney W. Grimes if (!maskflg) { 17368fae3551SRodney W. Grimes setnetent(0); 17378fae3551SRodney W. Grimes while (np = getnetent()) { 17388fae3551SRodney W. Grimes inetaddr2 = inet_makeaddr(np->n_net, 0); 17398fae3551SRodney W. Grimes if (inetaddr2.s_addr == inetaddr.s_addr) 17408fae3551SRodney W. Grimes break; 17418fae3551SRodney W. Grimes } 17428fae3551SRodney W. Grimes endnetent(); 17438fae3551SRodney W. Grimes } 17440f4b7baaSPaul Traina } else if ((np = getnetbyname(cp)) != NULL) { 17450f4b7baaSPaul Traina inetaddr = inet_makeaddr(np->n_net, 0); 17468fae3551SRodney W. Grimes } else 17478fae3551SRodney W. Grimes return (1); 17480f4b7baaSPaul Traina 17498fae3551SRodney W. Grimes if (maskflg) 17508fae3551SRodney W. Grimes net->nt_mask = inetaddr.s_addr; 17518fae3551SRodney W. Grimes else { 17528fae3551SRodney W. Grimes if (np) 17538fae3551SRodney W. Grimes name = np->n_name; 17548fae3551SRodney W. Grimes else 17558fae3551SRodney W. Grimes name = inet_ntoa(inetaddr); 17568fae3551SRodney W. Grimes net->nt_name = (char *)malloc(strlen(name) + 1); 17578fae3551SRodney W. Grimes if (net->nt_name == (char *)NULL) 17588fae3551SRodney W. Grimes out_of_mem(); 17598fae3551SRodney W. Grimes strcpy(net->nt_name, name); 17608fae3551SRodney W. Grimes net->nt_net = inetaddr.s_addr; 17618fae3551SRodney W. Grimes } 17628fae3551SRodney W. Grimes return (0); 17638fae3551SRodney W. Grimes } 17648fae3551SRodney W. Grimes 17658fae3551SRodney W. Grimes /* 17668fae3551SRodney W. Grimes * Parse out the next white space separated field 17678fae3551SRodney W. Grimes */ 17688fae3551SRodney W. Grimes void 17698fae3551SRodney W. Grimes nextfield(cp, endcp) 17708fae3551SRodney W. Grimes char **cp; 17718fae3551SRodney W. Grimes char **endcp; 17728fae3551SRodney W. Grimes { 17738fae3551SRodney W. Grimes char *p; 17748fae3551SRodney W. Grimes 17758fae3551SRodney W. Grimes p = *cp; 17768fae3551SRodney W. Grimes while (*p == ' ' || *p == '\t') 17778fae3551SRodney W. Grimes p++; 17788fae3551SRodney W. Grimes if (*p == '\n' || *p == '\0') 17798fae3551SRodney W. Grimes *cp = *endcp = p; 17808fae3551SRodney W. Grimes else { 17818fae3551SRodney W. Grimes *cp = p++; 17828fae3551SRodney W. Grimes while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 17838fae3551SRodney W. Grimes p++; 17848fae3551SRodney W. Grimes *endcp = p; 17858fae3551SRodney W. Grimes } 17868fae3551SRodney W. Grimes } 17878fae3551SRodney W. Grimes 17888fae3551SRodney W. Grimes /* 17898fae3551SRodney W. Grimes * Get an exports file line. Skip over blank lines and handle line 17908fae3551SRodney W. Grimes * continuations. 17918fae3551SRodney W. Grimes */ 17928fae3551SRodney W. Grimes int 17938fae3551SRodney W. Grimes get_line() 17948fae3551SRodney W. Grimes { 17958fae3551SRodney W. Grimes char *p, *cp; 17968fae3551SRodney W. Grimes int len; 17978fae3551SRodney W. Grimes int totlen, cont_line; 17988fae3551SRodney W. Grimes 17998fae3551SRodney W. Grimes /* 18008fae3551SRodney W. Grimes * Loop around ignoring blank lines and getting all continuation lines. 18018fae3551SRodney W. Grimes */ 18028fae3551SRodney W. Grimes p = line; 18038fae3551SRodney W. Grimes totlen = 0; 18048fae3551SRodney W. Grimes do { 18058fae3551SRodney W. Grimes if (fgets(p, LINESIZ - totlen, exp_file) == NULL) 18068fae3551SRodney W. Grimes return (0); 18078fae3551SRodney W. Grimes len = strlen(p); 18088fae3551SRodney W. Grimes cp = p + len - 1; 18098fae3551SRodney W. Grimes cont_line = 0; 18108fae3551SRodney W. Grimes while (cp >= p && 18118fae3551SRodney W. Grimes (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\\')) { 18128fae3551SRodney W. Grimes if (*cp == '\\') 18138fae3551SRodney W. Grimes cont_line = 1; 18148fae3551SRodney W. Grimes cp--; 18158fae3551SRodney W. Grimes len--; 18168fae3551SRodney W. Grimes } 18178fae3551SRodney W. Grimes *++cp = '\0'; 18188fae3551SRodney W. Grimes if (len > 0) { 18198fae3551SRodney W. Grimes totlen += len; 18208fae3551SRodney W. Grimes if (totlen >= LINESIZ) { 18218fae3551SRodney W. Grimes syslog(LOG_ERR, "Exports line too long"); 18228fae3551SRodney W. Grimes exit(2); 18238fae3551SRodney W. Grimes } 18248fae3551SRodney W. Grimes p = cp; 18258fae3551SRodney W. Grimes } 18268fae3551SRodney W. Grimes } while (totlen == 0 || cont_line); 18278fae3551SRodney W. Grimes return (1); 18288fae3551SRodney W. Grimes } 18298fae3551SRodney W. Grimes 18308fae3551SRodney W. Grimes /* 18318fae3551SRodney W. Grimes * Parse a description of a credential. 18328fae3551SRodney W. Grimes */ 18338fae3551SRodney W. Grimes void 18348fae3551SRodney W. Grimes parsecred(namelist, cr) 18358fae3551SRodney W. Grimes char *namelist; 18368fae3551SRodney W. Grimes struct ucred *cr; 18378fae3551SRodney W. Grimes { 18388fae3551SRodney W. Grimes char *name; 18398fae3551SRodney W. Grimes int cnt; 18408fae3551SRodney W. Grimes char *names; 18418fae3551SRodney W. Grimes struct passwd *pw; 18428fae3551SRodney W. Grimes struct group *gr; 18438fae3551SRodney W. Grimes int ngroups, groups[NGROUPS + 1]; 18448fae3551SRodney W. Grimes 18458fae3551SRodney W. Grimes /* 18468fae3551SRodney W. Grimes * Set up the unpriviledged user. 18478fae3551SRodney W. Grimes */ 18488fae3551SRodney W. Grimes cr->cr_ref = 1; 18498fae3551SRodney W. Grimes cr->cr_uid = -2; 18508fae3551SRodney W. Grimes cr->cr_groups[0] = -2; 18518fae3551SRodney W. Grimes cr->cr_ngroups = 1; 18528fae3551SRodney W. Grimes /* 18538fae3551SRodney W. Grimes * Get the user's password table entry. 18548fae3551SRodney W. Grimes */ 18558fae3551SRodney W. Grimes names = strsep(&namelist, " \t\n"); 18568fae3551SRodney W. Grimes name = strsep(&names, ":"); 18578fae3551SRodney W. Grimes if (isdigit(*name) || *name == '-') 18588fae3551SRodney W. Grimes pw = getpwuid(atoi(name)); 18598fae3551SRodney W. Grimes else 18608fae3551SRodney W. Grimes pw = getpwnam(name); 18618fae3551SRodney W. Grimes /* 18628fae3551SRodney W. Grimes * Credentials specified as those of a user. 18638fae3551SRodney W. Grimes */ 18648fae3551SRodney W. Grimes if (names == NULL) { 18658fae3551SRodney W. Grimes if (pw == NULL) { 18668fae3551SRodney W. Grimes syslog(LOG_ERR, "Unknown user: %s", name); 18678fae3551SRodney W. Grimes return; 18688fae3551SRodney W. Grimes } 18698fae3551SRodney W. Grimes cr->cr_uid = pw->pw_uid; 18708fae3551SRodney W. Grimes ngroups = NGROUPS + 1; 18718fae3551SRodney W. Grimes if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups)) 18728fae3551SRodney W. Grimes syslog(LOG_ERR, "Too many groups"); 18738fae3551SRodney W. Grimes /* 18748fae3551SRodney W. Grimes * Convert from int's to gid_t's and compress out duplicate 18758fae3551SRodney W. Grimes */ 18768fae3551SRodney W. Grimes cr->cr_ngroups = ngroups - 1; 18778fae3551SRodney W. Grimes cr->cr_groups[0] = groups[0]; 18788fae3551SRodney W. Grimes for (cnt = 2; cnt < ngroups; cnt++) 18798fae3551SRodney W. Grimes cr->cr_groups[cnt - 1] = groups[cnt]; 18808fae3551SRodney W. Grimes return; 18818fae3551SRodney W. Grimes } 18828fae3551SRodney W. Grimes /* 18838fae3551SRodney W. Grimes * Explicit credential specified as a colon separated list: 18848fae3551SRodney W. Grimes * uid:gid:gid:... 18858fae3551SRodney W. Grimes */ 18868fae3551SRodney W. Grimes if (pw != NULL) 18878fae3551SRodney W. Grimes cr->cr_uid = pw->pw_uid; 18888fae3551SRodney W. Grimes else if (isdigit(*name) || *name == '-') 18898fae3551SRodney W. Grimes cr->cr_uid = atoi(name); 18908fae3551SRodney W. Grimes else { 18918fae3551SRodney W. Grimes syslog(LOG_ERR, "Unknown user: %s", name); 18928fae3551SRodney W. Grimes return; 18938fae3551SRodney W. Grimes } 18948fae3551SRodney W. Grimes cr->cr_ngroups = 0; 18958fae3551SRodney W. Grimes while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS) { 18968fae3551SRodney W. Grimes name = strsep(&names, ":"); 18978fae3551SRodney W. Grimes if (isdigit(*name) || *name == '-') { 18988fae3551SRodney W. Grimes cr->cr_groups[cr->cr_ngroups++] = atoi(name); 18998fae3551SRodney W. Grimes } else { 19008fae3551SRodney W. Grimes if ((gr = getgrnam(name)) == NULL) { 19018fae3551SRodney W. Grimes syslog(LOG_ERR, "Unknown group: %s", name); 19028fae3551SRodney W. Grimes continue; 19038fae3551SRodney W. Grimes } 19048fae3551SRodney W. Grimes cr->cr_groups[cr->cr_ngroups++] = gr->gr_gid; 19058fae3551SRodney W. Grimes } 19068fae3551SRodney W. Grimes } 19078fae3551SRodney W. Grimes if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS) 19088fae3551SRodney W. Grimes syslog(LOG_ERR, "Too many groups"); 19098fae3551SRodney W. Grimes } 19108fae3551SRodney W. Grimes 19118fae3551SRodney W. Grimes #define STRSIZ (RPCMNT_NAMELEN+RPCMNT_PATHLEN+50) 19128fae3551SRodney W. Grimes /* 19138fae3551SRodney W. Grimes * Routines that maintain the remote mounttab 19148fae3551SRodney W. Grimes */ 19158fae3551SRodney W. Grimes void 19168fae3551SRodney W. Grimes get_mountlist() 19178fae3551SRodney W. Grimes { 19188fae3551SRodney W. Grimes struct mountlist *mlp, **mlpp; 191987564113SPeter Wemm char *host, *dirp, *cp; 19208fae3551SRodney W. Grimes int len; 19218fae3551SRodney W. Grimes char str[STRSIZ]; 19228fae3551SRodney W. Grimes FILE *mlfile; 19238fae3551SRodney W. Grimes 19248fae3551SRodney W. Grimes if ((mlfile = fopen(_PATH_RMOUNTLIST, "r")) == NULL) { 19258fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't open %s", _PATH_RMOUNTLIST); 19268fae3551SRodney W. Grimes return; 19278fae3551SRodney W. Grimes } 19288fae3551SRodney W. Grimes mlpp = &mlhead; 19298fae3551SRodney W. Grimes while (fgets(str, STRSIZ, mlfile) != NULL) { 193087564113SPeter Wemm cp = str; 193187564113SPeter Wemm host = strsep(&cp, " \t\n"); 193287564113SPeter Wemm dirp = strsep(&cp, " \t\n"); 193387564113SPeter Wemm if (host == NULL || dirp == NULL) 19348fae3551SRodney W. Grimes continue; 19358fae3551SRodney W. Grimes mlp = (struct mountlist *)malloc(sizeof (*mlp)); 193687564113SPeter Wemm strncpy(mlp->ml_host, host, RPCMNT_NAMELEN); 193787564113SPeter Wemm mlp->ml_host[RPCMNT_NAMELEN] = '\0'; 193887564113SPeter Wemm strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN); 193987564113SPeter Wemm mlp->ml_dirp[RPCMNT_PATHLEN] = '\0'; 19408fae3551SRodney W. Grimes mlp->ml_next = (struct mountlist *)NULL; 19418fae3551SRodney W. Grimes *mlpp = mlp; 19428fae3551SRodney W. Grimes mlpp = &mlp->ml_next; 19438fae3551SRodney W. Grimes } 19448fae3551SRodney W. Grimes fclose(mlfile); 19458fae3551SRodney W. Grimes } 19468fae3551SRodney W. Grimes 19478fae3551SRodney W. Grimes void 19488fae3551SRodney W. Grimes del_mlist(hostp, dirp) 19498fae3551SRodney W. Grimes char *hostp, *dirp; 19508fae3551SRodney W. Grimes { 19518fae3551SRodney W. Grimes struct mountlist *mlp, **mlpp; 19528fae3551SRodney W. Grimes struct mountlist *mlp2; 19538fae3551SRodney W. Grimes FILE *mlfile; 19548fae3551SRodney W. Grimes int fnd = 0; 19558fae3551SRodney W. Grimes 19568fae3551SRodney W. Grimes mlpp = &mlhead; 19578fae3551SRodney W. Grimes mlp = mlhead; 19588fae3551SRodney W. Grimes while (mlp) { 19598fae3551SRodney W. Grimes if (!strcmp(mlp->ml_host, hostp) && 19608fae3551SRodney W. Grimes (!dirp || !strcmp(mlp->ml_dirp, dirp))) { 19618fae3551SRodney W. Grimes fnd = 1; 19628fae3551SRodney W. Grimes mlp2 = mlp; 19638fae3551SRodney W. Grimes *mlpp = mlp = mlp->ml_next; 19648fae3551SRodney W. Grimes free((caddr_t)mlp2); 19658fae3551SRodney W. Grimes } else { 19668fae3551SRodney W. Grimes mlpp = &mlp->ml_next; 19678fae3551SRodney W. Grimes mlp = mlp->ml_next; 19688fae3551SRodney W. Grimes } 19698fae3551SRodney W. Grimes } 19708fae3551SRodney W. Grimes if (fnd) { 19718fae3551SRodney W. Grimes if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) { 19728fae3551SRodney W. Grimes syslog(LOG_ERR,"Can't update %s", _PATH_RMOUNTLIST); 19738fae3551SRodney W. Grimes return; 19748fae3551SRodney W. Grimes } 19758fae3551SRodney W. Grimes mlp = mlhead; 19768fae3551SRodney W. Grimes while (mlp) { 19778fae3551SRodney W. Grimes fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp); 19788fae3551SRodney W. Grimes mlp = mlp->ml_next; 19798fae3551SRodney W. Grimes } 19808fae3551SRodney W. Grimes fclose(mlfile); 19818fae3551SRodney W. Grimes } 19828fae3551SRodney W. Grimes } 19838fae3551SRodney W. Grimes 19848fae3551SRodney W. Grimes void 19858fae3551SRodney W. Grimes add_mlist(hostp, dirp) 19868fae3551SRodney W. Grimes char *hostp, *dirp; 19878fae3551SRodney W. Grimes { 19888fae3551SRodney W. Grimes struct mountlist *mlp, **mlpp; 19898fae3551SRodney W. Grimes FILE *mlfile; 19908fae3551SRodney W. Grimes 19918fae3551SRodney W. Grimes mlpp = &mlhead; 19928fae3551SRodney W. Grimes mlp = mlhead; 19938fae3551SRodney W. Grimes while (mlp) { 19948fae3551SRodney W. Grimes if (!strcmp(mlp->ml_host, hostp) && !strcmp(mlp->ml_dirp, dirp)) 19958fae3551SRodney W. Grimes return; 19968fae3551SRodney W. Grimes mlpp = &mlp->ml_next; 19978fae3551SRodney W. Grimes mlp = mlp->ml_next; 19988fae3551SRodney W. Grimes } 19998fae3551SRodney W. Grimes mlp = (struct mountlist *)malloc(sizeof (*mlp)); 20008fae3551SRodney W. Grimes strncpy(mlp->ml_host, hostp, RPCMNT_NAMELEN); 20018fae3551SRodney W. Grimes mlp->ml_host[RPCMNT_NAMELEN] = '\0'; 20028fae3551SRodney W. Grimes strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN); 20038fae3551SRodney W. Grimes mlp->ml_dirp[RPCMNT_PATHLEN] = '\0'; 20048fae3551SRodney W. Grimes mlp->ml_next = (struct mountlist *)NULL; 20058fae3551SRodney W. Grimes *mlpp = mlp; 20068fae3551SRodney W. Grimes if ((mlfile = fopen(_PATH_RMOUNTLIST, "a")) == NULL) { 20078fae3551SRodney W. Grimes syslog(LOG_ERR, "Can't update %s", _PATH_RMOUNTLIST); 20088fae3551SRodney W. Grimes return; 20098fae3551SRodney W. Grimes } 20108fae3551SRodney W. Grimes fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp); 20118fae3551SRodney W. Grimes fclose(mlfile); 20128fae3551SRodney W. Grimes } 20138fae3551SRodney W. Grimes 20148fae3551SRodney W. Grimes /* 20158fae3551SRodney W. Grimes * This function is called via. SIGTERM when the system is going down. 20168fae3551SRodney W. Grimes * It sends a broadcast RPCMNT_UMNTALL. 20178fae3551SRodney W. Grimes */ 20188fae3551SRodney W. Grimes void 20198fae3551SRodney W. Grimes send_umntall() 20208fae3551SRodney W. Grimes { 20218fae3551SRodney W. Grimes (void) clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL, 20228fae3551SRodney W. Grimes xdr_void, (caddr_t)0, xdr_void, (caddr_t)0, umntall_each); 20238fae3551SRodney W. Grimes exit(0); 20248fae3551SRodney W. Grimes } 20258fae3551SRodney W. Grimes 20268fae3551SRodney W. Grimes int 20278fae3551SRodney W. Grimes umntall_each(resultsp, raddr) 20288fae3551SRodney W. Grimes caddr_t resultsp; 20298fae3551SRodney W. Grimes struct sockaddr_in *raddr; 20308fae3551SRodney W. Grimes { 20318fae3551SRodney W. Grimes return (1); 20328fae3551SRodney W. Grimes } 20338fae3551SRodney W. Grimes 20348fae3551SRodney W. Grimes /* 20358fae3551SRodney W. Grimes * Free up a group list. 20368fae3551SRodney W. Grimes */ 20378fae3551SRodney W. Grimes void 20388fae3551SRodney W. Grimes free_grp(grp) 20398fae3551SRodney W. Grimes struct grouplist *grp; 20408fae3551SRodney W. Grimes { 20418fae3551SRodney W. Grimes char **addrp; 20428fae3551SRodney W. Grimes 20438fae3551SRodney W. Grimes if (grp->gr_type == GT_HOST) { 20448fae3551SRodney W. Grimes if (grp->gr_ptr.gt_hostent->h_name) { 20458fae3551SRodney W. Grimes addrp = grp->gr_ptr.gt_hostent->h_addr_list; 20468fae3551SRodney W. Grimes while (addrp && *addrp) 20478fae3551SRodney W. Grimes free(*addrp++); 20488fae3551SRodney W. Grimes free((caddr_t)grp->gr_ptr.gt_hostent->h_addr_list); 20498fae3551SRodney W. Grimes free(grp->gr_ptr.gt_hostent->h_name); 20508fae3551SRodney W. Grimes } 20518fae3551SRodney W. Grimes free((caddr_t)grp->gr_ptr.gt_hostent); 20528fae3551SRodney W. Grimes } else if (grp->gr_type == GT_NET) { 20538fae3551SRodney W. Grimes if (grp->gr_ptr.gt_net.nt_name) 20548fae3551SRodney W. Grimes free(grp->gr_ptr.gt_net.nt_name); 20558fae3551SRodney W. Grimes } 20568fae3551SRodney W. Grimes #ifdef ISO 20578fae3551SRodney W. Grimes else if (grp->gr_type == GT_ISO) 20588fae3551SRodney W. Grimes free((caddr_t)grp->gr_ptr.gt_isoaddr); 20598fae3551SRodney W. Grimes #endif 20608fae3551SRodney W. Grimes free((caddr_t)grp); 20618fae3551SRodney W. Grimes } 20628fae3551SRodney W. Grimes 20638fae3551SRodney W. Grimes #ifdef DEBUG 20648fae3551SRodney W. Grimes void 20658fae3551SRodney W. Grimes SYSLOG(int pri, const char *fmt, ...) 20668fae3551SRodney W. Grimes { 20678fae3551SRodney W. Grimes va_list ap; 20688fae3551SRodney W. Grimes 20698fae3551SRodney W. Grimes va_start(ap, fmt); 20708fae3551SRodney W. Grimes vfprintf(stderr, fmt, ap); 20718fae3551SRodney W. Grimes va_end(ap); 20728fae3551SRodney W. Grimes } 20738fae3551SRodney W. Grimes #endif /* DEBUG */ 20748fae3551SRodney W. Grimes 20758fae3551SRodney W. Grimes /* 20768fae3551SRodney W. Grimes * Check options for consistency. 20778fae3551SRodney W. Grimes */ 20788fae3551SRodney W. Grimes int 20798fae3551SRodney W. Grimes check_options(dp) 20808fae3551SRodney W. Grimes struct dirlist *dp; 20818fae3551SRodney W. Grimes { 20828fae3551SRodney W. Grimes 20838fae3551SRodney W. Grimes if (dp == (struct dirlist *)NULL) 20848fae3551SRodney W. Grimes return (1); 20858fae3551SRodney W. Grimes if ((opt_flags & (OP_MAPROOT | OP_MAPALL)) == (OP_MAPROOT | OP_MAPALL) || 20868fae3551SRodney W. Grimes (opt_flags & (OP_MAPROOT | OP_KERB)) == (OP_MAPROOT | OP_KERB) || 20878fae3551SRodney W. Grimes (opt_flags & (OP_MAPALL | OP_KERB)) == (OP_MAPALL | OP_KERB)) { 20888fae3551SRodney W. Grimes syslog(LOG_ERR, "-mapall, -maproot and -kerb mutually exclusive"); 20898fae3551SRodney W. Grimes return (1); 20908fae3551SRodney W. Grimes } 20918fae3551SRodney W. Grimes if ((opt_flags & OP_MASK) && (opt_flags & OP_NET) == 0) { 20928fae3551SRodney W. Grimes syslog(LOG_ERR, "-mask requires -net"); 20938fae3551SRodney W. Grimes return (1); 20948fae3551SRodney W. Grimes } 20958fae3551SRodney W. Grimes if ((opt_flags & (OP_NET | OP_ISO)) == (OP_NET | OP_ISO)) { 20968fae3551SRodney W. Grimes syslog(LOG_ERR, "-net and -iso mutually exclusive"); 20978fae3551SRodney W. Grimes return (1); 20988fae3551SRodney W. Grimes } 20998fae3551SRodney W. Grimes if ((opt_flags & OP_ALLDIRS) && dp->dp_left) { 21008fae3551SRodney W. Grimes syslog(LOG_ERR, "-alldir has multiple directories"); 21018fae3551SRodney W. Grimes return (1); 21028fae3551SRodney W. Grimes } 21038fae3551SRodney W. Grimes return (0); 21048fae3551SRodney W. Grimes } 21058fae3551SRodney W. Grimes 21068fae3551SRodney W. Grimes /* 21078fae3551SRodney W. Grimes * Check an absolute directory path for any symbolic links. Return true 21088fae3551SRodney W. Grimes * if no symbolic links are found. 21098fae3551SRodney W. Grimes */ 21108fae3551SRodney W. Grimes int 21118fae3551SRodney W. Grimes check_dirpath(dirp) 21128fae3551SRodney W. Grimes char *dirp; 21138fae3551SRodney W. Grimes { 21148fae3551SRodney W. Grimes char *cp; 21158fae3551SRodney W. Grimes int ret = 1; 21168fae3551SRodney W. Grimes struct stat sb; 21178fae3551SRodney W. Grimes 21188fae3551SRodney W. Grimes cp = dirp + 1; 21198fae3551SRodney W. Grimes while (*cp && ret) { 21208fae3551SRodney W. Grimes if (*cp == '/') { 21218fae3551SRodney W. Grimes *cp = '\0'; 2122a62dc406SDoug Rabson if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode)) 21238fae3551SRodney W. Grimes ret = 0; 21248fae3551SRodney W. Grimes *cp = '/'; 21258fae3551SRodney W. Grimes } 21268fae3551SRodney W. Grimes cp++; 21278fae3551SRodney W. Grimes } 2128a62dc406SDoug Rabson if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode)) 21298fae3551SRodney W. Grimes ret = 0; 21308fae3551SRodney W. Grimes return (ret); 21318fae3551SRodney W. Grimes } 2132a62dc406SDoug Rabson 2133a62dc406SDoug Rabson /* 2134a62dc406SDoug Rabson * Just translate an ascii string to an integer. 2135a62dc406SDoug Rabson */ 2136a62dc406SDoug Rabson int 2137a62dc406SDoug Rabson get_num(cp) 2138a62dc406SDoug Rabson register char *cp; 2139a62dc406SDoug Rabson { 2140a62dc406SDoug Rabson register int res = 0; 2141a62dc406SDoug Rabson 2142a62dc406SDoug Rabson while (*cp) { 2143a62dc406SDoug Rabson if (*cp < '0' || *cp > '9') 2144a62dc406SDoug Rabson return (-1); 2145a62dc406SDoug Rabson res = res * 10 + (*cp++ - '0'); 2146a62dc406SDoug Rabson } 2147a62dc406SDoug Rabson return (res); 2148a62dc406SDoug Rabson } 2149