1/* 2 * Copyright (c) 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static char copyright[] = 39"@(#) Copyright (c) 1992, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint 44static char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) 3/27/94"; 45#endif /* not lint */ 46 47#include <sys/param.h> 48#include <sys/mount.h> 49#include <sys/socket.h> 50#include <sys/socketvar.h> 51#include <sys/stat.h> 52#include <sys/syslog.h> 53 54#include <rpc/rpc.h> 55#include <rpc/pmap_clnt.h> 56#include <rpc/pmap_prot.h> 57 58#ifdef ISO 59#include <netiso/iso.h> 60#endif 61 62#ifdef KERBEROS 63#include <kerberosIV/des.h> 64#include <kerberosIV/krb.h> 65#endif 66 67#include <nfs/rpcv2.h> 68#include <nfs/nfsv2.h> 69#define KERNEL 70#include <nfs/nfs.h> 71#undef KERNEL 72#include <nfs/nqnfs.h> 73 74#include <arpa/inet.h> 75 76#include <ctype.h> 77#include <err.h> 78#include <errno.h> 79#include <fcntl.h> 80#include <netdb.h> 81#include <signal.h> 82#include <stdio.h> 83#include <stdlib.h> 84#include <strings.h> 85#include <unistd.h> 86 87#include "mntopts.h" 88 89struct mntopt mopts[] = { 90 MOPT_STDOPTS, 91 MOPT_FORCE, 92 MOPT_UPDATE, 93 { NULL } 94}; 95 96struct nfs_args nfsdefargs = { 97 (struct sockaddr *)0, 98 sizeof (struct sockaddr_in), 99 SOCK_DGRAM, 100 0, 101 (nfsv2fh_t *)0, 102 0, 103 NFS_WSIZE, 104 NFS_RSIZE, 105 NFS_TIMEO, 106 NFS_RETRANS, 107 NFS_MAXGRPS, 108 NFS_DEFRAHEAD, 109 NQ_DEFLEASE, 110 NQ_DEADTHRESH, 111 (char *)0, 112}; 113 114struct nfhret { 115 u_long stat; 116 nfsv2fh_t nfh; 117}; 118#define DEF_RETRY 10000 119#define BGRND 1 120#define ISBGRND 2 121int retrycnt = DEF_RETRY; 122int opflags = 0; 123 124#ifdef KERBEROS 125char inst[INST_SZ]; 126char realm[REALM_SZ]; 127KTEXT_ST kt; 128#endif 129 130int getnfsargs __P((char *, struct nfs_args *)); 131#ifdef ISO 132struct iso_addr *iso_addr __P((const char *)); 133#endif 134void set_rpc_maxgrouplist __P((int)); 135__dead void usage __P((void)); 136int xdr_dir __P((XDR *, char *)); 137int xdr_fh __P((XDR *, struct nfhret *)); 138 139int 140main(argc, argv) 141 int argc; 142 char *argv[]; 143{ 144 register int c; 145 register struct nfs_args *nfsargsp; 146 struct nfs_args nfsargs; 147 struct nfsd_cargs ncd; 148 int mntflags, i, nfssvc_flag, num; 149 char *name, *p, *spec; 150 int error = 0;
| 1/* 2 * Copyright (c) 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static char copyright[] = 39"@(#) Copyright (c) 1992, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint 44static char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) 3/27/94"; 45#endif /* not lint */ 46 47#include <sys/param.h> 48#include <sys/mount.h> 49#include <sys/socket.h> 50#include <sys/socketvar.h> 51#include <sys/stat.h> 52#include <sys/syslog.h> 53 54#include <rpc/rpc.h> 55#include <rpc/pmap_clnt.h> 56#include <rpc/pmap_prot.h> 57 58#ifdef ISO 59#include <netiso/iso.h> 60#endif 61 62#ifdef KERBEROS 63#include <kerberosIV/des.h> 64#include <kerberosIV/krb.h> 65#endif 66 67#include <nfs/rpcv2.h> 68#include <nfs/nfsv2.h> 69#define KERNEL 70#include <nfs/nfs.h> 71#undef KERNEL 72#include <nfs/nqnfs.h> 73 74#include <arpa/inet.h> 75 76#include <ctype.h> 77#include <err.h> 78#include <errno.h> 79#include <fcntl.h> 80#include <netdb.h> 81#include <signal.h> 82#include <stdio.h> 83#include <stdlib.h> 84#include <strings.h> 85#include <unistd.h> 86 87#include "mntopts.h" 88 89struct mntopt mopts[] = { 90 MOPT_STDOPTS, 91 MOPT_FORCE, 92 MOPT_UPDATE, 93 { NULL } 94}; 95 96struct nfs_args nfsdefargs = { 97 (struct sockaddr *)0, 98 sizeof (struct sockaddr_in), 99 SOCK_DGRAM, 100 0, 101 (nfsv2fh_t *)0, 102 0, 103 NFS_WSIZE, 104 NFS_RSIZE, 105 NFS_TIMEO, 106 NFS_RETRANS, 107 NFS_MAXGRPS, 108 NFS_DEFRAHEAD, 109 NQ_DEFLEASE, 110 NQ_DEADTHRESH, 111 (char *)0, 112}; 113 114struct nfhret { 115 u_long stat; 116 nfsv2fh_t nfh; 117}; 118#define DEF_RETRY 10000 119#define BGRND 1 120#define ISBGRND 2 121int retrycnt = DEF_RETRY; 122int opflags = 0; 123 124#ifdef KERBEROS 125char inst[INST_SZ]; 126char realm[REALM_SZ]; 127KTEXT_ST kt; 128#endif 129 130int getnfsargs __P((char *, struct nfs_args *)); 131#ifdef ISO 132struct iso_addr *iso_addr __P((const char *)); 133#endif 134void set_rpc_maxgrouplist __P((int)); 135__dead void usage __P((void)); 136int xdr_dir __P((XDR *, char *)); 137int xdr_fh __P((XDR *, struct nfhret *)); 138 139int 140main(argc, argv) 141 int argc; 142 char *argv[]; 143{ 144 register int c; 145 register struct nfs_args *nfsargsp; 146 struct nfs_args nfsargs; 147 struct nfsd_cargs ncd; 148 int mntflags, i, nfssvc_flag, num; 149 char *name, *p, *spec; 150 int error = 0;
|
| 151 struct vfsconf *vfc;
|
151#ifdef KERBEROS 152 uid_t last_ruid; 153#endif 154 155#ifdef KERBEROS 156 last_ruid = -1; 157 (void)strcpy(realm, KRB_REALM); 158#endif 159 retrycnt = DEF_RETRY; 160 161 mntflags = 0; 162 nfsargs = nfsdefargs; 163 nfsargsp = &nfsargs; 164 while ((c = getopt(argc, argv, 165 "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF) 166 switch (c) { 167 case 'a': 168 num = strtol(optarg, &p, 10); 169 if (*p || num < 0) 170 errx(1, "illegal -a value -- %s", optarg); 171 nfsargsp->readahead = num; 172 nfsargsp->flags |= NFSMNT_READAHEAD; 173 break; 174 case 'b': 175 opflags |= BGRND; 176 break; 177 case 'c': 178 nfsargsp->flags |= NFSMNT_NOCONN; 179 break; 180 case 'D': 181 num = strtol(optarg, &p, 10); 182 if (*p || num <= 0) 183 errx(1, "illegal -D value -- %s", optarg); 184 nfsargsp->deadthresh = num; 185 nfsargsp->flags |= NFSMNT_DEADTHRESH; 186 break; 187 case 'd': 188 nfsargsp->flags |= NFSMNT_DUMBTIMR; 189 break; 190 case 'g': 191 num = strtol(optarg, &p, 10); 192 if (*p || num <= 0) 193 errx(1, "illegal -g value -- %s", optarg); 194 set_rpc_maxgrouplist(num); 195 nfsargsp->maxgrouplist = num; 196 nfsargsp->flags |= NFSMNT_MAXGRPS; 197 break; 198 case 'i': 199 nfsargsp->flags |= NFSMNT_INT; 200 break; 201#ifdef KERBEROS 202 case 'K': 203 nfsargsp->flags |= NFSMNT_KERB; 204 break; 205#endif 206 case 'k': 207 nfsargsp->flags |= NFSMNT_NQLOOKLEASE; 208 break; 209 case 'L': 210 num = strtol(optarg, &p, 10); 211 if (*p || num < 2) 212 errx(1, "illegal -L value -- %s", optarg); 213 nfsargsp->leaseterm = num; 214 nfsargsp->flags |= NFSMNT_LEASETERM; 215 break; 216 case 'l': 217 nfsargsp->flags |= NFSMNT_RDIRALOOK; 218 break; 219 case 'M': 220 nfsargsp->flags |= NFSMNT_MYWRITE; 221 break; 222#ifdef KERBEROS 223 case 'm': 224 (void)strncpy(realm, optarg, REALM_SZ - 1); 225 realm[REALM_SZ - 1] = '\0'; 226 break; 227#endif 228 case 'o': 229 getmntopts(optarg, mopts, &mntflags); 230 break; 231 case 'P': 232 nfsargsp->flags |= NFSMNT_RESVPORT; 233 break; 234#ifdef ISO 235 case 'p': 236 nfsargsp->sotype = SOCK_SEQPACKET; 237 break; 238#endif 239 case 'q': 240 nfsargsp->flags |= NFSMNT_NQNFS; 241 break; 242 case 'R': 243 num = strtol(optarg, &p, 10); 244 if (*p || num <= 0) 245 errx(1, "illegal -R value -- %s", optarg); 246 retrycnt = num; 247 break; 248 case 'r': 249 num = strtol(optarg, &p, 10); 250 if (*p || num <= 0) 251 errx(1, "illegal -r value -- %s", optarg); 252 nfsargsp->rsize = num; 253 nfsargsp->flags |= NFSMNT_RSIZE; 254 break; 255 case 's': 256 nfsargsp->flags |= NFSMNT_SOFT; 257 break; 258 case 'T': 259 nfsargsp->sotype = SOCK_STREAM; 260 break; 261 case 't': 262 num = strtol(optarg, &p, 10); 263 if (*p || num <= 0) 264 errx(1, "illegal -t value -- %s", optarg); 265 nfsargsp->timeo = num; 266 nfsargsp->flags |= NFSMNT_TIMEO; 267 break; 268 case 'w': 269 num = strtol(optarg, &p, 10); 270 if (*p || num <= 0) 271 errx(1, "illegal -w value -- %s", optarg); 272 nfsargsp->wsize = num; 273 nfsargsp->flags |= NFSMNT_WSIZE; 274 break; 275 case 'x': 276 num = strtol(optarg, &p, 10); 277 if (*p || num <= 0) 278 errx(1, "illegal -x value -- %s", optarg); 279 nfsargsp->retrans = num; 280 nfsargsp->flags |= NFSMNT_RETRANS; 281 break; 282 default: 283 usage(); 284 break; 285 } 286 argc -= optind; 287 argv += optind; 288 289 if (argc != 2) 290 error = 1; 291 292 spec = *argv++; 293 name = *argv; 294 295 if (!getnfsargs(spec, nfsargsp)) 296 exit(1);
| 152#ifdef KERBEROS 153 uid_t last_ruid; 154#endif 155 156#ifdef KERBEROS 157 last_ruid = -1; 158 (void)strcpy(realm, KRB_REALM); 159#endif 160 retrycnt = DEF_RETRY; 161 162 mntflags = 0; 163 nfsargs = nfsdefargs; 164 nfsargsp = &nfsargs; 165 while ((c = getopt(argc, argv, 166 "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF) 167 switch (c) { 168 case 'a': 169 num = strtol(optarg, &p, 10); 170 if (*p || num < 0) 171 errx(1, "illegal -a value -- %s", optarg); 172 nfsargsp->readahead = num; 173 nfsargsp->flags |= NFSMNT_READAHEAD; 174 break; 175 case 'b': 176 opflags |= BGRND; 177 break; 178 case 'c': 179 nfsargsp->flags |= NFSMNT_NOCONN; 180 break; 181 case 'D': 182 num = strtol(optarg, &p, 10); 183 if (*p || num <= 0) 184 errx(1, "illegal -D value -- %s", optarg); 185 nfsargsp->deadthresh = num; 186 nfsargsp->flags |= NFSMNT_DEADTHRESH; 187 break; 188 case 'd': 189 nfsargsp->flags |= NFSMNT_DUMBTIMR; 190 break; 191 case 'g': 192 num = strtol(optarg, &p, 10); 193 if (*p || num <= 0) 194 errx(1, "illegal -g value -- %s", optarg); 195 set_rpc_maxgrouplist(num); 196 nfsargsp->maxgrouplist = num; 197 nfsargsp->flags |= NFSMNT_MAXGRPS; 198 break; 199 case 'i': 200 nfsargsp->flags |= NFSMNT_INT; 201 break; 202#ifdef KERBEROS 203 case 'K': 204 nfsargsp->flags |= NFSMNT_KERB; 205 break; 206#endif 207 case 'k': 208 nfsargsp->flags |= NFSMNT_NQLOOKLEASE; 209 break; 210 case 'L': 211 num = strtol(optarg, &p, 10); 212 if (*p || num < 2) 213 errx(1, "illegal -L value -- %s", optarg); 214 nfsargsp->leaseterm = num; 215 nfsargsp->flags |= NFSMNT_LEASETERM; 216 break; 217 case 'l': 218 nfsargsp->flags |= NFSMNT_RDIRALOOK; 219 break; 220 case 'M': 221 nfsargsp->flags |= NFSMNT_MYWRITE; 222 break; 223#ifdef KERBEROS 224 case 'm': 225 (void)strncpy(realm, optarg, REALM_SZ - 1); 226 realm[REALM_SZ - 1] = '\0'; 227 break; 228#endif 229 case 'o': 230 getmntopts(optarg, mopts, &mntflags); 231 break; 232 case 'P': 233 nfsargsp->flags |= NFSMNT_RESVPORT; 234 break; 235#ifdef ISO 236 case 'p': 237 nfsargsp->sotype = SOCK_SEQPACKET; 238 break; 239#endif 240 case 'q': 241 nfsargsp->flags |= NFSMNT_NQNFS; 242 break; 243 case 'R': 244 num = strtol(optarg, &p, 10); 245 if (*p || num <= 0) 246 errx(1, "illegal -R value -- %s", optarg); 247 retrycnt = num; 248 break; 249 case 'r': 250 num = strtol(optarg, &p, 10); 251 if (*p || num <= 0) 252 errx(1, "illegal -r value -- %s", optarg); 253 nfsargsp->rsize = num; 254 nfsargsp->flags |= NFSMNT_RSIZE; 255 break; 256 case 's': 257 nfsargsp->flags |= NFSMNT_SOFT; 258 break; 259 case 'T': 260 nfsargsp->sotype = SOCK_STREAM; 261 break; 262 case 't': 263 num = strtol(optarg, &p, 10); 264 if (*p || num <= 0) 265 errx(1, "illegal -t value -- %s", optarg); 266 nfsargsp->timeo = num; 267 nfsargsp->flags |= NFSMNT_TIMEO; 268 break; 269 case 'w': 270 num = strtol(optarg, &p, 10); 271 if (*p || num <= 0) 272 errx(1, "illegal -w value -- %s", optarg); 273 nfsargsp->wsize = num; 274 nfsargsp->flags |= NFSMNT_WSIZE; 275 break; 276 case 'x': 277 num = strtol(optarg, &p, 10); 278 if (*p || num <= 0) 279 errx(1, "illegal -x value -- %s", optarg); 280 nfsargsp->retrans = num; 281 nfsargsp->flags |= NFSMNT_RETRANS; 282 break; 283 default: 284 usage(); 285 break; 286 } 287 argc -= optind; 288 argv += optind; 289 290 if (argc != 2) 291 error = 1; 292 293 spec = *argv++; 294 name = *argv; 295 296 if (!getnfsargs(spec, nfsargsp)) 297 exit(1);
|
297 if (mount(MOUNT_NFS, name, mntflags, nfsargsp))
| 298 299 vfc = getvfsbyname("nfs"); 300 if(!vfc && vfsisloadable("nfs")) { 301 if(vfsload("nfs")) 302 err(1, "vfsload(nfs)"); 303 endvfsent(); /* flush cache */ 304 vfc = getvfsbyname("nfs"); 305 } 306 307 if (mount(vfc ? vfc->vfc_index : MOUNT_NFS, name, mntflags, nfsargsp))
|
298 err(1, "%s", name); 299 if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) { 300 if ((opflags & ISBGRND) == 0) { 301 if (i = fork()) { 302 if (i == -1) 303 err(1, "nqnfs 1"); 304 exit(0); 305 } 306 (void) setsid(); 307 (void) close(STDIN_FILENO); 308 (void) close(STDOUT_FILENO); 309 (void) close(STDERR_FILENO); 310 (void) chdir("/"); 311 } 312 openlog("mount_nfs:", LOG_PID, LOG_DAEMON); 313 nfssvc_flag = NFSSVC_MNTD; 314 ncd.ncd_dirp = name; 315 while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) { 316 if (errno != ENEEDAUTH) { 317 syslog(LOG_ERR, "nfssvc err %m"); 318 continue; 319 } 320 nfssvc_flag = 321 NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL; 322#ifdef KERBEROS 323 /* 324 * Set up as ncd_authuid for the kerberos call. 325 * Must set ruid to ncd_authuid and reset the 326 * ticket name iff ncd_authuid is not the same 327 * as last time, so that the right ticket file 328 * is found. 329 */ 330 if (ncd.ncd_authuid != last_ruid) { 331 krb_set_tkt_string(""); 332 last_ruid = ncd.ncd_authuid; 333 } 334 setreuid(ncd.ncd_authuid, 0); 335 if (krb_mk_req(&kt, "rcmd", inst, realm, 0) == 336 KSUCCESS && 337 kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) { 338 ncd.ncd_authtype = RPCAUTH_NQNFS; 339 ncd.ncd_authlen = kt.length; 340 ncd.ncd_authstr = (char *)kt.dat; 341 nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH; 342 } 343 setreuid(0, 0); 344#endif /* KERBEROS */ 345 } 346 } 347 exit(0); 348} 349 350int 351getnfsargs(spec, nfsargsp) 352 char *spec; 353 struct nfs_args *nfsargsp; 354{ 355 register CLIENT *clp; 356 struct hostent *hp; 357 static struct sockaddr_in saddr; 358#ifdef ISO 359 static struct sockaddr_iso isoaddr; 360 struct iso_addr *isop; 361 int isoflag = 0; 362#endif 363 struct timeval pertry, try; 364 enum clnt_stat clnt_stat; 365 int so = RPC_ANYSOCK, i; 366 char *hostp, *delimp; 367#ifdef KERBEROS 368 char *cp; 369#endif 370 u_short tport; 371 static struct nfhret nfhret; 372 static char nam[MNAMELEN + 1]; 373 374 strncpy(nam, spec, MNAMELEN); 375 nam[MNAMELEN] = '\0'; 376 if ((delimp = strchr(spec, '@')) != NULL) { 377 hostp = delimp + 1; 378 } else if ((delimp = strchr(spec, ':')) != NULL) { 379 hostp = spec; 380 spec = delimp + 1; 381 } else { 382 warnx("no <host>:<dirpath> or <dirpath>@<host> spec"); 383 return (0); 384 } 385 *delimp = '\0'; 386 /* 387 * DUMB!! Until the mount protocol works on iso transport, we must 388 * supply both an iso and an inet address for the host. 389 */ 390#ifdef ISO 391 if (!strncmp(hostp, "iso=", 4)) { 392 u_short isoport; 393 394 hostp += 4; 395 isoflag++; 396 if ((delimp = strchr(hostp, '+')) == NULL) { 397 warnx("no iso+inet address"); 398 return (0); 399 } 400 *delimp = '\0'; 401 if ((isop = iso_addr(hostp)) == NULL) { 402 warnx("bad ISO address"); 403 return (0); 404 } 405 bzero((caddr_t)&isoaddr, sizeof (isoaddr)); 406 bcopy((caddr_t)isop, (caddr_t)&isoaddr.siso_addr, 407 sizeof (struct iso_addr)); 408 isoaddr.siso_len = sizeof (isoaddr); 409 isoaddr.siso_family = AF_ISO; 410 isoaddr.siso_tlen = 2; 411 isoport = htons(NFS_PORT); 412 bcopy((caddr_t)&isoport, TSEL(&isoaddr), isoaddr.siso_tlen); 413 hostp = delimp + 1; 414 } 415#endif /* ISO */ 416 417 /* 418 * Handle an internet host address and reverse resolve it if 419 * doing Kerberos. 420 */ 421 if (isdigit(*hostp)) { 422 if ((saddr.sin_addr.s_addr = inet_addr(hostp)) == -1) { 423 warnx("bad net address %s", hostp); 424 return (0); 425 } 426 } else if ((hp = gethostbyname(hostp)) != NULL) { 427 bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 428 } else { 429 warnx("can't get net id for host"); 430 return (0); 431 } 432#ifdef KERBEROS 433 if ((nfsargsp->flags & NFSMNT_KERB)) { 434 if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr, 435 sizeof (u_long), AF_INET)) == (struct hostent *)0) { 436 warnx("can't reverse resolve net address"); 437 return (0); 438 } 439 bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 440 strncpy(inst, hp->h_name, INST_SZ); 441 inst[INST_SZ - 1] = '\0'; 442 if (cp = strchr(inst, '.')) 443 *cp = '\0'; 444 } 445#endif /* KERBEROS */ 446 447 nfhret.stat = EACCES; /* Mark not yet successful */ 448 while (retrycnt > 0) { 449 saddr.sin_family = AF_INET; 450 saddr.sin_port = htons(PMAPPORT); 451 if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 452 NFS_VER2, IPPROTO_UDP)) == 0) { 453 if ((opflags & ISBGRND) == 0) 454 clnt_pcreateerror("NFS Portmap"); 455 } else { 456 saddr.sin_port = 0; 457 pertry.tv_sec = 10; 458 pertry.tv_usec = 0; 459 if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 460 RPCMNT_VER1, pertry, &so)) == NULL) { 461 if ((opflags & ISBGRND) == 0) 462 clnt_pcreateerror("Cannot MNT PRC"); 463 } else { 464 clp->cl_auth = authunix_create_default(); 465 try.tv_sec = 10; 466 try.tv_usec = 0; 467 clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 468 xdr_dir, spec, xdr_fh, &nfhret, try); 469 if (clnt_stat != RPC_SUCCESS) { 470 if ((opflags & ISBGRND) == 0) 471 warnx("%s", clnt_sperror(clp, 472 "bad MNT RPC")); 473 } else { 474 auth_destroy(clp->cl_auth); 475 clnt_destroy(clp); 476 retrycnt = 0; 477 } 478 } 479 } 480 if (--retrycnt > 0) { 481 if (opflags & BGRND) { 482 opflags &= ~BGRND; 483 if (i = fork()) { 484 if (i == -1) 485 err(1, "nqnfs 2"); 486 exit(0); 487 } 488 (void) setsid(); 489 (void) close(STDIN_FILENO); 490 (void) close(STDOUT_FILENO); 491 (void) close(STDERR_FILENO); 492 (void) chdir("/"); 493 opflags |= ISBGRND; 494 } 495 sleep(60); 496 } 497 } 498 if (nfhret.stat) { 499 if (opflags & ISBGRND) 500 exit(1); 501 warn("can't access %s", spec); 502 return (0); 503 } 504 saddr.sin_port = htons(tport); 505#ifdef ISO 506 if (isoflag) { 507 nfsargsp->addr = (struct sockaddr *) &isoaddr; 508 nfsargsp->addrlen = sizeof (isoaddr); 509 } else 510#endif /* ISO */ 511 { 512 nfsargsp->addr = (struct sockaddr *) &saddr; 513 nfsargsp->addrlen = sizeof (saddr); 514 } 515 nfsargsp->fh = &nfhret.nfh; 516 nfsargsp->hostname = nam; 517 return (1); 518} 519 520/* 521 * xdr routines for mount rpc's 522 */ 523int 524xdr_dir(xdrsp, dirp) 525 XDR *xdrsp; 526 char *dirp; 527{ 528 return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 529} 530 531int 532xdr_fh(xdrsp, np) 533 XDR *xdrsp; 534 struct nfhret *np; 535{ 536 if (!xdr_u_long(xdrsp, &(np->stat))) 537 return (0); 538 if (np->stat) 539 return (1); 540 return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 541} 542 543__dead void 544usage() 545{ 546 (void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n", 547"[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]", 548"\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]", 549"\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]", 550"\trhost:path node"); 551 exit(1); 552}
| 308 err(1, "%s", name); 309 if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) { 310 if ((opflags & ISBGRND) == 0) { 311 if (i = fork()) { 312 if (i == -1) 313 err(1, "nqnfs 1"); 314 exit(0); 315 } 316 (void) setsid(); 317 (void) close(STDIN_FILENO); 318 (void) close(STDOUT_FILENO); 319 (void) close(STDERR_FILENO); 320 (void) chdir("/"); 321 } 322 openlog("mount_nfs:", LOG_PID, LOG_DAEMON); 323 nfssvc_flag = NFSSVC_MNTD; 324 ncd.ncd_dirp = name; 325 while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) { 326 if (errno != ENEEDAUTH) { 327 syslog(LOG_ERR, "nfssvc err %m"); 328 continue; 329 } 330 nfssvc_flag = 331 NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL; 332#ifdef KERBEROS 333 /* 334 * Set up as ncd_authuid for the kerberos call. 335 * Must set ruid to ncd_authuid and reset the 336 * ticket name iff ncd_authuid is not the same 337 * as last time, so that the right ticket file 338 * is found. 339 */ 340 if (ncd.ncd_authuid != last_ruid) { 341 krb_set_tkt_string(""); 342 last_ruid = ncd.ncd_authuid; 343 } 344 setreuid(ncd.ncd_authuid, 0); 345 if (krb_mk_req(&kt, "rcmd", inst, realm, 0) == 346 KSUCCESS && 347 kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) { 348 ncd.ncd_authtype = RPCAUTH_NQNFS; 349 ncd.ncd_authlen = kt.length; 350 ncd.ncd_authstr = (char *)kt.dat; 351 nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH; 352 } 353 setreuid(0, 0); 354#endif /* KERBEROS */ 355 } 356 } 357 exit(0); 358} 359 360int 361getnfsargs(spec, nfsargsp) 362 char *spec; 363 struct nfs_args *nfsargsp; 364{ 365 register CLIENT *clp; 366 struct hostent *hp; 367 static struct sockaddr_in saddr; 368#ifdef ISO 369 static struct sockaddr_iso isoaddr; 370 struct iso_addr *isop; 371 int isoflag = 0; 372#endif 373 struct timeval pertry, try; 374 enum clnt_stat clnt_stat; 375 int so = RPC_ANYSOCK, i; 376 char *hostp, *delimp; 377#ifdef KERBEROS 378 char *cp; 379#endif 380 u_short tport; 381 static struct nfhret nfhret; 382 static char nam[MNAMELEN + 1]; 383 384 strncpy(nam, spec, MNAMELEN); 385 nam[MNAMELEN] = '\0'; 386 if ((delimp = strchr(spec, '@')) != NULL) { 387 hostp = delimp + 1; 388 } else if ((delimp = strchr(spec, ':')) != NULL) { 389 hostp = spec; 390 spec = delimp + 1; 391 } else { 392 warnx("no <host>:<dirpath> or <dirpath>@<host> spec"); 393 return (0); 394 } 395 *delimp = '\0'; 396 /* 397 * DUMB!! Until the mount protocol works on iso transport, we must 398 * supply both an iso and an inet address for the host. 399 */ 400#ifdef ISO 401 if (!strncmp(hostp, "iso=", 4)) { 402 u_short isoport; 403 404 hostp += 4; 405 isoflag++; 406 if ((delimp = strchr(hostp, '+')) == NULL) { 407 warnx("no iso+inet address"); 408 return (0); 409 } 410 *delimp = '\0'; 411 if ((isop = iso_addr(hostp)) == NULL) { 412 warnx("bad ISO address"); 413 return (0); 414 } 415 bzero((caddr_t)&isoaddr, sizeof (isoaddr)); 416 bcopy((caddr_t)isop, (caddr_t)&isoaddr.siso_addr, 417 sizeof (struct iso_addr)); 418 isoaddr.siso_len = sizeof (isoaddr); 419 isoaddr.siso_family = AF_ISO; 420 isoaddr.siso_tlen = 2; 421 isoport = htons(NFS_PORT); 422 bcopy((caddr_t)&isoport, TSEL(&isoaddr), isoaddr.siso_tlen); 423 hostp = delimp + 1; 424 } 425#endif /* ISO */ 426 427 /* 428 * Handle an internet host address and reverse resolve it if 429 * doing Kerberos. 430 */ 431 if (isdigit(*hostp)) { 432 if ((saddr.sin_addr.s_addr = inet_addr(hostp)) == -1) { 433 warnx("bad net address %s", hostp); 434 return (0); 435 } 436 } else if ((hp = gethostbyname(hostp)) != NULL) { 437 bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 438 } else { 439 warnx("can't get net id for host"); 440 return (0); 441 } 442#ifdef KERBEROS 443 if ((nfsargsp->flags & NFSMNT_KERB)) { 444 if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr, 445 sizeof (u_long), AF_INET)) == (struct hostent *)0) { 446 warnx("can't reverse resolve net address"); 447 return (0); 448 } 449 bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 450 strncpy(inst, hp->h_name, INST_SZ); 451 inst[INST_SZ - 1] = '\0'; 452 if (cp = strchr(inst, '.')) 453 *cp = '\0'; 454 } 455#endif /* KERBEROS */ 456 457 nfhret.stat = EACCES; /* Mark not yet successful */ 458 while (retrycnt > 0) { 459 saddr.sin_family = AF_INET; 460 saddr.sin_port = htons(PMAPPORT); 461 if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 462 NFS_VER2, IPPROTO_UDP)) == 0) { 463 if ((opflags & ISBGRND) == 0) 464 clnt_pcreateerror("NFS Portmap"); 465 } else { 466 saddr.sin_port = 0; 467 pertry.tv_sec = 10; 468 pertry.tv_usec = 0; 469 if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 470 RPCMNT_VER1, pertry, &so)) == NULL) { 471 if ((opflags & ISBGRND) == 0) 472 clnt_pcreateerror("Cannot MNT PRC"); 473 } else { 474 clp->cl_auth = authunix_create_default(); 475 try.tv_sec = 10; 476 try.tv_usec = 0; 477 clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 478 xdr_dir, spec, xdr_fh, &nfhret, try); 479 if (clnt_stat != RPC_SUCCESS) { 480 if ((opflags & ISBGRND) == 0) 481 warnx("%s", clnt_sperror(clp, 482 "bad MNT RPC")); 483 } else { 484 auth_destroy(clp->cl_auth); 485 clnt_destroy(clp); 486 retrycnt = 0; 487 } 488 } 489 } 490 if (--retrycnt > 0) { 491 if (opflags & BGRND) { 492 opflags &= ~BGRND; 493 if (i = fork()) { 494 if (i == -1) 495 err(1, "nqnfs 2"); 496 exit(0); 497 } 498 (void) setsid(); 499 (void) close(STDIN_FILENO); 500 (void) close(STDOUT_FILENO); 501 (void) close(STDERR_FILENO); 502 (void) chdir("/"); 503 opflags |= ISBGRND; 504 } 505 sleep(60); 506 } 507 } 508 if (nfhret.stat) { 509 if (opflags & ISBGRND) 510 exit(1); 511 warn("can't access %s", spec); 512 return (0); 513 } 514 saddr.sin_port = htons(tport); 515#ifdef ISO 516 if (isoflag) { 517 nfsargsp->addr = (struct sockaddr *) &isoaddr; 518 nfsargsp->addrlen = sizeof (isoaddr); 519 } else 520#endif /* ISO */ 521 { 522 nfsargsp->addr = (struct sockaddr *) &saddr; 523 nfsargsp->addrlen = sizeof (saddr); 524 } 525 nfsargsp->fh = &nfhret.nfh; 526 nfsargsp->hostname = nam; 527 return (1); 528} 529 530/* 531 * xdr routines for mount rpc's 532 */ 533int 534xdr_dir(xdrsp, dirp) 535 XDR *xdrsp; 536 char *dirp; 537{ 538 return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 539} 540 541int 542xdr_fh(xdrsp, np) 543 XDR *xdrsp; 544 struct nfhret *np; 545{ 546 if (!xdr_u_long(xdrsp, &(np->stat))) 547 return (0); 548 if (np->stat) 549 return (1); 550 return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 551} 552 553__dead void 554usage() 555{ 556 (void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n", 557"[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]", 558"\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]", 559"\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]", 560"\trhost:path node"); 561 exit(1); 562}
|