nfs-utils/nfs-utils.1.2.8.rc3.patch

593 lines
16 KiB
Diff
Raw Normal View History

diff --git a/support/export/rmtab.c b/support/export/rmtab.c
index 31c0f50..d16b3b3 100644
--- a/support/export/rmtab.c
+++ b/support/export/rmtab.c
@@ -1,7 +1,7 @@
/*
- * support/export/rmntab.c
+ * support/export/rmtab.c
*
- * Interface to the rmnt file.
+ * Interface to the rmtab file.
*
*/
@@ -12,7 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include "xmalloc.h"
+
#include "misc.h"
#include "nfslib.h"
#include "exportfs.h"
diff --git a/support/export/xtab.c b/support/export/xtab.c
index 2a43193..e953071 100644
--- a/support/export/xtab.c
+++ b/support/export/xtab.c
@@ -14,7 +14,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
-#include "xmalloc.h"
+
#include "nfslib.h"
#include "exportfs.h"
#include "xio.h"
diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
index e641c45..61e07a8 100644
--- a/support/nfs/cacheio.c
+++ b/support/nfs/cacheio.c
@@ -162,11 +162,16 @@ int qword_eol(FILE *f)
{
int err;
- fprintf(f,"\n");
- err = fflush(f);
- if (err) {
- xlog_warn("qword_eol: fflush failed: errno %d (%s)",
+ err = fprintf(f,"\n");
+ if (err < 0) {
+ xlog_warn("qword_eol: fprintf failed: errno %d (%s)",
errno, strerror(errno));
+ } else {
+ err = fflush(f);
+ if (err) {
+ xlog_warn("qword_eol: fflush failed: errno %d (%s)",
+ errno, strerror(errno));
+ }
}
/*
* We must send one line (and one line only) in a single write
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index ec251fa..d01ba2f 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -52,6 +52,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/fsuid.h>
+#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
@@ -250,21 +251,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
if ((p = strstr(buf, "port")) != NULL)
sscanf(p, "port: %127s\n", port);
- /* check service, program, and version */
- if (memcmp(service, "nfs", 3) != 0)
- return -1;
+ /* get program, and version numbers */
*prog = atoi(program + 1); /* skip open paren */
*vers = atoi(version);
- if (strlen(service) == 3 ) {
- if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) &&
- (*vers != 4)))
- goto fail;
- } else if (memcmp(service, "nfs4_cb", 7) == 0) {
- if (*vers != 1)
- goto fail;
- }
-
if (!addrstr_to_sockaddr(addr, address, port))
goto fail;
@@ -398,10 +388,10 @@ process_clnt_dir_files(struct clnt_info * clp)
static int
get_poll_index(int *ind)
{
- int i;
+ unsigned int i;
*ind = -1;
- for (i=0; i<FD_ALLOC_BLOCK; i++) {
+ for (i=0; i<pollsize; i++) {
if (pollarray[i].events == 0) {
*ind = i;
break;
@@ -483,9 +473,13 @@ fail_keep_client:
void
init_client_list(void)
{
+ struct rlimit rlim;
TAILQ_INIT(&clnt_list);
/* Eventually plan to grow/shrink poll array: */
pollsize = FD_ALLOC_BLOCK;
+ if (getrlimit(RLIMIT_NOFILE, &rlim) < 0 &&
+ rlim.rlim_cur != RLIM_INFINITY)
+ pollsize = rlim.rlim_cur;
pollarray = calloc(pollsize, sizeof(struct pollfd));
}
@@ -567,9 +561,8 @@ process_pipedir(char *pipe_name)
update_old_clients(namelist, j, pipe_name);
for (i=0; i < j; i++) {
- if (i < FD_ALLOC_BLOCK
- && !strncmp(namelist[i]->d_name, "clnt", 4)
- && !find_client(namelist[i]->d_name, pipe_name))
+ if (!strncmp(namelist[i]->d_name, "clnt", 4)
+ && !find_client(namelist[i]->d_name, pipe_name))
process_clnt_dir(namelist[i]->d_name, pipe_name);
free(namelist[i]);
}
@@ -962,12 +955,6 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
printerr(1, "handling krb5 upcall (%s)\n", clp->dirname);
- if (tgtname) {
- if (clp->servicename) {
- free(clp->servicename);
- clp->servicename = strdup(tgtname);
- }
- }
token.length = 0;
token.value = NULL;
memset(&pd, 0, sizeof(struct authgss_private_data));
@@ -1016,7 +1003,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
int success = 0;
do {
gssd_refresh_krb5_machine_credential(clp->servername,
- NULL, service);
+ NULL, service,
+ tgtname);
/*
* Get a list of credential cache names and try each
* of them until one works or we've tried them all
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
index 60ba594..aeb8f70 100644
--- a/utils/gssd/krb5_util.c
+++ b/utils/gssd/krb5_util.c
@@ -774,12 +774,16 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt,
}
/*
- * Find a keytab entry to use for a given target hostname.
+ * Find a keytab entry to use for a given target realm.
* Tries to find the most appropriate keytab to use given the
* name of the host we are trying to connect with.
+ *
+ * Note: the tgtname contains a hostname in the realm that we
+ * are authenticating to. It may, or may not be the same as
+ * the server hostname.
*/
static int
-find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
+find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname,
krb5_keytab_entry *kte, const char **svcnames)
{
krb5_error_code code;
@@ -795,7 +799,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
/* Get full target hostname */
- retval = get_full_hostname(hostname, targethostname,
+ retval = get_full_hostname(tgtname, targethostname,
sizeof(targethostname));
if (retval)
goto out;
@@ -1128,7 +1132,7 @@ gssd_get_krb5_machine_cred_list(char ***list)
if (ple->ccname) {
/* Make sure cred is up-to-date before returning it */
retval = gssd_refresh_krb5_machine_credential(NULL, ple,
- NULL);
+ NULL, NULL);
if (retval)
continue;
if (i + 1 > listsize) {
@@ -1219,7 +1223,8 @@ gssd_destroy_krb5_machine_creds(void)
int
gssd_refresh_krb5_machine_credential(char *hostname,
struct gssd_k5_kt_princ *ple,
- char *service)
+ char *service,
+ char *tgtname)
{
krb5_error_code code = 0;
krb5_context context;
@@ -1258,7 +1263,10 @@ gssd_refresh_krb5_machine_credential(char *hostname,
if (ple == NULL) {
krb5_keytab_entry kte;
- code = find_keytab_entry(context, kt, hostname, &kte, svcnames);
+ if (tgtname == NULL)
+ tgtname = hostname;
+
+ code = find_keytab_entry(context, kt, tgtname, &kte, svcnames);
if (code) {
printerr(0, "ERROR: %s: no usable keytab entry found "
"in keytab %s for connection with host %s\n",
diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
index cd6e107..9f41625 100644
--- a/utils/gssd/krb5_util.h
+++ b/utils/gssd/krb5_util.h
@@ -31,7 +31,8 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername);
void gssd_destroy_krb5_machine_creds(void);
int gssd_refresh_krb5_machine_credential(char *hostname,
struct gssd_k5_kt_princ *ple,
- char *service);
+ char *service,
+ char *tgtname);
char *gssd_k5_err_msg(krb5_context context, krb5_error_code code);
void gssd_k5_get_default_realm(char **def_realm);
diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c
index 6c34faf..1d44d34 100644
--- a/utils/gssd/svcgssd_krb5.c
+++ b/utils/gssd/svcgssd_krb5.c
@@ -38,6 +38,7 @@
#include <stdio.h>
#include <errno.h>
+#include <ctype.h>
#include <gssapi/gssapi.h>
#include <krb5.h>
@@ -98,6 +99,12 @@ parse_enctypes(char *enctypes)
if (n == 0)
return ENOENT;
+ /* Skip pass any non digits */
+ while (*enctypes && isdigit(*enctypes) == 0)
+ enctypes++;
+ if (*enctypes == '\0')
+ return EINVAL;
+
/* Allocate space for enctypes array */
if ((parsed_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
return ENOMEM;
diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
index e80efb4..beba9c4 100644
--- a/utils/idmapd/idmapd.c
+++ b/utils/idmapd/idmapd.c
@@ -145,7 +145,6 @@ static void svrreopen(int, short, void *);
static int nfsopen(struct idmap_client *);
static void nfscb(int, short, void *);
static void nfsdcb(int, short, void *);
-static int validateascii(char *, u_int32_t);
static int addfield(char **, ssize_t *, char *);
static int getfield(char **, char *, size_t);
@@ -425,7 +424,8 @@ dirscancb(int UNUSED(fd), short UNUSED(which), void *data)
pipefsdir, ents[i]->d_name);
if ((ic->ic_dirfd = open(path, O_RDONLY, 0)) == -1) {
- xlog_warn("dirscancb: open(%s): %s", path, strerror(errno));
+ if (verbose > 0)
+ xlog_warn("dirscancb: open(%s): %s", path, strerror(errno));
free(ic);
goto out;
}
@@ -642,6 +642,8 @@ out:
static void
imconv(struct idmap_client *ic, struct idmap_msg *im)
{
+ u_int32_t len;
+
switch (im->im_conv) {
case IDMAP_CONV_IDTONAME:
idtonameres(im);
@@ -652,10 +654,10 @@ imconv(struct idmap_client *ic, struct idmap_msg *im)
im->im_id, im->im_name);
break;
case IDMAP_CONV_NAMETOID:
- if (validateascii(im->im_name, sizeof(im->im_name)) == -1) {
- im->im_status |= IDMAP_STATUS_INVALIDMSG;
+ len = strnlen(im->im_name, IDMAP_NAMESZ - 1);
+ /* Check for NULL termination just to be careful */
+ if (im->im_name[len+1] != '\0')
return;
- }
nametoidres(im);
if (verbose > 1)
xlog_warn("%s %s: (%s) name \"%s\" -> id \"%d\"",
@@ -855,25 +857,6 @@ nametoidres(struct idmap_msg *im)
}
static int
-validateascii(char *string, u_int32_t len)
-{
- u_int32_t i;
-
- for (i = 0; i < len; i++) {
- if (string[i] == '\0')
- break;
-
- if (string[i] & 0x80)
- return (-1);
- }
-
- if ((i >= len) || string[i] != '\0')
- return (-1);
-
- return (i + 1);
-}
-
-static int
addfield(char **bpp, ssize_t *bsizp, char *fld)
{
char ch, *bp = *bpp;
diff --git a/utils/mount/error.c b/utils/mount/error.c
index 83ad1d2..f8fc13f 100644
--- a/utils/mount/error.c
+++ b/utils/mount/error.c
@@ -225,7 +225,7 @@ void mount_error(const char *spec, const char *mount_point, int error)
case ENOENT:
if (spec)
nfs_error(_("%s: mounting %s failed, "
- "reason given by server:\n %s"),
+ "reason given by server: %s"),
progname, spec, strerror(error));
else
nfs_error(_("%s: mount point %s does not exist"),
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 9b4197b..8ee3024 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -666,6 +666,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi)
case EOPNOTSUPP:
case EHOSTUNREACH:
case ETIMEDOUT:
+ case EACCES:
continue;
default:
goto out;
@@ -761,6 +762,7 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi)
case ECONNREFUSED:
case EHOSTUNREACH:
case ETIMEDOUT:
+ case EACCES:
continue;
default:
goto out;
diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
index 508040a..330cab5 100644
--- a/utils/mountd/auth.c
+++ b/utils/mountd/auth.c
@@ -10,10 +10,12 @@
#include <config.h>
#endif
+#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include "sockaddr.h"
@@ -21,7 +23,6 @@
#include "nfslib.h"
#include "exportfs.h"
#include "mountd.h"
-#include "xmalloc.h"
#include "v4root.h"
enum auth_error
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index e950ec6..45012be 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -29,7 +29,6 @@
#include "nfslib.h"
#include "exportfs.h"
#include "mountd.h"
-#include "xmalloc.h"
#include "fsloc.h"
#include "pseudoflavors.h"
@@ -109,12 +108,10 @@ static void auth_unix_ip(FILE *f)
struct addrinfo *ai = NULL;
ai = client_resolve(tmp->ai_addr);
- if (ai == NULL)
- goto out;
- client = client_compose(ai);
- freeaddrinfo(ai);
- if (!client)
- goto out;
+ if (ai) {
+ client = client_compose(ai);
+ freeaddrinfo(ai);
+ }
}
qword_print(f, "nfsd");
qword_print(f, ipaddr);
@@ -127,7 +124,6 @@ static void auth_unix_ip(FILE *f)
xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT");
free(client);
-out:
freeaddrinfo(tmp);
}
@@ -347,6 +343,30 @@ static char *next_mnt(void **v, char *p)
return me->mnt_dir;
}
+static int is_subdirectory(char *child, char *parent)
+{
+ size_t l = strlen(parent);
+
+ if (strcmp(parent, "/") == 0)
+ return 1;
+
+ return strcmp(child, parent) == 0
+ || (strncmp(child, parent, l) == 0 && child[l] == '/');
+}
+
+static int path_matches(nfs_export *exp, char *path)
+{
+ if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+ return is_subdirectory(path, exp->m_export.e_path);
+ return strcmp(path, exp->m_export.e_path) == 0;
+}
+
+static int
+export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
+{
+ return path_matches(exp, path) && client_matches(exp, dom, ai);
+}
+
/* True iff e1 is a child of e2 and e2 has crossmnt set: */
static bool subexport(struct exportent *e1, struct exportent *e2)
{
@@ -354,8 +374,7 @@ static bool subexport(struct exportent *e1, struct exportent *e2)
size_t l2 = strlen(p2);
return e2->e_flags & NFSEXP_CROSSMOUNT
- && strncmp(p1, p2, l2) == 0
- && p1[l2] == '/';
+ && is_subdirectory(p1, p2);
}
struct parsed_fsid {
@@ -756,27 +775,6 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
return qword_eol(f);
}
-static int is_subdirectory(char *child, char *parent)
-{
- size_t l = strlen(parent);
-
- return strcmp(child, parent) == 0
- || (strncmp(child, parent, l) == 0 && child[l] == '/');
-}
-
-static int path_matches(nfs_export *exp, char *path)
-{
- if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
- return is_subdirectory(path, exp->m_export.e_path);
- return strcmp(path, exp->m_export.e_path) == 0;
-}
-
-static int
-export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
-{
- return path_matches(exp, path) && client_matches(exp, dom, ai);
-}
-
static nfs_export *
lookup_export(char *dom, char *path, struct addrinfo *ai)
{
@@ -830,6 +828,7 @@ lookup_export(char *dom, char *path, struct addrinfo *ai)
#ifdef HAVE_NFS_PLUGIN_H
#include <dlfcn.h>
+#include <link.h>
#include <nfs-plugin.h>
/*
@@ -1094,6 +1093,7 @@ static struct exportent *lookup_junction(char *dom, const char *pathname,
struct addrinfo *ai)
{
struct exportent *exp;
+ struct link_map *map;
void *handle;
handle = dlopen("libnfsjunct.so", RTLD_NOW);
@@ -1101,6 +1101,11 @@ static struct exportent *lookup_junction(char *dom, const char *pathname,
xlog(D_GENERAL, "%s: dlopen: %s", __func__, dlerror());
return NULL;
}
+
+ if (dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0)
+ xlog(D_GENERAL, "%s: loaded plug-in %s",
+ __func__, map->l_name);
+
(void)dlerror(); /* Clear any error */
exp = invoke_junction_ops(handle, dom, pathname, ai);
diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c
index 9801b9c..4334340 100644
--- a/utils/nfsdcltrack/nfsdcltrack.c
+++ b/utils/nfsdcltrack/nfsdcltrack.c
@@ -379,6 +379,17 @@ cltrack_legacy_gracedone(void)
while ((entry = readdir(v4recovery))) {
int len;
+ /* skip "." and ".." */
+ if (entry->d_name[0] == '.') {
+ switch (entry->d_name[1]) {
+ case '\0':
+ continue;
+ case '.':
+ if (entry->d_name[2] == '\0')
+ continue;
+ }
+ }
+
/* borrow the clientid blob for this */
len = snprintf((char *)blob, sizeof(blob), "%s/%s", dirname,
entry->d_name);
diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c
index 4ecb03c..fd576d9 100644
--- a/utils/statd/rmtcall.c
+++ b/utils/statd/rmtcall.c
@@ -68,21 +68,19 @@ statd_get_socket(void)
{
struct sockaddr_in sin;
struct servent *se;
- int loopcnt = 100;
+ const int loopcnt = 100;
+ int i, tmp_sockets[loopcnt];
if (sockfd >= 0)
return sockfd;
- while (loopcnt-- > 0) {
-
- if (sockfd >= 0) close(sockfd);
+ for (i = 0; i < loopcnt; ++i) {
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
xlog(L_ERROR, "%s: Can't create socket: %m", __func__);
- return -1;
+ break;
}
-
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -96,7 +94,16 @@ statd_get_socket(void)
if (se == NULL)
break;
/* rather not use that port, try again */
+
+ tmp_sockets[i] = sockfd;
}
+
+ while (--i >= 0)
+ close(tmp_sockets[i]);
+
+ if (sockfd < 0)
+ return -1;
+
FD_SET(sockfd, &SVC_FDSET);
return sockfd;
}