* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1992, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid
[] = "@(#)mount_nfs.c 8.3 (Berkeley) %G%";
#include <sys/socketvar.h>
#include <rpc/pmap_clnt.h>
#include <rpc/pmap_prot.h>
#include <kerberosIV/des.h>
#include <kerberosIV/krb.h>
struct mntopt mopts
[] = {
struct nfs_args nfsdefargs
= {
sizeof (struct sockaddr_in
),
int retrycnt
= DEF_RETRY
;
int getnfsargs
__P((char *, struct nfs_args
*));
struct iso_addr
*iso_addr
__P((const char *));
void set_rpc_maxgrouplist
__P((int));
__dead
void usage
__P((void));
int xdr_dir
__P((XDR
*, char *));
int xdr_fh
__P((XDR
*, struct nfhret
*));
register struct nfs_args
*nfsargsp
;
int mntflags
, i
, nfssvc_flag
, num
;
(void)strcpy(realm
, KRB_REALM
);
while ((c
= getopt(argc
, argv
,
"a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF
)
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -a value -- %s", optarg
);
nfsargsp
->readahead
= num
;
nfsargsp
->flags
|= NFSMNT_READAHEAD
;
nfsargsp
->flags
|= NFSMNT_NOCONN
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -D value -- %s", optarg
);
nfsargsp
->deadthresh
= num
;
nfsargsp
->flags
|= NFSMNT_DEADTHRESH
;
nfsargsp
->flags
|= NFSMNT_DUMBTIMR
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -g value -- %s", optarg
);
set_rpc_maxgrouplist(num
);
nfsargsp
->maxgrouplist
= num
;
nfsargsp
->flags
|= NFSMNT_MAXGRPS
;
nfsargsp
->flags
|= NFSMNT_INT
;
nfsargsp
->flags
|= NFSMNT_KERB
;
nfsargsp
->flags
|= NFSMNT_NQLOOKLEASE
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -L value -- %s", optarg
);
nfsargsp
->leaseterm
= num
;
nfsargsp
->flags
|= NFSMNT_LEASETERM
;
nfsargsp
->flags
|= NFSMNT_RDIRALOOK
;
nfsargsp
->flags
|= NFSMNT_MYWRITE
;
(void)strncpy(realm
, optarg
, REALM_SZ
- 1);
realm
[REALM_SZ
- 1] = '\0';
getmntopts(optarg
, mopts
, &mntflags
);
nfsargsp
->flags
|= NFSMNT_RESVPORT
;
nfsargsp
->sotype
= SOCK_SEQPACKET
;
nfsargsp
->flags
|= NFSMNT_NQNFS
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -R value -- %s", optarg
);
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -r value -- %s", optarg
);
nfsargsp
->flags
|= NFSMNT_RSIZE
;
nfsargsp
->flags
|= NFSMNT_SOFT
;
nfsargsp
->sotype
= SOCK_STREAM
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -t value -- %s", optarg
);
nfsargsp
->flags
|= NFSMNT_TIMEO
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -w value -- %s", optarg
);
nfsargsp
->flags
|= NFSMNT_WSIZE
;
num
= strtol(optarg
, &p
, 10);
errx(1, "illegal -x value -- %s", optarg
);
nfsargsp
->flags
|= NFSMNT_RETRANS
;
if (!getnfsargs(spec
, nfsargsp
))
if (mount(MOUNT_NFS
, name
, mntflags
, nfsargsp
))
if (nfsargsp
->flags
& (NFSMNT_NQNFS
| NFSMNT_KERB
)) {
if ((opflags
& ISBGRND
) == 0) {
(void) close(STDIN_FILENO
);
(void) close(STDOUT_FILENO
);
(void) close(STDERR_FILENO
);
openlog("mount_nfs:", LOG_PID
, LOG_DAEMON
);
nfssvc_flag
= NFSSVC_MNTD
;
while (nfssvc(nfssvc_flag
, (caddr_t
)&ncd
) < 0) {
if (errno
!= ENEEDAUTH
) {
syslog(LOG_ERR
, "nfssvc err %m");
NFSSVC_MNTD
| NFSSVC_GOTAUTH
| NFSSVC_AUTHINFAIL
;
* Set up as ncd_authuid for the kerberos call.
* Must set ruid to ncd_authuid and reset the
* ticket name iff ncd_authuid is not the same
* as last time, so that the right ticket file
if (ncd
.ncd_authuid
!= last_ruid
) {
last_ruid
= ncd
.ncd_authuid
;
setreuid(ncd
.ncd_authuid
, 0);
if (krb_mk_req(&kt
, "rcmd", inst
, realm
, 0) ==
kt
.length
<= (RPCAUTH_MAXSIZ
- 2 * NFSX_UNSIGNED
)) {
ncd
.ncd_authtype
= RPCAUTH_NQNFS
;
ncd
.ncd_authlen
= kt
.length
;
ncd
.ncd_authstr
= (char *)kt
.dat
;
nfssvc_flag
= NFSSVC_MNTD
| NFSSVC_GOTAUTH
;
getnfsargs(spec
, nfsargsp
)
struct nfs_args
*nfsargsp
;
static struct sockaddr_in saddr
;
static struct sockaddr_iso isoaddr
;
struct timeval pertry
, try;
enum clnt_stat clnt_stat
;
static struct nfhret nfhret
;
static char nam
[MNAMELEN
+ 1];
strncpy(nam
, spec
, MNAMELEN
);
if ((delimp
= strchr(spec
, '@')) != NULL
) {
} else if ((delimp
= strchr(spec
, ':')) != NULL
) {
warnx("no <host>:<dirpath> or <dirpath>@<host> spec");
* DUMB!! Until the mount protocol works on iso transport, we must
* supply both an iso and an inet address for the host.
if (!strncmp(hostp
, "iso=", 4)) {
if ((delimp
= strchr(hostp
, '+')) == NULL
) {
warnx("no iso+inet address");
if ((isop
= iso_addr(hostp
)) == NULL
) {
warnx("bad ISO address");
bzero((caddr_t
)&isoaddr
, sizeof (isoaddr
));
bcopy((caddr_t
)isop
, (caddr_t
)&isoaddr
.siso_addr
,
sizeof (struct iso_addr
));
isoaddr
.siso_len
= sizeof (isoaddr
);
isoaddr
.siso_family
= AF_ISO
;
isoport
= htons(NFS_PORT
);
bcopy((caddr_t
)&isoport
, TSEL(&isoaddr
), isoaddr
.siso_tlen
);
* Handle an internet host address and reverse resolve it if
if ((saddr
.sin_addr
.s_addr
= inet_addr(hostp
)) == -1) {
warnx("bad net address %s", hostp
);
if ((nfsargsp
->flags
& NFSMNT_KERB
) &&
(hp
= gethostbyaddr((char *)&saddr
.sin_addr
.s_addr
,
sizeof (u_long
), AF_INET
)) == (struct hostent
*)0) {
warnx("can't reverse resolve net address");
} else if ((hp
= gethostbyname(hostp
)) == NULL
) {
warnx("can't get net id for host");
if (nfsargsp
->flags
& NFSMNT_KERB
) {
strncpy(inst
, hp
->h_name
, INST_SZ
);
inst
[INST_SZ
- 1] = '\0';
if (cp
= strchr(inst
, '.'))
bcopy(hp
->h_addr
, (caddr_t
)&saddr
.sin_addr
, hp
->h_length
);
nfhret
.stat
= EACCES
; /* Mark not yet successful */
saddr
.sin_family
= AF_INET
;
saddr
.sin_port
= htons(PMAPPORT
);
if ((tport
= pmap_getport(&saddr
, RPCPROG_NFS
,
NFS_VER2
, IPPROTO_UDP
)) == 0) {
if ((opflags
& ISBGRND
) == 0)
clnt_pcreateerror("NFS Portmap");
if ((clp
= clntudp_create(&saddr
, RPCPROG_MNT
,
RPCMNT_VER1
, pertry
, &so
)) == NULL
) {
if ((opflags
& ISBGRND
) == 0)
clnt_pcreateerror("Cannot MNT PRC");
clp
->cl_auth
= authunix_create_default();
clnt_stat
= clnt_call(clp
, RPCMNT_MOUNT
,
xdr_dir
, spec
, xdr_fh
, &nfhret
, try);
if (clnt_stat
!= RPC_SUCCESS
) {
if ((opflags
& ISBGRND
) == 0)
warnx("%s", clnt_sperror(clp
,
auth_destroy(clp
->cl_auth
);
(void) close(STDIN_FILENO
);
(void) close(STDOUT_FILENO
);
(void) close(STDERR_FILENO
);
warn("can't access %s", spec
);
saddr
.sin_port
= htons(tport
);
nfsargsp
->addr
= (struct sockaddr
*) &isoaddr
;
nfsargsp
->addrlen
= sizeof (isoaddr
);
nfsargsp
->addr
= (struct sockaddr
*) &saddr
;
nfsargsp
->addrlen
= sizeof (saddr
);
nfsargsp
->fh
= &nfhret
.nfh
;
nfsargsp
->hostname
= nam
;
* xdr routines for mount rpc's
return (xdr_string(xdrsp
, &dirp
, RPCMNT_PATHLEN
));
if (!xdr_u_long(xdrsp
, &(np
->stat
)))
return (xdr_opaque(xdrsp
, (caddr_t
)&(np
->nfh
), NFSX_FH
));
(void)fprintf(stderr
, "usage: mount_nfs %s\n%s\n%s\n%s\n",
"[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]",
"\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]",
"\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]",