Blob Blame History Raw
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/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/cache.c b/utils/mountd/cache.c
index e950ec6..c13f305 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -109,12 +109,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 +125,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);
 
 }
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);