diff options
-rw-r--r-- | support/include/nfslib.h | 9 | ||||
-rw-r--r-- | support/nfs/getfh.c | 64 | ||||
-rw-r--r-- | utils/mountd/mountd.c | 7 |
3 files changed, 67 insertions, 13 deletions
diff --git a/support/include/nfslib.h b/support/include/nfslib.h index af242d3..3db5bec 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -134,9 +134,12 @@ int nfsaddclient(struct nfsctl_client *clp); int nfsdelclient(struct nfsctl_client *clp); int nfsexport(struct nfsctl_export *exp); int nfsunexport(struct nfsctl_export *exp); -struct nfs_fh_len * getfh_old(struct sockaddr *addr, dev_t dev, ino_t ino); -struct nfs_fh_len * getfh(struct sockaddr *addr, const char *); -struct nfs_fh_len * getfh_size(struct sockaddr *addr, const char *, int size); + +struct nfs_fh_len * getfh_old(const struct sockaddr_in *sin, + const dev_t dev, const ino_t ino); +struct nfs_fh_len * getfh(const struct sockaddr_in *sin, const char *path); +struct nfs_fh_len * getfh_size(const struct sockaddr_in *sin, + const char *path, int const size); void qword_print(FILE *f, char *str); void qword_printhex(FILE *f, char *str, int slen); diff --git a/support/nfs/getfh.c b/support/nfs/getfh.c index 81266fd..611459b 100644 --- a/support/nfs/getfh.c +++ b/support/nfs/getfh.c @@ -19,60 +19,112 @@ #include <errno.h> #include "nfslib.h" +/** + * getfh_old - ask the kernel for an NFSv2 file handle via nfsctl() + * @sin: pointer to IPv4 address of a client + * @dev: device number of device where requested object resides + * @ino: inode number of requested object + * + * Returns a pointer to an NFSv2 file handle, or NULL if some error + * occurred. errno is set to reflect the specifics of the error. + */ struct nfs_fh_len * -getfh_old (struct sockaddr *addr, dev_t dev, ino_t ino) +getfh_old(const struct sockaddr_in *sin, const dev_t dev, const ino_t ino) { union nfsctl_res res; struct nfsctl_arg arg; static struct nfs_fh_len rfh; + if (sin->sin_family != AF_INET) { + errno = EAFNOSUPPORT; + return NULL; + } + + memset(&arg, 0, sizeof(arg)); + memset(&res, 0, sizeof(res)); + arg.ca_version = NFSCTL_VERSION; arg.ca_getfh.gf_version = 2; /* obsolete */ arg.ca_getfh.gf_dev = dev; arg.ca_getfh.gf_ino = ino; - memcpy(&arg.ca_getfh.gf_addr, addr, sizeof(struct sockaddr_in)); + memcpy(&arg.ca_getfh.gf_addr, sin, sizeof(*sin)); if (nfsctl(NFSCTL_GETFH, &arg, &res) < 0) return NULL; + memset(&rfh, 0, sizeof(rfh)); rfh.fh_size = 32; memcpy(rfh.fh_handle, &res.cr_getfh, 32); return &rfh; } +/** + * getfh - ask the kernel for an NFSv2 file handle via nfsctl() + * @sin: pointer to IPv4 address of a client + * @path: pointer to a '\0'-terminated ASCII string containing an pathname + * + * Returns a pointer to an NFSv2 file handle, or NULL if some error + * occurred. errno is set to reflect the specifics of the error. + */ struct nfs_fh_len * -getfh(struct sockaddr *addr, const char *path) +getfh(const struct sockaddr_in *sin, const char *path) { static union nfsctl_res res; struct nfsctl_arg arg; static struct nfs_fh_len rfh; + if (sin->sin_family != AF_INET) { + errno = EAFNOSUPPORT; + return NULL; + } + + memset(&arg, 0, sizeof(arg)); + memset(&res, 0, sizeof(res)); + arg.ca_version = NFSCTL_VERSION; arg.ca_getfd.gd_version = 2; /* obsolete */ strncpy(arg.ca_getfd.gd_path, path, sizeof(arg.ca_getfd.gd_path) - 1); arg.ca_getfd.gd_path[sizeof (arg.ca_getfd.gd_path) - 1] = '\0'; - memcpy(&arg.ca_getfd.gd_addr, addr, sizeof(struct sockaddr_in)); + memcpy(&arg.ca_getfd.gd_addr, sin, sizeof(*sin)); if (nfsctl(NFSCTL_GETFD, &arg, &res) < 0) return NULL; + memset(&rfh, 0, sizeof(rfh)); rfh.fh_size = 32; memcpy(rfh.fh_handle, &res.cr_getfh, 32); return &rfh; } +/** + * getfh_size - ask the kernel for a file handle via nfsctl() + * @sin: pointer to IPv4 address of a client + * @path: pointer to a '\0'-terminated ASCII string containing an pathname + * @size: maximum size, in bytes, of the returned file handle + * + * Returns a pointer to an NFSv3 file handle, or NULL if some error + * occurred. errno is set to reflect the specifics of the error. + */ struct nfs_fh_len * -getfh_size(struct sockaddr *addr, const char *path, int size) +getfh_size(const struct sockaddr_in *sin, const char *path, const int size) { static union nfsctl_res res; struct nfsctl_arg arg; + if (sin->sin_family != AF_INET) { + errno = EAFNOSUPPORT; + return NULL; + } + + memset(&arg, 0, sizeof(arg)); + memset(&res, 0, sizeof(res)); + arg.ca_version = NFSCTL_VERSION; strncpy(arg.ca_getfs.gd_path, path, sizeof(arg.ca_getfs.gd_path) - 1); arg.ca_getfs.gd_path[sizeof (arg.ca_getfs.gd_path) - 1] = '\0'; - memcpy(&arg.ca_getfs.gd_addr, addr, sizeof(struct sockaddr_in)); + memcpy(&arg.ca_getfs.gd_addr, sin, sizeof(*sin)); arg.ca_getfs.gd_maxlen = size; if (nfsctl(NFSCTL_GETFS, &arg, &res) < 0) diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index dc84404..78f26c2 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -484,14 +484,13 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret, xtab_append(exp); if (v3) - fh = getfh_size ((struct sockaddr *) sin, p, 64); + fh = getfh_size(sin, p, 64); if (!v3 || (fh == NULL && errno == EINVAL)) { /* We first try the new nfs syscall. */ - fh = getfh ((struct sockaddr *) sin, p); + fh = getfh(sin, p); if (fh == NULL && errno == EINVAL) /* Let's try the old one. */ - fh = getfh_old ((struct sockaddr *) sin, - stb.st_dev, stb.st_ino); + fh = getfh_old(sin, stb.st_dev, stb.st_ino); } if (fh == NULL && !did_export) { exp->m_exported = 0; |