import nfs-utils-2.3.3-46.el8
This commit is contained in:
		
							parent
							
								
									729a14eba8
								
							
						
					
					
						commit
						0d15ecad00
					
				
							
								
								
									
										43
									
								
								SOURCES/nfs-utils-2.3.3-exportfs-root.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								SOURCES/nfs-utils-2.3.3-exportfs-root.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| commit ac266e2edc4f40eef810d52c72657b645e4010db | ||||
| Author: Ondrej Mosnacek <omosnace@redhat.com> | ||||
| Date:   Tue Apr 6 15:57:37 2021 -0400 | ||||
| 
 | ||||
|     exportfs: fix unexporting of '/' | ||||
|      | ||||
|     The code that has been added to strip trailing slashes from path in | ||||
|     unexportfs_parsed() forgot to account for the case of the root | ||||
|     directory, which is simply '/'. In that case it accesses path[-1] and | ||||
|     reduces the path to an empty string, which then fails to match any | ||||
|     export. | ||||
|      | ||||
|     Fix it by stopping the stripping when the path is just a single | ||||
|     character - it doesn't matter if it's a '/' or not, we want to keep it | ||||
|     either way in that case. | ||||
|      | ||||
|     Reproducer: | ||||
|      | ||||
|         exportfs localhost:/ | ||||
|         exportfs -u localhost:/ | ||||
|      | ||||
|     Without this patch, the unexport step fails with "exportfs: Could not | ||||
|     find 'localhost:/' to unexport." | ||||
|      | ||||
|     Fixes: a9a7728d8743 ("exportfs: Deal with path's trailing "/" in unexportfs_parsed()") | ||||
|     Link: https://bugzilla.redhat.com/show_bug.cgi?id=1941171 | ||||
|      | ||||
|     Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> | ||||
|     Signed-off-by: Steve Dickson <steved@redhat.com> | ||||
| 
 | ||||
| diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
 | ||||
| index 262dd19a..25d757d8 100644
 | ||||
| --- a/utils/exportfs/exportfs.c
 | ||||
| +++ b/utils/exportfs/exportfs.c
 | ||||
| @@ -383,7 +383,7 @@ unexportfs_parsed(char *hname, char *path, int verbose)
 | ||||
|  	 * so need to deal with it. | ||||
|  	*/ | ||||
|  	size_t nlen = strlen(path); | ||||
| -	while (path[nlen - 1] == '/')
 | ||||
| +	while ((nlen > 1) && (path[nlen - 1] == '/'))
 | ||||
|  		nlen--; | ||||
|   | ||||
|  	for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) { | ||||
							
								
								
									
										290
									
								
								SOURCES/nfs-utils-2.3.3-gssd-debug-cleanup.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								SOURCES/nfs-utils-2.3.3-gssd-debug-cleanup.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,290 @@ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/err_util.c.orig nfs-utils-2.3.3/utils/gssd/err_util.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/err_util.c.orig	2018-09-06 14:09:08.000000000 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/err_util.c	2021-07-19 12:29:21.366829573 -0400
 | ||||
| @@ -70,3 +70,17 @@ int get_verbosity(void)
 | ||||
|  { | ||||
|  	return verbosity; | ||||
|  } | ||||
| +
 | ||||
| +char * 
 | ||||
| +sec2time(int value)
 | ||||
| +{
 | ||||
| +    static char buf[BUFSIZ];
 | ||||
| +    int hr, min, sec;
 | ||||
| +
 | ||||
| +    hr = (value / 3600);
 | ||||
| +    min = (value  - (3600*hr))/60;
 | ||||
| +    sec = (value  - (3600*hr) - (min*60));
 | ||||
| +    sprintf(buf, "%dh:%dm:%ds", hr, min, sec);
 | ||||
| +    return(buf);
 | ||||
| +}
 | ||||
| +
 | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/err_util.h.orig nfs-utils-2.3.3/utils/gssd/err_util.h
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/err_util.h.orig	2018-09-06 14:09:08.000000000 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/err_util.h	2021-07-19 12:29:21.367829599 -0400
 | ||||
| @@ -34,5 +34,6 @@
 | ||||
|  void initerr(char *progname, int verbosity, int fg); | ||||
|  void printerr(int priority, char *format, ...); | ||||
|  int get_verbosity(void); | ||||
| +char * sec2time(int);
 | ||||
|   | ||||
|  #endif /* _ERR_UTIL_H_ */ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.c.orig nfs-utils-2.3.3/utils/gssd/gssd.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.c.orig	2021-07-19 12:24:13.963644016 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.c	2021-07-19 12:29:21.368829626 -0400
 | ||||
| @@ -396,7 +396,7 @@ gssd_free_client(struct clnt_info *clp)
 | ||||
|  	if (refcnt > 0) | ||||
|  		return; | ||||
|   | ||||
| -	printerr(3, "freeing client %s\n", clp->relpath);
 | ||||
| +	printerr(4, "freeing client %s\n", clp->relpath);
 | ||||
|   | ||||
|  	if (clp->krb5_fd >= 0) | ||||
|  		close(clp->krb5_fd); | ||||
| @@ -417,7 +417,7 @@ gssd_free_client(struct clnt_info *clp)
 | ||||
|  static void | ||||
|  gssd_destroy_client(struct clnt_info *clp) | ||||
|  { | ||||
| -	printerr(3, "destroying client %s\n", clp->relpath);
 | ||||
| +	printerr(4, "destroying client %s\n", clp->relpath);
 | ||||
|   | ||||
|  	if (clp->krb5_ev) { | ||||
|  		event_del(clp->krb5_ev); | ||||
| @@ -494,7 +494,7 @@ scan_active_thread_list(void)
 | ||||
|  			 * upcall_thread_info from the list and free it. | ||||
|  			 */ | ||||
|  			if (tret == PTHREAD_CANCELED) | ||||
| -				printerr(3, "watchdog: thread id 0x%lx cancelled successfully\n",
 | ||||
| +				printerr(2, "watchdog: thread id 0x%lx cancelled successfully\n",
 | ||||
|  						info->tid); | ||||
|  			saveprev = info->list.tqe_prev; | ||||
|  			TAILQ_REMOVE(&active_thread_list, info, list); | ||||
| @@ -783,7 +783,7 @@ gssd_scan(void)
 | ||||
|  { | ||||
|  	struct dirent *d; | ||||
|   | ||||
| -	printerr(3, "doing a full rescan\n");
 | ||||
| +	printerr(4, "doing a full rescan\n");
 | ||||
|  	rewinddir(pipefs_dir); | ||||
|   | ||||
|  	while ((d = readdir(pipefs_dir))) { | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd_proc.c.orig nfs-utils-2.3.3/utils/gssd/gssd_proc.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd_proc.c.orig	2021-07-19 12:24:13.964644043 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd_proc.c	2021-07-19 12:29:21.368829626 -0400
 | ||||
| @@ -166,8 +166,9 @@ do_downcall(int k5_fd, uid_t uid, struct
 | ||||
|  	unsigned int buf_size = 0; | ||||
|  	pthread_t tid = pthread_self(); | ||||
|   | ||||
| -	printerr(2, "do_downcall(0x%x): lifetime_rec=%u acceptor=%.*s\n",
 | ||||
| -		tid, lifetime_rec, acceptor->length, acceptor->value);
 | ||||
| +	if (get_verbosity() > 1)
 | ||||
| +		printerr(2, "do_downcall(0x%lx): lifetime_rec=%s acceptor=%.*s\n",
 | ||||
| +			tid, sec2time(lifetime_rec), acceptor->length, acceptor->value);
 | ||||
|  	buf_size = sizeof(uid) + sizeof(timeout) + sizeof(pd->pd_seq_win) + | ||||
|  		sizeof(pd->pd_ctx_hndl.length) + pd->pd_ctx_hndl.length + | ||||
|  		sizeof(context_token->length) + context_token->length + | ||||
| @@ -193,7 +194,7 @@ do_downcall(int k5_fd, uid_t uid, struct
 | ||||
|  	return; | ||||
|  out_err: | ||||
|  	free(buf); | ||||
| -	printerr(1, "do_downcall(0x%x): Failed to write downcall!\n", tid);
 | ||||
| +	printerr(1, "do_downcall(0x%lx): Failed to write downcall!\n", tid);
 | ||||
|  	return; | ||||
|  } | ||||
|   | ||||
| @@ -204,8 +205,9 @@ do_error_downcall(int k5_fd, uid_t uid,
 | ||||
|  	char	*p = buf, *end = buf + 1024; | ||||
|  	unsigned int timeout = 0; | ||||
|  	int	zero = 0; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
| -	printerr(2, "doing error downcall\n");
 | ||||
| +	printerr(2, "do_error_downcall(0x%lx): uid %d err %d\n", tid, uid, err);
 | ||||
|   | ||||
|  	if (WRITE_BYTES(&p, end, uid)) goto out_err; | ||||
|  	if (WRITE_BYTES(&p, end, timeout)) goto out_err; | ||||
| @@ -328,6 +330,7 @@ create_auth_rpc_client(struct clnt_info
 | ||||
|  	struct timeval	timeout; | ||||
|  	struct sockaddr		*addr = (struct sockaddr *) &clp->addr; | ||||
|  	socklen_t		salen; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
|  	sec.qop = GSS_C_QOP_DEFAULT; | ||||
|  	sec.svc = RPCSEC_GSS_SVC_NONE; | ||||
| @@ -361,8 +364,8 @@ create_auth_rpc_client(struct clnt_info
 | ||||
|   | ||||
|  	/* create an rpc connection to the nfs server */ | ||||
|   | ||||
| -	printerr(2, "creating %s client for server %s\n", clp->protocol,
 | ||||
| -			clp->servername);
 | ||||
| +	printerr(3, "create_auth_rpc_client(0x%lx): creating %s client for server %s\n", 
 | ||||
| +		tid, clp->protocol, clp->servername);
 | ||||
|   | ||||
|  	protocol = IPPROTO_TCP; | ||||
|  	if ((strcmp(clp->protocol, "udp")) == 0) | ||||
| @@ -405,7 +408,8 @@ create_auth_rpc_client(struct clnt_info
 | ||||
|  	if (!tgtname) | ||||
|  		tgtname = clp->servicename; | ||||
|   | ||||
| -	printerr(2, "creating context with server %s\n", tgtname);
 | ||||
| +	printerr(3, "create_auth_rpc_client(0x%lx): creating context with server %s\n", 
 | ||||
| +		tid, tgtname);
 | ||||
|  	auth = authgss_create_default(rpc_clnt, tgtname, &sec); | ||||
|  	if (!auth) { | ||||
|  		/* Our caller should print appropriate message */ | ||||
| @@ -507,9 +511,10 @@ krb5_not_machine_creds(struct clnt_info
 | ||||
|  	gss_cred_id_t	gss_cred; | ||||
|  	char		**dname; | ||||
|  	int		err, resp = -1; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
| -	printerr(2, "krb5_not_machine_creds: uid %d tgtname %s\n", 
 | ||||
| -		uid, tgtname);
 | ||||
| +	printerr(2, "krb5_not_machine_creds(0x%lx): uid %d tgtname %s\n", 
 | ||||
| +		tid, uid, tgtname);
 | ||||
|   | ||||
|  	*chg_err = change_identity(uid); | ||||
|  	if (*chg_err) { | ||||
| @@ -555,9 +560,10 @@ krb5_use_machine_creds(struct clnt_info
 | ||||
|  	char	**ccname; | ||||
|  	int	nocache = 0; | ||||
|  	int	success = 0; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
| -	printerr(2, "krb5_use_machine_creds: uid %d tgtname %s\n", 
 | ||||
| -		uid, tgtname);
 | ||||
| +	printerr(2, "krb5_use_machine_creds(0x%lx): uid %d tgtname %s\n", 
 | ||||
| +		tid, uid, tgtname);
 | ||||
|   | ||||
|  	do { | ||||
|  		gssd_refresh_krb5_machine_credential(clp->servername, | ||||
| @@ -874,6 +880,7 @@ start_upcall_thread(void (*func)(struct
 | ||||
|  	pthread_t th; | ||||
|  	struct upcall_thread_info *tinfo; | ||||
|  	int ret; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
|  	tinfo = alloc_upcall_thread_info(); | ||||
|  	if (!tinfo) | ||||
| @@ -896,6 +903,9 @@ start_upcall_thread(void (*func)(struct
 | ||||
|  		free(tinfo); | ||||
|  		return ret; | ||||
|  	} | ||||
| +	printerr(2, "start_upcall_thread(0x%lx): created thread id 0x%lx\n", 
 | ||||
| +		tid, th);
 | ||||
| +
 | ||||
|  	tinfo->tid = th; | ||||
|  	pthread_mutex_lock(&active_thread_list_lock); | ||||
|  	clock_gettime(CLOCK_MONOTONIC, &tinfo->timeout); | ||||
| @@ -958,7 +968,7 @@ handle_gssd_upcall(struct clnt_info *clp
 | ||||
|  	} | ||||
|  	lbuf[lbuflen-1] = 0; | ||||
|   | ||||
| -	printerr(2, "\n%s(0x%x): '%s' (%s)\n", __func__, tid,
 | ||||
| +	printerr(2, "\n%s(0x%lx): '%s' (%s)\n", __func__, tid,
 | ||||
|  		 lbuf, clp->relpath); | ||||
|   | ||||
|  	for (p = strtok(lbuf, " "); p; p = strtok(NULL, " ")) { | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/krb5_util.c.orig nfs-utils-2.3.3/utils/gssd/krb5_util.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/krb5_util.c.orig	2021-07-19 12:24:13.951643697 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/krb5_util.c	2021-07-19 12:36:27.746223992 -0400
 | ||||
| @@ -375,6 +375,7 @@ gssd_get_single_krb5_cred(krb5_context c
 | ||||
|  	char *cache_type; | ||||
|  	char *pname = NULL; | ||||
|  	char *k5err = NULL; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
|  	memset(&my_creds, 0, sizeof(my_creds)); | ||||
|   | ||||
| @@ -385,8 +386,8 @@ gssd_get_single_krb5_cred(krb5_context c
 | ||||
|  	now += 300; | ||||
|  	pthread_mutex_lock(&ple_lock); | ||||
|  	if (ple->ccname && ple->endtime > now && !nocache) { | ||||
| -		printerr(3, "INFO: Credentials in CC '%s' are good until %d\n",
 | ||||
| -			 ple->ccname, ple->endtime);
 | ||||
| +		printerr(3, "%s(0x%lx): Credentials in CC '%s' are good until %s",
 | ||||
| +			 __func__, tid, ple->ccname, ctime((time_t *)&ple->endtime));
 | ||||
|  		code = 0; | ||||
|  		pthread_mutex_unlock(&ple_lock); | ||||
|  		goto out; | ||||
| @@ -486,7 +487,8 @@ gssd_get_single_krb5_cred(krb5_context c
 | ||||
|  	} | ||||
|   | ||||
|  	code = 0; | ||||
| -	printerr(2, "%s: principal '%s' ccache:'%s'\n", __func__, pname, cc_name);
 | ||||
| +	printerr(2, "%s(0x%lx): principal '%s' ccache:'%s'\n", 
 | ||||
| +		__func__, tid, pname, cc_name);
 | ||||
|    out: | ||||
|  #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS | ||||
|  	if (init_opts) | ||||
| @@ -615,6 +617,7 @@ get_full_hostname(const char *inhost, ch
 | ||||
|  	struct addrinfo hints; | ||||
|  	int retval; | ||||
|  	char *c; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
|  	memset(&hints, 0, sizeof(hints)); | ||||
|  	hints.ai_socktype = SOCK_STREAM; | ||||
| @@ -624,8 +627,8 @@ get_full_hostname(const char *inhost, ch
 | ||||
|  	/* Get full target hostname */ | ||||
|  	retval = getaddrinfo(inhost, NULL, &hints, &addrs); | ||||
|  	if (retval) { | ||||
| -		printerr(1, "%s while getting full hostname for '%s'\n",
 | ||||
| -			 gai_strerror(retval), inhost);
 | ||||
| +		printerr(1, "%s(0x%lx): getaddrinfo(%s) failed: %s\n",
 | ||||
| +			 __func__, tid, inhost, gai_strerror(retval));
 | ||||
|  		goto out; | ||||
|  	} | ||||
|  	strncpy(outhost, addrs->ai_canonname, outhostlen); | ||||
| @@ -633,7 +636,10 @@ get_full_hostname(const char *inhost, ch
 | ||||
|  	for (c = outhost; *c != '\0'; c++) | ||||
|  	    *c = tolower(*c); | ||||
|   | ||||
| -	printerr(3, "Full hostname for '%s' is '%s'\n", inhost, outhost);
 | ||||
| +	if (get_verbosity() && strcmp(inhost, outhost))
 | ||||
| +		printerr(1, "%s(0x%0lx): inhost '%s' different than outhost'%s'\n", 
 | ||||
| +			inhost, outhost);
 | ||||
| +
 | ||||
|  	retval = 0; | ||||
|  out: | ||||
|  	return retval; | ||||
| @@ -819,6 +825,7 @@ find_keytab_entry(krb5_context context,
 | ||||
|  	krb5_principal princ; | ||||
|  	const char *notsetstr = "not set"; | ||||
|  	char *adhostoverride = NULL; | ||||
| +	pthread_t tid = pthread_self();
 | ||||
|   | ||||
|   | ||||
|  	/* Get full target hostname */ | ||||
| @@ -972,7 +979,7 @@ find_keytab_entry(krb5_context context,
 | ||||
|  					tried_upper = 1; | ||||
|  				} | ||||
|  			} else { | ||||
| -				printerr(2, "Success getting keytab entry for '%s'\n",spn);
 | ||||
| +				printerr(2, "find_keytab_entry(0x%lx): Success getting keytab entry for '%s'\n",tid, spn);
 | ||||
|  				retval = 0; | ||||
|  				goto out; | ||||
|  			} | ||||
| @@ -1113,9 +1120,6 @@ gssd_refresh_krb5_machine_credential_int
 | ||||
|  	char *k5err = NULL; | ||||
|  	const char *svcnames[] = { "$", "root", "nfs", "host", NULL }; | ||||
|   | ||||
| -	printerr(2, "%s: hostname=%s ple=%p service=%s srchost=%s\n",
 | ||||
| -		__func__, hostname, ple, service, srchost);
 | ||||
| -
 | ||||
|  	/* | ||||
|  	 * If a specific service name was specified, use it. | ||||
|  	 * Otherwise, use the default list. | ||||
| @@ -1124,9 +1128,10 @@ gssd_refresh_krb5_machine_credential_int
 | ||||
|  		svcnames[0] = service; | ||||
|  		svcnames[1] = NULL; | ||||
|  	} | ||||
| -	if (hostname == NULL && ple == NULL)
 | ||||
| +	if (hostname == NULL && ple == NULL) {
 | ||||
| +		printerr(0, "ERROR: %s: Invalid args\n", __func__);
 | ||||
|  		return EINVAL; | ||||
| -
 | ||||
| +	}
 | ||||
|  	code = krb5_init_context(&context); | ||||
|  	if (code) { | ||||
|  		k5err = gssd_k5_err_msg(NULL, code); | ||||
							
								
								
									
										402
									
								
								SOURCES/nfs-utils-2.3.3-gssd-failed-thread.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								SOURCES/nfs-utils-2.3.3-gssd-failed-thread.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,402 @@ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.c.orig nfs-utils-2.3.3/utils/gssd/gssd.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.c.orig	2021-07-19 09:39:04.273895536 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.c	2021-07-19 09:40:13.942751214 -0400
 | ||||
| @@ -364,7 +364,7 @@ out:
 | ||||
|  /* Actually frees clp and fields that might be used from other | ||||
|   * threads if was last reference. | ||||
|   */ | ||||
| -static void
 | ||||
| +void
 | ||||
|  gssd_free_client(struct clnt_info *clp) | ||||
|  { | ||||
|  	int refcnt; | ||||
| @@ -416,55 +416,6 @@ gssd_destroy_client(struct clnt_info *cl
 | ||||
|   | ||||
|  static void gssd_scan(void); | ||||
|   | ||||
| -static int
 | ||||
| -start_upcall_thread(void (*func)(struct clnt_upcall_info *), void *info)
 | ||||
| -{
 | ||||
| -	pthread_attr_t attr;
 | ||||
| -	pthread_t th;
 | ||||
| -	int ret;
 | ||||
| -
 | ||||
| -	ret = pthread_attr_init(&attr);
 | ||||
| -	if (ret != 0) {
 | ||||
| -		printerr(0, "ERROR: failed to init pthread attr: ret %d: %s\n",
 | ||||
| -			 ret, strerror(errno));
 | ||||
| -		return ret;
 | ||||
| -	}
 | ||||
| -	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | ||||
| -	if (ret != 0) {
 | ||||
| -		printerr(0, "ERROR: failed to create pthread attr: ret %d: "
 | ||||
| -			 "%s\n", ret, strerror(errno));
 | ||||
| -		return ret;
 | ||||
| -	}
 | ||||
| -
 | ||||
| -	ret = pthread_create(&th, &attr, (void *)func, (void *)info);
 | ||||
| -	if (ret != 0)
 | ||||
| -		printerr(0, "ERROR: pthread_create failed: ret %d: %s\n",
 | ||||
| -			 ret, strerror(errno));
 | ||||
| -	return ret;
 | ||||
| -}
 | ||||
| -
 | ||||
| -static struct clnt_upcall_info *alloc_upcall_info(struct clnt_info *clp)
 | ||||
| -{
 | ||||
| -	struct clnt_upcall_info *info;
 | ||||
| -
 | ||||
| -	info = malloc(sizeof(struct clnt_upcall_info));
 | ||||
| -	if (info == NULL)
 | ||||
| -		return NULL;
 | ||||
| -
 | ||||
| -	pthread_mutex_lock(&clp_lock);
 | ||||
| -	clp->refcount++;
 | ||||
| -	pthread_mutex_unlock(&clp_lock);
 | ||||
| -	info->clp = clp;
 | ||||
| -
 | ||||
| -	return info;
 | ||||
| -}
 | ||||
| -
 | ||||
| -void free_upcall_info(struct clnt_upcall_info *info)
 | ||||
| -{
 | ||||
| -	gssd_free_client(info->clp);
 | ||||
| -	free(info);
 | ||||
| -}
 | ||||
| -
 | ||||
|  /* For each upcall read the upcall info into the buffer, then create a | ||||
|   * thread in a detached state so that resources are released back into | ||||
|   * the system without the need for a join. | ||||
| @@ -473,44 +424,16 @@ static void
 | ||||
|  gssd_clnt_gssd_cb(int UNUSED(fd), short UNUSED(which), void *data) | ||||
|  { | ||||
|  	struct clnt_info *clp = data; | ||||
| -	struct clnt_upcall_info *info;
 | ||||
| -
 | ||||
| -	info = alloc_upcall_info(clp);
 | ||||
| -	if (info == NULL)
 | ||||
| -		return;
 | ||||
| -
 | ||||
| -	info->lbuflen = read(clp->gssd_fd, info->lbuf, sizeof(info->lbuf));
 | ||||
| -	if (info->lbuflen <= 0 || info->lbuf[info->lbuflen-1] != '\n') {
 | ||||
| -		printerr(0, "WARNING: %s: failed reading request\n", __func__);
 | ||||
| -		free_upcall_info(info);
 | ||||
| -		return;
 | ||||
| -	}
 | ||||
| -	info->lbuf[info->lbuflen-1] = 0;
 | ||||
|   | ||||
| -	if (start_upcall_thread(handle_gssd_upcall, info))
 | ||||
| -		free_upcall_info(info);
 | ||||
| +	handle_gssd_upcall(clp);
 | ||||
|  } | ||||
|   | ||||
|  static void | ||||
|  gssd_clnt_krb5_cb(int UNUSED(fd), short UNUSED(which), void *data) | ||||
|  { | ||||
|  	struct clnt_info *clp = data; | ||||
| -	struct clnt_upcall_info *info;
 | ||||
| -
 | ||||
| -	info = alloc_upcall_info(clp);
 | ||||
| -	if (info == NULL)
 | ||||
| -		return;
 | ||||
| -
 | ||||
| -	if (read(clp->krb5_fd, &info->uid,
 | ||||
| -			sizeof(info->uid)) < (ssize_t)sizeof(info->uid)) {
 | ||||
| -		printerr(0, "WARNING: %s: failed reading uid from krb5 "
 | ||||
| -			 "upcall pipe: %s\n", __func__, strerror(errno));
 | ||||
| -		free_upcall_info(info);
 | ||||
| -		return;
 | ||||
| -	}
 | ||||
|   | ||||
| -	if (start_upcall_thread(handle_krb5_upcall, info))
 | ||||
| -		free_upcall_info(info);
 | ||||
| +	handle_krb5_upcall(clp);
 | ||||
|  } | ||||
|   | ||||
|  static struct clnt_info * | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.h.orig nfs-utils-2.3.3/utils/gssd/gssd.h
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.h.orig	2021-07-19 09:39:04.269895430 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.h	2021-07-19 09:40:13.943751240 -0400
 | ||||
| @@ -84,14 +84,17 @@ struct clnt_info {
 | ||||
|   | ||||
|  struct clnt_upcall_info { | ||||
|  	struct clnt_info 	*clp; | ||||
| -	char			lbuf[RPC_CHAN_BUF_SIZE];
 | ||||
| -	int			lbuflen;
 | ||||
|  	uid_t			uid; | ||||
| +	int			fd;
 | ||||
| +	char			*srchost;
 | ||||
| +	char			*target;
 | ||||
| +	char			*service;
 | ||||
|  }; | ||||
|   | ||||
| -void handle_krb5_upcall(struct clnt_upcall_info *clp);
 | ||||
| -void handle_gssd_upcall(struct clnt_upcall_info *clp);
 | ||||
| +void handle_krb5_upcall(struct clnt_info *clp);
 | ||||
| +void handle_gssd_upcall(struct clnt_info *clp);
 | ||||
|  void free_upcall_info(struct clnt_upcall_info *info); | ||||
| +void gssd_free_client(struct clnt_info *clp);
 | ||||
|   | ||||
|   | ||||
|  #endif /* _RPC_GSSD_H_ */ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd_proc.c.orig nfs-utils-2.3.3/utils/gssd/gssd_proc.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd_proc.c.orig	2021-07-19 09:39:04.269895430 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd_proc.c	2021-07-19 09:40:13.944751267 -0400
 | ||||
| @@ -80,6 +80,8 @@
 | ||||
|  #include "nfslib.h" | ||||
|  #include "gss_names.h" | ||||
|   | ||||
| +extern pthread_mutex_t clp_lock;
 | ||||
| +
 | ||||
|  /* Encryption types supported by the kernel rpcsec_gss code */ | ||||
|  int num_krb5_enctypes = 0; | ||||
|  krb5_enctype *krb5_enctypes = NULL; | ||||
| @@ -719,22 +721,133 @@ out_return_error:
 | ||||
|  	goto out; | ||||
|  } | ||||
|   | ||||
| -void
 | ||||
| -handle_krb5_upcall(struct clnt_upcall_info *info)
 | ||||
| -{
 | ||||
| -	struct clnt_info *clp = info->clp;
 | ||||
| +static struct clnt_upcall_info *
 | ||||
| +alloc_upcall_info(struct clnt_info *clp, uid_t uid, int fd, char *srchost,
 | ||||
| +		  char *target, char *service)
 | ||||
| +{
 | ||||
| +	struct clnt_upcall_info *info;
 | ||||
| +
 | ||||
| +	info = malloc(sizeof(struct clnt_upcall_info));
 | ||||
| +	if (info == NULL)
 | ||||
| +		return NULL;
 | ||||
| +
 | ||||
| +	memset(info, 0, sizeof(*info));
 | ||||
| +	pthread_mutex_lock(&clp_lock);
 | ||||
| +	clp->refcount++;
 | ||||
| +	pthread_mutex_unlock(&clp_lock);
 | ||||
| +	info->clp = clp;
 | ||||
| +	info->uid = uid;
 | ||||
| +	info->fd = fd;
 | ||||
| +	if (srchost) {
 | ||||
| +		info->srchost = strdup(srchost);
 | ||||
| +		if (info->srchost == NULL)
 | ||||
| +			goto out_info;
 | ||||
| +	}
 | ||||
| +	if (target) {
 | ||||
| +		info->target = strdup(target);
 | ||||
| +		if (info->target == NULL)
 | ||||
| +			goto out_srchost;
 | ||||
| +	}
 | ||||
| +	if (service) {
 | ||||
| +		info->service = strdup(service);
 | ||||
| +		if (info->service == NULL)
 | ||||
| +			goto out_target;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +out:
 | ||||
| +	return info;
 | ||||
|   | ||||
| -	printerr(2, "\n%s: uid %d (%s)\n", __func__, info->uid, clp->relpath);
 | ||||
| +out_target:
 | ||||
| +	if (info->target)
 | ||||
| +		free(info->target);
 | ||||
| +out_srchost:
 | ||||
| +	if (info->srchost)
 | ||||
| +		free(info->srchost);
 | ||||
| +out_info:
 | ||||
| +	free(info);
 | ||||
| +	info = NULL;
 | ||||
| +	goto out;
 | ||||
| +}
 | ||||
| +
 | ||||
| +void free_upcall_info(struct clnt_upcall_info *info)
 | ||||
| +{
 | ||||
| +	gssd_free_client(info->clp);
 | ||||
| +	if (info->service)
 | ||||
| +		free(info->service);
 | ||||
| +	if (info->target)
 | ||||
| +		free(info->target);
 | ||||
| +	if (info->srchost)
 | ||||
| +		free(info->srchost);
 | ||||
| +	free(info);
 | ||||
| +}
 | ||||
|   | ||||
| -	process_krb5_upcall(clp, info->uid, clp->krb5_fd, NULL, NULL, NULL);
 | ||||
| +static void
 | ||||
| +gssd_work_thread_fn(struct clnt_upcall_info *info)
 | ||||
| +{
 | ||||
| +	process_krb5_upcall(info->clp, info->uid, info->fd, info->srchost, info->target, info->service);
 | ||||
|  	free_upcall_info(info); | ||||
|  } | ||||
|   | ||||
| +static int
 | ||||
| +start_upcall_thread(void (*func)(struct clnt_upcall_info *), void *info)
 | ||||
| +{
 | ||||
| +	pthread_attr_t attr;
 | ||||
| +	pthread_t th;
 | ||||
| +	int ret;
 | ||||
| +
 | ||||
| +	ret = pthread_attr_init(&attr);
 | ||||
| +	if (ret != 0) {
 | ||||
| +		printerr(0, "ERROR: failed to init pthread attr: ret %d: %s\n",
 | ||||
| +			 ret, strerror(errno));
 | ||||
| +		return ret;
 | ||||
| +	}
 | ||||
| +	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | ||||
| +	if (ret != 0) {
 | ||||
| +		printerr(0, "ERROR: failed to create pthread attr: ret %d: "
 | ||||
| +			 "%s\n", ret, strerror(errno));
 | ||||
| +		return ret;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ret = pthread_create(&th, &attr, (void *)func, (void *)info);
 | ||||
| +	if (ret != 0)
 | ||||
| +		printerr(0, "ERROR: pthread_create failed: ret %d: %s\n",
 | ||||
| +			 ret, strerror(errno));
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
|  void | ||||
| -handle_gssd_upcall(struct clnt_upcall_info *info)
 | ||||
| +handle_krb5_upcall(struct clnt_info *clp)
 | ||||
|  { | ||||
| -	struct clnt_info	*clp = info->clp;
 | ||||
|  	uid_t			uid; | ||||
| +	struct clnt_upcall_info	*info;
 | ||||
| +	int			err;
 | ||||
| +
 | ||||
| +	if (read(clp->krb5_fd, &uid, sizeof(uid)) < (ssize_t)sizeof(uid)) {
 | ||||
| +		printerr(0, "WARNING: failed reading uid from krb5 "
 | ||||
| +			    "upcall pipe: %s\n", strerror(errno));
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +	printerr(2, "\n%s: uid %d (%s)\n", __func__, uid, clp->relpath);
 | ||||
| +
 | ||||
| +	info = alloc_upcall_info(clp, uid, clp->krb5_fd, NULL, NULL, NULL);
 | ||||
| +	if (info == NULL) {
 | ||||
| +		printerr(0, "%s: failed to allocate clnt_upcall_info\n", __func__);
 | ||||
| +		do_error_downcall(clp->krb5_fd, uid, -EACCES);
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +	err = start_upcall_thread(gssd_work_thread_fn, info);
 | ||||
| +	if (err != 0) {
 | ||||
| +		do_error_downcall(clp->krb5_fd, uid, -EACCES);
 | ||||
| +		free_upcall_info(info);
 | ||||
| +	}
 | ||||
| +}
 | ||||
| +
 | ||||
| +void
 | ||||
| +handle_gssd_upcall(struct clnt_info *clp)
 | ||||
| +{
 | ||||
| +	uid_t			uid;
 | ||||
| +	char			lbuf[RPC_CHAN_BUF_SIZE];
 | ||||
| +	int			lbuflen = 0;
 | ||||
|  	char			*p; | ||||
|  	char			*mech = NULL; | ||||
|  	char			*uidstr = NULL; | ||||
| @@ -742,20 +855,22 @@ handle_gssd_upcall(struct clnt_upcall_in
 | ||||
|  	char			*service = NULL; | ||||
|  	char			*srchost = NULL; | ||||
|  	char			*enctypes = NULL; | ||||
| -	char			*upcall_str;
 | ||||
| -	char			*pbuf = info->lbuf;
 | ||||
|  	pthread_t tid = pthread_self(); | ||||
| +	struct clnt_upcall_info	*info;
 | ||||
| +	int			err;
 | ||||
|   | ||||
| -	printerr(2, "\n%s(0x%x): '%s' (%s)\n", __func__, tid, 
 | ||||
| -		info->lbuf, clp->relpath);
 | ||||
| -
 | ||||
| -	upcall_str = strdup(info->lbuf);
 | ||||
| -	if (upcall_str == NULL) {
 | ||||
| -		printerr(0, "ERROR: malloc failure\n");
 | ||||
| -		goto out_nomem;
 | ||||
| +	lbuflen = read(clp->gssd_fd, lbuf, sizeof(lbuf));
 | ||||
| +	if (lbuflen <= 0 || lbuf[lbuflen-1] != '\n') {
 | ||||
| +		printerr(0, "WARNING: handle_gssd_upcall: "
 | ||||
| +			    "failed reading request\n");
 | ||||
| +		return;
 | ||||
|  	} | ||||
| +	lbuf[lbuflen-1] = 0;
 | ||||
| +
 | ||||
| +	printerr(2, "\n%s(0x%x): '%s' (%s)\n", __func__, tid,
 | ||||
| +		 lbuf, clp->relpath);
 | ||||
|   | ||||
| -	while ((p = strsep(&pbuf, " "))) {
 | ||||
| +	for (p = strtok(lbuf, " "); p; p = strtok(NULL, " ")) {
 | ||||
|  		if (!strncmp(p, "mech=", strlen("mech="))) | ||||
|  			mech = p + strlen("mech="); | ||||
|  		else if (!strncmp(p, "uid=", strlen("uid="))) | ||||
| @@ -773,8 +888,8 @@ handle_gssd_upcall(struct clnt_upcall_in
 | ||||
|  	if (!mech || strlen(mech) < 1) { | ||||
|  		printerr(0, "WARNING: handle_gssd_upcall: " | ||||
|  			    "failed to find gss mechanism name " | ||||
| -			    "in upcall string '%s'\n", upcall_str);
 | ||||
| -		goto out;
 | ||||
| +			    "in upcall string '%s'\n", lbuf);
 | ||||
| +		return;
 | ||||
|  	} | ||||
|   | ||||
|  	if (uidstr) { | ||||
| @@ -786,21 +901,21 @@ handle_gssd_upcall(struct clnt_upcall_in
 | ||||
|  	if (!uidstr) { | ||||
|  		printerr(0, "WARNING: handle_gssd_upcall: " | ||||
|  			    "failed to find uid " | ||||
| -			    "in upcall string '%s'\n", upcall_str);
 | ||||
| -		goto out;
 | ||||
| +			    "in upcall string '%s'\n", lbuf);
 | ||||
| +		return;
 | ||||
|  	} | ||||
|   | ||||
|  	if (enctypes && parse_enctypes(enctypes) != 0) { | ||||
|  		printerr(0, "WARNING: handle_gssd_upcall: " | ||||
|  			 "parsing encryption types failed: errno %d\n", errno); | ||||
| -		goto out;
 | ||||
| +		return;
 | ||||
|  	} | ||||
|   | ||||
|  	if (target && strlen(target) < 1) { | ||||
|  		printerr(0, "WARNING: handle_gssd_upcall: " | ||||
|  			 "failed to parse target name " | ||||
| -			 "in upcall string '%s'\n", upcall_str);
 | ||||
| -		goto out;
 | ||||
| +			 "in upcall string '%s'\n", lbuf);
 | ||||
| +		return;
 | ||||
|  	} | ||||
|   | ||||
|  	/* | ||||
| @@ -814,21 +929,26 @@ handle_gssd_upcall(struct clnt_upcall_in
 | ||||
|  	if (service && strlen(service) < 1) { | ||||
|  		printerr(0, "WARNING: handle_gssd_upcall: " | ||||
|  			 "failed to parse service type " | ||||
| -			 "in upcall string '%s'\n", upcall_str);
 | ||||
| -		goto out;
 | ||||
| +			 "in upcall string '%s'\n", lbuf);
 | ||||
| +		return;
 | ||||
|  	} | ||||
|   | ||||
| -	if (strcmp(mech, "krb5") == 0 && clp->servername)
 | ||||
| -		process_krb5_upcall(clp, uid, clp->gssd_fd, srchost, target, service);
 | ||||
| -	else {
 | ||||
| +	if (strcmp(mech, "krb5") == 0 && clp->servername) {
 | ||||
| +		info = alloc_upcall_info(clp, uid, clp->gssd_fd, srchost, target, service);
 | ||||
| +		if (info == NULL) {
 | ||||
| +			printerr(0, "%s: failed to allocate clnt_upcall_info\n", __func__);
 | ||||
| +			do_error_downcall(clp->gssd_fd, uid, -EACCES);
 | ||||
| +			return;
 | ||||
| +		}
 | ||||
| +		err = start_upcall_thread(gssd_work_thread_fn, info);
 | ||||
| +		if (err != 0) {
 | ||||
| +			do_error_downcall(clp->gssd_fd, uid, -EACCES);
 | ||||
| +			free_upcall_info(info);
 | ||||
| +		}
 | ||||
| +	} else {
 | ||||
|  		if (clp->servername) | ||||
|  			printerr(0, "WARNING: handle_gssd_upcall: " | ||||
|  				 "received unknown gss mech '%s'\n", mech); | ||||
|  		do_error_downcall(clp->gssd_fd, uid, -EACCES); | ||||
|  	} | ||||
| -out:
 | ||||
| -	free(upcall_str);
 | ||||
| -out_nomem:
 | ||||
| -	free_upcall_info(info);
 | ||||
| -	return;
 | ||||
|  } | ||||
							
								
								
									
										141
									
								
								SOURCES/nfs-utils-2.3.3-gssd-k5identity.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								SOURCES/nfs-utils-2.3.3-gssd-k5identity.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,141 @@ | ||||
| diff -up nfs-utils-2.3.3/nfs.conf.orig nfs-utils-2.3.3/nfs.conf
 | ||||
| --- nfs-utils-2.3.3/nfs.conf.orig	2021-04-17 10:49:23.660184527 -0400
 | ||||
| +++ nfs-utils-2.3.3/nfs.conf	2021-04-17 11:14:41.482108562 -0400
 | ||||
| @@ -21,6 +21,7 @@ use-gss-proxy=1
 | ||||
|  # keytab-file=/etc/krb5.keytab | ||||
|  # cred-cache-directory= | ||||
|  # preferred-realm= | ||||
| +# set-home=1
 | ||||
|  # | ||||
|  [lockd] | ||||
|  # port=0 | ||||
| diff -up nfs-utils-2.3.3/systemd/nfs.conf.man.orig nfs-utils-2.3.3/systemd/nfs.conf.man
 | ||||
| --- nfs-utils-2.3.3/systemd/nfs.conf.man.orig	2021-04-17 10:49:23.696185472 -0400
 | ||||
| +++ nfs-utils-2.3.3/systemd/nfs.conf.man	2021-04-17 11:14:41.483108588 -0400
 | ||||
| @@ -222,7 +222,8 @@ Recognized values:
 | ||||
|  .BR rpc-timeout , | ||||
|  .BR keytab-file , | ||||
|  .BR cred-cache-directory , | ||||
| -.BR preferred-realm .
 | ||||
| +.BR preferred-realm ,
 | ||||
| +.BR set-home .
 | ||||
|   | ||||
|  See | ||||
|  .BR rpc.gssd (8) | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.c.orig nfs-utils-2.3.3/utils/gssd/gssd.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.c.orig	2021-04-17 10:49:23.684185157 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.c	2021-04-17 11:14:41.483108588 -0400
 | ||||
| @@ -87,6 +87,8 @@ unsigned int  context_timeout = 0;
 | ||||
|  unsigned int  rpc_timeout = 5; | ||||
|  char *preferred_realm = NULL; | ||||
|  char *ccachedir = NULL; | ||||
| +/* set $HOME to "/" by default */
 | ||||
| +static bool set_home = true;
 | ||||
|  /* Avoid DNS reverse lookups on server names */ | ||||
|  static bool avoid_dns = true; | ||||
|  static bool use_gssproxy = false; | ||||
| @@ -885,7 +887,7 @@ sig_die(int signal)
 | ||||
|  static void | ||||
|  usage(char *progname) | ||||
|  { | ||||
| -	fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D]\n",
 | ||||
| +	fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D] [-H]\n",
 | ||||
|  		progname); | ||||
|  	exit(1); | ||||
|  } | ||||
| @@ -926,6 +928,7 @@ read_gss_conf(void)
 | ||||
|  		preferred_realm = s; | ||||
|   | ||||
|  	use_gssproxy = conf_get_bool("gssd", "use-gss-proxy", use_gssproxy); | ||||
| +	set_home = conf_get_bool("gssd", "set-home", set_home);
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| @@ -946,7 +949,7 @@ main(int argc, char *argv[])
 | ||||
|  	verbosity = conf_get_num("gssd", "verbosity", verbosity); | ||||
|  	rpc_verbosity = conf_get_num("gssd", "rpc-verbosity", rpc_verbosity); | ||||
|   | ||||
| -	while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:T:R:")) != -1) {
 | ||||
| +	while ((opt = getopt(argc, argv, "HDfvrlmnMp:k:d:t:T:R:")) != -1) {
 | ||||
|  		switch (opt) { | ||||
|  			case 'f': | ||||
|  				fg = 1; | ||||
| @@ -994,6 +997,9 @@ main(int argc, char *argv[])
 | ||||
|  			case 'D': | ||||
|  				avoid_dns = false; | ||||
|  				break; | ||||
| +			case 'H':
 | ||||
| +				set_home = false;
 | ||||
| +				break;
 | ||||
|  			default: | ||||
|  				usage(argv[0]); | ||||
|  				break; | ||||
| @@ -1003,13 +1009,19 @@ main(int argc, char *argv[])
 | ||||
|  	/* | ||||
|  	 * Some krb5 routines try to scrape info out of files in the user's | ||||
|  	 * home directory. This can easily deadlock when that homedir is on a | ||||
| -	 * kerberized NFS mount. By setting $HOME unconditionally to "/", we
 | ||||
| -	 * prevent this behavior in routines that use $HOME in preference to
 | ||||
| -	 * the results of getpw*.
 | ||||
| +	 * kerberized NFS mount. By setting $HOME to "/" by default, we prevent
 | ||||
| +	 * this behavior in routines that use $HOME in preference to the results
 | ||||
| +	 * of getpw*.
 | ||||
| +	 *
 | ||||
| +	 * Some users do not use Kerberized home dirs and need $HOME to remain
 | ||||
| +	 * unchanged. Those users can leave $HOME unchanged by setting set_home
 | ||||
| +	 * to false.
 | ||||
|  	 */ | ||||
| -	if (setenv("HOME", "/", 1)) {
 | ||||
| -		printerr(0, "gssd: Unable to set $HOME: %s\n", strerror(errno));
 | ||||
| -		exit(1);
 | ||||
| +	if (set_home) {
 | ||||
| +		if (setenv("HOME", "/", 1)) {
 | ||||
| +			printerr(0, "gssd: Unable to set $HOME: %s\n", strerror(errno));
 | ||||
| +			exit(1);
 | ||||
| +		}
 | ||||
|  	} | ||||
|   | ||||
|  	if (use_gssproxy) { | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.man.orig nfs-utils-2.3.3/utils/gssd/gssd.man
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.man.orig	2021-04-17 10:49:23.650184264 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.man	2021-04-17 11:14:41.484108615 -0400
 | ||||
| @@ -8,7 +8,7 @@
 | ||||
|  rpc.gssd \- RPCSEC_GSS daemon | ||||
|  .SH SYNOPSIS | ||||
|  .B rpc.gssd | ||||
| -.RB [ \-DfMnlvr ]
 | ||||
| +.RB [ \-DfMnlvrH ]
 | ||||
|  .RB [ \-k | ||||
|  .IR keytab ] | ||||
|  .RB [ \-p | ||||
| @@ -297,6 +297,16 @@ The default timeout is set to 5 seconds.
 | ||||
|  If you get messages like "WARNING: can't create tcp rpc_clnt to server | ||||
|  %servername% for user with uid %uid%: RPC: Remote system error - | ||||
|  Connection timed out", you should consider an increase of this timeout. | ||||
| +.TP
 | ||||
| +.B -H
 | ||||
| +Avoids setting $HOME to "/". This allows rpc.gssd to read per user k5identity
 | ||||
| +files versus trying to read /.k5identity for each user.
 | ||||
| +
 | ||||
| +If
 | ||||
| +.B \-H
 | ||||
| +is not set, rpc.gssd will use the first match found in
 | ||||
| +/var/kerberos/krb5/user/$EUID/client.keytab and will not use a principal based on
 | ||||
| +host and/or service parameters listed in $HOME/.k5identity.
 | ||||
|  .SH CONFIGURATION FILE | ||||
|  Many of the options that can be set on the command line can also be | ||||
|  controlled through values set in the | ||||
| @@ -354,6 +364,13 @@ Equivalent to
 | ||||
|  .B preferred-realm | ||||
|  Equivalent to | ||||
|  .BR -R . | ||||
| +.TP
 | ||||
| +.B set-home
 | ||||
| +Setting to
 | ||||
| +.B false
 | ||||
| +is equivalent to providing the
 | ||||
| +.B -H
 | ||||
| +flag.
 | ||||
|  .P | ||||
|  In addtion, the following value is recognized from the | ||||
|  .B [general] | ||||
							
								
								
									
										17
									
								
								SOURCES/nfs-utils-2.3.3-gssd-man-tflag.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								SOURCES/nfs-utils-2.3.3-gssd-man-tflag.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.man.orig nfs-utils-2.3.3/utils/gssd/gssd.man
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.man.orig	2021-04-17 11:21:18.326543446 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.man	2021-04-17 12:35:59.867574517 -0400
 | ||||
| @@ -347,11 +347,11 @@ Equivalent to
 | ||||
|  .TP | ||||
|  .B context-timeout | ||||
|  Equivalent to | ||||
| -.BR -T .
 | ||||
| +.BR -t .
 | ||||
|  .TP | ||||
|  .B rpc-timeout | ||||
|  Equivalent to | ||||
| -.BR -t .
 | ||||
| +.BR -T .
 | ||||
|  .TP | ||||
|  .B keytab-file | ||||
|  Equivalent to | ||||
							
								
								
									
										43
									
								
								SOURCES/nfs-utils-2.3.3-gssd-mutex-refcnt.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								SOURCES/nfs-utils-2.3.3-gssd-mutex-refcnt.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/krb5_util.c.orig nfs-utils-2.3.3/utils/gssd/krb5_util.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/krb5_util.c.orig	2021-07-22 15:27:27.728680553 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/krb5_util.c	2021-07-22 15:30:08.916979585 -0400
 | ||||
| @@ -165,18 +165,28 @@ static int gssd_get_single_krb5_cred(krb
 | ||||
|  static int query_krb5_ccache(const char* cred_cache, char **ret_princname, | ||||
|  		char **ret_realm); | ||||
|   | ||||
| -static void release_ple(krb5_context context, struct gssd_k5_kt_princ *ple)
 | ||||
| +static void release_ple_locked(krb5_context context,
 | ||||
| +			       struct gssd_k5_kt_princ *ple)
 | ||||
|  { | ||||
|  	if (--ple->refcount) | ||||
|  		return; | ||||
|   | ||||
| -	printerr(3, "freeing cached principal (ccname=%s, realm=%s)\n", ple->ccname, ple->realm);
 | ||||
| +	printerr(3, "freeing cached principal (ccname=%s, realm=%s)\n",
 | ||||
| +		 ple->ccname, ple->realm);
 | ||||
|  	krb5_free_principal(context, ple->princ); | ||||
|  	free(ple->ccname); | ||||
|  	free(ple->realm); | ||||
|  	free(ple); | ||||
|  } | ||||
|   | ||||
| +static void release_ple(krb5_context context, struct gssd_k5_kt_princ *ple)
 | ||||
| +{
 | ||||
| +	pthread_mutex_lock(&ple_lock);
 | ||||
| +	release_ple_locked(context, ple);
 | ||||
| +	pthread_mutex_unlock(&ple_lock);
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
|  /* | ||||
|   * Called from the scandir function to weed out potential krb5 | ||||
|   * credentials cache files | ||||
| @@ -1396,7 +1406,7 @@ gssd_destroy_krb5_principals(int destroy
 | ||||
|  			} | ||||
|  		} | ||||
|   | ||||
| -		release_ple(context, ple);
 | ||||
| +		release_ple_locked(context, ple);
 | ||||
|  	} | ||||
|  	pthread_mutex_unlock(&ple_lock); | ||||
|  	krb5_free_context(context); | ||||
							
								
								
									
										625
									
								
								SOURCES/nfs-utils-2.3.3-gssd-timeout-thread.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										625
									
								
								SOURCES/nfs-utils-2.3.3-gssd-timeout-thread.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,625 @@ | ||||
| diff -up nfs-utils-2.3.3/nfs.conf.orig nfs-utils-2.3.3/nfs.conf
 | ||||
| --- nfs-utils-2.3.3/nfs.conf.orig	2021-07-19 09:45:40.441448059 -0400
 | ||||
| +++ nfs-utils-2.3.3/nfs.conf	2021-07-19 12:08:55.314182838 -0400
 | ||||
| @@ -22,6 +22,8 @@ use-gss-proxy=1
 | ||||
|  # cred-cache-directory= | ||||
|  # preferred-realm= | ||||
|  # set-home=1 | ||||
| +# upcall-timeout=30
 | ||||
| +# cancel-timed-out-upcalls=0
 | ||||
|  # | ||||
|  [lockd] | ||||
|  # port=0 | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.c.orig nfs-utils-2.3.3/utils/gssd/gssd.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.c.orig	2021-07-19 09:45:40.448448246 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.c	2021-07-19 12:08:55.315182865 -0400
 | ||||
| @@ -96,8 +96,29 @@ pthread_mutex_t clp_lock = PTHREAD_MUTEX
 | ||||
|  static bool signal_received = false; | ||||
|  static struct event_base *evbase = NULL; | ||||
|   | ||||
| +int upcall_timeout = DEF_UPCALL_TIMEOUT;
 | ||||
| +static bool cancel_timed_out_upcalls = false;
 | ||||
| +
 | ||||
|  TAILQ_HEAD(topdir_list_head, topdir) topdir_list; | ||||
|   | ||||
| +/*
 | ||||
| + * active_thread_list:
 | ||||
| + *
 | ||||
| + * 	used to track upcalls for timeout purposes.
 | ||||
| + *
 | ||||
| + * 	protected by the active_thread_list_lock mutex.
 | ||||
| + *
 | ||||
| + * 	upcall_thread_info structures are added to the tail of the list
 | ||||
| + * 	by start_upcall_thread(), so entries closer to the head of the list
 | ||||
| + * 	will be closer to hitting the upcall timeout.
 | ||||
| + *
 | ||||
| + * 	upcall_thread_info structures are removed from the list upon a
 | ||||
| + * 	sucessful join of the upcall thread by the watchdog thread (via
 | ||||
| + * 	scan_active_thread_list().
 | ||||
| + */
 | ||||
| +TAILQ_HEAD(active_thread_list_head, upcall_thread_info) active_thread_list;
 | ||||
| +pthread_mutex_t active_thread_list_lock = PTHREAD_MUTEX_INITIALIZER;
 | ||||
| +
 | ||||
|  struct topdir { | ||||
|  	TAILQ_ENTRY(topdir) list; | ||||
|  	TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list; | ||||
| @@ -436,6 +457,138 @@ gssd_clnt_krb5_cb(int UNUSED(fd), short
 | ||||
|  	handle_krb5_upcall(clp); | ||||
|  } | ||||
|   | ||||
| +/*
 | ||||
| + * scan_active_thread_list:
 | ||||
| + *
 | ||||
| + * Walks the active_thread_list, trying to join as many upcall threads as
 | ||||
| + * possible.  For threads that have terminated, the corresponding
 | ||||
| + * upcall_thread_info will be removed from the list and freed.  Threads that
 | ||||
| + * are still busy and have exceeded the upcall_timeout will cause an error to
 | ||||
| + * be logged and may be canceled (depending on the value of
 | ||||
| + * cancel_timed_out_upcalls).
 | ||||
| + *
 | ||||
| + * Returns the number of seconds that the watchdog thread should wait before
 | ||||
| + * calling scan_active_thread_list() again.
 | ||||
| + */
 | ||||
| +static int
 | ||||
| +scan_active_thread_list(void)
 | ||||
| +{
 | ||||
| +	struct upcall_thread_info *info;
 | ||||
| +	struct timespec now;
 | ||||
| +	unsigned int sleeptime;
 | ||||
| +	bool sleeptime_set = false;
 | ||||
| +	int err;
 | ||||
| +	void *tret, *saveprev;
 | ||||
| +
 | ||||
| +	sleeptime = upcall_timeout;
 | ||||
| +	pthread_mutex_lock(&active_thread_list_lock);
 | ||||
| +	clock_gettime(CLOCK_MONOTONIC, &now);
 | ||||
| +	TAILQ_FOREACH(info, &active_thread_list, list) {
 | ||||
| +		err = pthread_tryjoin_np(info->tid, &tret);
 | ||||
| +		switch (err) {
 | ||||
| +		case 0:
 | ||||
| +			/*
 | ||||
| +			 * The upcall thread has either completed successfully, or
 | ||||
| +			 * has been canceled _and_ has acted on the cancellation request
 | ||||
| +			 * (i.e. has hit a cancellation point).  We can now remove the
 | ||||
| +			 * upcall_thread_info from the list and free it.
 | ||||
| +			 */
 | ||||
| +			if (tret == PTHREAD_CANCELED)
 | ||||
| +				printerr(3, "watchdog: thread id 0x%lx cancelled successfully\n",
 | ||||
| +						info->tid);
 | ||||
| +			saveprev = info->list.tqe_prev;
 | ||||
| +			TAILQ_REMOVE(&active_thread_list, info, list);
 | ||||
| +			free(info);
 | ||||
| +			info = saveprev;
 | ||||
| +			break;
 | ||||
| +		case EBUSY:
 | ||||
| +			/*
 | ||||
| +			 * The upcall thread is still running.  If the timeout has expired
 | ||||
| +			 * then we either cancel the thread, log an error, and do an error
 | ||||
| +			 * downcall to the kernel (cancel_timed_out_upcalls=true) or simply
 | ||||
| +			 * log an error (cancel_timed_out_upcalls=false).  In either case,
 | ||||
| +			 * the error is logged only once.
 | ||||
| +			 */
 | ||||
| +			if (now.tv_sec >= info->timeout.tv_sec) {
 | ||||
| +				if (cancel_timed_out_upcalls && !(info->flags & UPCALL_THREAD_CANCELED)) {
 | ||||
| +					printerr(0, "watchdog: thread id 0x%lx timed out\n",
 | ||||
| +							info->tid);
 | ||||
| +					pthread_cancel(info->tid);
 | ||||
| +					info->flags |= (UPCALL_THREAD_CANCELED|UPCALL_THREAD_WARNED);
 | ||||
| +					do_error_downcall(info->fd, info->uid, -ETIMEDOUT);
 | ||||
| +				} else {
 | ||||
| +					if (!(info->flags & UPCALL_THREAD_WARNED)) {
 | ||||
| +						printerr(0, "watchdog: thread id 0x%lx running for %ld seconds\n",
 | ||||
| +								info->tid,
 | ||||
| +								now.tv_sec - info->timeout.tv_sec + upcall_timeout);
 | ||||
| +						info->flags |= UPCALL_THREAD_WARNED;
 | ||||
| +					}
 | ||||
| +				}
 | ||||
| +			} else if (!sleeptime_set) {
 | ||||
| +			/*
 | ||||
| +			 * The upcall thread is still running, but the timeout has not yet
 | ||||
| +			 * expired.  Calculate the time remaining until the timeout will
 | ||||
| +			 * expire.  This is the amount of time the watchdog thread will
 | ||||
| +			 * wait before running again.  We only need to do this for the busy
 | ||||
| +			 * thread closest to the head of the list - entries appearing later
 | ||||
| +			 * in the list will time out later.
 | ||||
| +			 */
 | ||||
| +				sleeptime = info->timeout.tv_sec - now.tv_sec;
 | ||||
| +				sleeptime_set = true;
 | ||||
| +			}
 | ||||
| +			break;
 | ||||
| +		default:
 | ||||
| +			/* EDEADLK, EINVAL, and ESRCH... none of which should happen! */
 | ||||
| +			printerr(0, "watchdog: attempt to join thread id 0x%lx returned %d (%s)!\n",
 | ||||
| +					info->tid, err, strerror(err));
 | ||||
| +			break;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	pthread_mutex_unlock(&active_thread_list_lock);
 | ||||
| +
 | ||||
| +	return sleeptime;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void *
 | ||||
| +watchdog_thread_fn(void *UNUSED(arg))
 | ||||
| +{
 | ||||
| +	unsigned int sleeptime;
 | ||||
| +
 | ||||
| +	for (;;) {
 | ||||
| +		sleeptime = scan_active_thread_list();
 | ||||
| +		printerr(4, "watchdog: sleeping %u secs\n", sleeptime);
 | ||||
| +		sleep(sleeptime);
 | ||||
| +	}
 | ||||
| +	return (void *)0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +start_watchdog_thread(void)
 | ||||
| +{
 | ||||
| +	pthread_attr_t attr;
 | ||||
| +	pthread_t th;
 | ||||
| +	int ret;
 | ||||
| +
 | ||||
| +	ret = pthread_attr_init(&attr);
 | ||||
| +	if (ret != 0) {
 | ||||
| +		printerr(0, "ERROR: failed to init pthread attr: ret %d: %s\n",
 | ||||
| +			 ret, strerror(errno));
 | ||||
| +		return ret;
 | ||||
| +	}
 | ||||
| +	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | ||||
| +	if (ret != 0) {
 | ||||
| +		printerr(0, "ERROR: failed to create pthread attr: ret %d: %s\n",
 | ||||
| +			 ret, strerror(errno));
 | ||||
| +		return ret;
 | ||||
| +	}
 | ||||
| +	ret = pthread_create(&th, &attr, watchdog_thread_fn, NULL);
 | ||||
| +	if (ret != 0) {
 | ||||
| +		printerr(0, "ERROR: pthread_create failed: ret %d: %s\n",
 | ||||
| +			 ret, strerror(errno));
 | ||||
| +	}
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
|  static struct clnt_info * | ||||
|  gssd_get_clnt(struct topdir *tdi, const char *name) | ||||
|  { | ||||
| @@ -810,7 +963,7 @@ sig_die(int signal)
 | ||||
|  static void | ||||
|  usage(char *progname) | ||||
|  { | ||||
| -	fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D] [-H]\n",
 | ||||
| +	fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D] [-H] [-U upcall timeout] [-C]\n",
 | ||||
|  		progname); | ||||
|  	exit(1); | ||||
|  } | ||||
| @@ -831,6 +984,9 @@ read_gss_conf(void)
 | ||||
|  #endif | ||||
|  	context_timeout = conf_get_num("gssd", "context-timeout", context_timeout); | ||||
|  	rpc_timeout = conf_get_num("gssd", "rpc-timeout", rpc_timeout); | ||||
| +	upcall_timeout = conf_get_num("gssd", "upcall-timeout", upcall_timeout);
 | ||||
| +	cancel_timed_out_upcalls = conf_get_bool("gssd", "cancel-timed-out-upcalls",
 | ||||
| +						cancel_timed_out_upcalls);
 | ||||
|  	s = conf_get_str("gssd", "pipefs-directory"); | ||||
|  	if (!s) | ||||
|  		s = conf_get_str("general", "pipefs-directory"); | ||||
| @@ -872,7 +1028,7 @@ main(int argc, char *argv[])
 | ||||
|  	verbosity = conf_get_num("gssd", "verbosity", verbosity); | ||||
|  	rpc_verbosity = conf_get_num("gssd", "rpc-verbosity", rpc_verbosity); | ||||
|   | ||||
| -	while ((opt = getopt(argc, argv, "HDfvrlmnMp:k:d:t:T:R:")) != -1) {
 | ||||
| +	while ((opt = getopt(argc, argv, "HDfvrlmnMp:k:d:t:T:R:U:C")) != -1) {
 | ||||
|  		switch (opt) { | ||||
|  			case 'f': | ||||
|  				fg = 1; | ||||
| @@ -923,6 +1079,12 @@ main(int argc, char *argv[])
 | ||||
|  			case 'H': | ||||
|  				set_home = false; | ||||
|  				break; | ||||
| +			case 'U':
 | ||||
| +				upcall_timeout = atoi(optarg);
 | ||||
| +				break;
 | ||||
| +			case 'C':
 | ||||
| +				cancel_timed_out_upcalls = true;
 | ||||
| +				break;
 | ||||
|  			default: | ||||
|  				usage(argv[0]); | ||||
|  				break; | ||||
| @@ -995,6 +1157,11 @@ main(int argc, char *argv[])
 | ||||
|  	else | ||||
|  		progname = argv[0]; | ||||
|   | ||||
| +	if (upcall_timeout > MAX_UPCALL_TIMEOUT)
 | ||||
| +		upcall_timeout = MAX_UPCALL_TIMEOUT;
 | ||||
| +	else if (upcall_timeout < MIN_UPCALL_TIMEOUT)
 | ||||
| +		upcall_timeout = MIN_UPCALL_TIMEOUT;
 | ||||
| +
 | ||||
|  	initerr(progname, verbosity, fg); | ||||
|  #ifdef HAVE_LIBTIRPC_SET_DEBUG | ||||
|  	/* | ||||
| @@ -1045,6 +1212,14 @@ main(int argc, char *argv[])
 | ||||
|  			       gssd_inotify_cb, NULL); | ||||
|  	event_add(inotify_ev, NULL); | ||||
|   | ||||
| +	TAILQ_INIT(&active_thread_list);
 | ||||
| +
 | ||||
| +	rc = start_watchdog_thread();
 | ||||
| +	if (rc != 0) {
 | ||||
| +		printerr(0, "ERROR: failed to start watchdog thread: %d\n", rc);
 | ||||
| +		exit(EXIT_FAILURE);
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	TAILQ_INIT(&topdir_list); | ||||
|  	gssd_scan(); | ||||
|  	daemon_ready(); | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.h.orig nfs-utils-2.3.3/utils/gssd/gssd.h
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.h.orig	2021-07-19 09:45:40.449448272 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.h	2021-07-19 12:08:55.315182865 -0400
 | ||||
| @@ -50,6 +50,12 @@
 | ||||
|  #define GSSD_DEFAULT_KEYTAB_FILE		"/etc/krb5.keytab" | ||||
|  #define GSSD_SERVICE_NAME			"nfs" | ||||
|  #define RPC_CHAN_BUF_SIZE			32768 | ||||
| +
 | ||||
| +/* timeouts are in seconds */
 | ||||
| +#define MIN_UPCALL_TIMEOUT			5
 | ||||
| +#define DEF_UPCALL_TIMEOUT			30
 | ||||
| +#define MAX_UPCALL_TIMEOUT			600
 | ||||
| +
 | ||||
|  /* | ||||
|   * The gss mechanisms that we can handle | ||||
|   */ | ||||
| @@ -91,10 +97,22 @@ struct clnt_upcall_info {
 | ||||
|  	char			*service; | ||||
|  }; | ||||
|   | ||||
| +struct upcall_thread_info {
 | ||||
| +	TAILQ_ENTRY(upcall_thread_info) list;
 | ||||
| +	pthread_t		tid;
 | ||||
| +	struct timespec		timeout;
 | ||||
| +	uid_t			uid;
 | ||||
| +	int			fd;
 | ||||
| +	unsigned short		flags;
 | ||||
| +#define UPCALL_THREAD_CANCELED	0x0001
 | ||||
| +#define UPCALL_THREAD_WARNED	0x0002
 | ||||
| +};
 | ||||
| +
 | ||||
|  void handle_krb5_upcall(struct clnt_info *clp); | ||||
|  void handle_gssd_upcall(struct clnt_info *clp); | ||||
|  void free_upcall_info(struct clnt_upcall_info *info); | ||||
|  void gssd_free_client(struct clnt_info *clp); | ||||
| +int do_error_downcall(int k5_fd, uid_t uid, int err);
 | ||||
|   | ||||
|   | ||||
|  #endif /* _RPC_GSSD_H_ */ | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd.man.orig nfs-utils-2.3.3/utils/gssd/gssd.man
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd.man.orig	2021-07-19 09:45:40.443448112 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd.man	2021-07-19 12:08:55.315182865 -0400
 | ||||
| @@ -8,7 +8,7 @@
 | ||||
|  rpc.gssd \- RPCSEC_GSS daemon | ||||
|  .SH SYNOPSIS | ||||
|  .B rpc.gssd | ||||
| -.RB [ \-DfMnlvrH ]
 | ||||
| +.RB [ \-DfMnlvrHC ]
 | ||||
|  .RB [ \-k | ||||
|  .IR keytab ] | ||||
|  .RB [ \-p | ||||
| @@ -17,6 +17,10 @@ rpc.gssd \- RPCSEC_GSS daemon
 | ||||
|  .IR ccachedir ] | ||||
|  .RB [ \-t | ||||
|  .IR timeout ] | ||||
| +.RB [ \-T
 | ||||
| +.IR timeout ]
 | ||||
| +.RB [ \-U
 | ||||
| +.IR timeout ]
 | ||||
|  .RB [ \-R | ||||
|  .IR realm ] | ||||
|  .SH INTRODUCTION | ||||
| @@ -290,7 +294,7 @@ seconds, which allows changing Kerberos
 | ||||
|  The default is no explicit timeout, which means the kernel context will live | ||||
|  the lifetime of the Kerberos service ticket used in its creation. | ||||
|  .TP | ||||
| -.B -T timeout
 | ||||
| +.BI "-T " timeout
 | ||||
|  Timeout, in seconds, to create an RPC connection with a server while | ||||
|  establishing an authenticated gss context for a user. | ||||
|  The default timeout is set to 5 seconds. | ||||
| @@ -298,6 +302,18 @@ If you get messages like "WARNING: can't
 | ||||
|  %servername% for user with uid %uid%: RPC: Remote system error - | ||||
|  Connection timed out", you should consider an increase of this timeout. | ||||
|  .TP | ||||
| +.BI "-U " timeout
 | ||||
| +Timeout, in seconds, for upcall threads.  Threads executing longer than
 | ||||
| +.I timeout
 | ||||
| +seconds will cause an error message to be logged.  The default
 | ||||
| +.I timeout
 | ||||
| +is 30 seconds.  The minimum is 5 seconds.  The maximum is 600 seconds.
 | ||||
| +.TP
 | ||||
| +.B -C
 | ||||
| +In addition to logging an error message for threads that have timed out,
 | ||||
| +the thread will be canceled and an error of -ETIMEDOUT will be reported
 | ||||
| +to the kernel.
 | ||||
| +.TP
 | ||||
|  .B -H | ||||
|  Avoids setting $HOME to "/". This allows rpc.gssd to read per user k5identity | ||||
|  files versus trying to read /.k5identity for each user. | ||||
| @@ -365,6 +381,17 @@ Equivalent to
 | ||||
|  Equivalent to | ||||
|  .BR -R . | ||||
|  .TP | ||||
| +.B upcall-timeout
 | ||||
| +Equivalent to
 | ||||
| +.BR -U .
 | ||||
| +.TP
 | ||||
| +.B cancel-timed-out-upcalls
 | ||||
| +Setting to
 | ||||
| +.B true
 | ||||
| +is equivalent to providing the
 | ||||
| +.B -C
 | ||||
| +flag.
 | ||||
| +.TP
 | ||||
|  .B set-home | ||||
|  Setting to | ||||
|  .B false | ||||
| diff -up nfs-utils-2.3.3/utils/gssd/gssd_proc.c.orig nfs-utils-2.3.3/utils/gssd/gssd_proc.c
 | ||||
| --- nfs-utils-2.3.3/utils/gssd/gssd_proc.c.orig	2021-07-19 09:45:40.449448272 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/gssd/gssd_proc.c	2021-07-19 12:08:55.316182891 -0400
 | ||||
| @@ -81,11 +81,24 @@
 | ||||
|  #include "gss_names.h" | ||||
|   | ||||
|  extern pthread_mutex_t clp_lock; | ||||
| +extern pthread_mutex_t active_thread_list_lock;
 | ||||
| +extern int upcall_timeout;
 | ||||
| +extern TAILQ_HEAD(active_thread_list_head, upcall_thread_info) active_thread_list;
 | ||||
|   | ||||
|  /* Encryption types supported by the kernel rpcsec_gss code */ | ||||
|  int num_krb5_enctypes = 0; | ||||
|  krb5_enctype *krb5_enctypes = NULL; | ||||
|   | ||||
| +/* Args for the cleanup_handler() */
 | ||||
| +struct cleanup_args  {
 | ||||
| +	OM_uint32 	*min_stat;
 | ||||
| +	gss_buffer_t	acceptor;
 | ||||
| +	gss_buffer_t	token;
 | ||||
| +	struct authgss_private_data *pd;
 | ||||
| +	AUTH		**auth;
 | ||||
| +	CLIENT		**rpc_clnt;
 | ||||
| +};
 | ||||
| +
 | ||||
|  /* | ||||
|   * Parse the supported encryption type information | ||||
|   */ | ||||
| @@ -184,7 +197,7 @@ out_err:
 | ||||
|  	return; | ||||
|  } | ||||
|   | ||||
| -static int
 | ||||
| +int
 | ||||
|  do_error_downcall(int k5_fd, uid_t uid, int err) | ||||
|  { | ||||
|  	char	buf[1024]; | ||||
| @@ -604,27 +617,66 @@ out:
 | ||||
|  } | ||||
|   | ||||
|  /* | ||||
| + * cleanup_handler:
 | ||||
| + *
 | ||||
| + * Free any resources allocated by process_krb5_upcall().
 | ||||
| + *
 | ||||
| + * Runs upon normal termination of process_krb5_upcall as well as if the
 | ||||
| + * thread is canceled.
 | ||||
| + */
 | ||||
| +static void
 | ||||
| +cleanup_handler(void *arg)
 | ||||
| +{
 | ||||
| +	struct cleanup_args *args = (struct cleanup_args *)arg;
 | ||||
| +
 | ||||
| +	gss_release_buffer(args->min_stat, args->acceptor);
 | ||||
| +	if (args->token->value)
 | ||||
| +		free(args->token->value);
 | ||||
| +#ifdef HAVE_AUTHGSS_FREE_PRIVATE_DATA
 | ||||
| +	if (args->pd->pd_ctx_hndl.length != 0 || args->pd->pd_ctx != 0)
 | ||||
| +		authgss_free_private_data(args->pd);
 | ||||
| +#endif
 | ||||
| +	if (*args->auth)
 | ||||
| +		AUTH_DESTROY(*args->auth);
 | ||||
| +	if (*args->rpc_clnt)
 | ||||
| +		clnt_destroy(*args->rpc_clnt);
 | ||||
| +}
 | ||||
| +
 | ||||
| +/*
 | ||||
| + * process_krb5_upcall:
 | ||||
| + *
 | ||||
|   * this code uses the userland rpcsec gss library to create a krb5 | ||||
|   * context on behalf of the kernel | ||||
| + *
 | ||||
| + * This is the meat of the upcall thread.  Note that cancelability is disabled
 | ||||
| + * and enabled at various points to ensure that any resources reserved by the
 | ||||
| + * lower level libraries are released safely.
 | ||||
|   */ | ||||
|  static void | ||||
| -process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *srchost,
 | ||||
| -		    char *tgtname, char *service)
 | ||||
| +process_krb5_upcall(struct clnt_upcall_info *info)
 | ||||
|  { | ||||
| +	struct clnt_info	*clp = info->clp;
 | ||||
| +	uid_t			uid = info->uid;
 | ||||
| +	int			fd = info->fd;
 | ||||
| +	char			*srchost = info->srchost;
 | ||||
| +	char			*tgtname = info->target;
 | ||||
| +	char			*service = info->service;
 | ||||
|  	CLIENT			*rpc_clnt = NULL; | ||||
|  	AUTH			*auth = NULL; | ||||
|  	struct authgss_private_data pd; | ||||
|  	gss_buffer_desc		token; | ||||
| -	int			err, downcall_err = -EACCES;
 | ||||
| +	int			err, downcall_err;
 | ||||
|  	OM_uint32		maj_stat, min_stat, lifetime_rec; | ||||
|  	gss_name_t		gacceptor = GSS_C_NO_NAME; | ||||
|  	gss_OID			mech; | ||||
|  	gss_buffer_desc		acceptor  = {0}; | ||||
| +	struct cleanup_args cleanup_args = {&min_stat, &acceptor, &token, &pd, &auth, &rpc_clnt};
 | ||||
|   | ||||
|  	token.length = 0; | ||||
|  	token.value = NULL; | ||||
|  	memset(&pd, 0, sizeof(struct authgss_private_data)); | ||||
|   | ||||
| +	pthread_cleanup_push(cleanup_handler, &cleanup_args);
 | ||||
|  	/* | ||||
|  	 * If "service" is specified, then the kernel is indicating that | ||||
|  	 * we must use machine credentials for this request.  (Regardless | ||||
| @@ -646,6 +698,8 @@ process_krb5_upcall(struct clnt_info *cl
 | ||||
|  	 * used for this case is not important. | ||||
|  	 * | ||||
|  	 */ | ||||
| +	downcall_err = -EACCES;
 | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 | ||||
|  	if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0 && | ||||
|  				service == NULL)) { | ||||
|   | ||||
| @@ -666,15 +720,21 @@ process_krb5_upcall(struct clnt_info *cl
 | ||||
|  			goto out_return_error; | ||||
|  		} | ||||
|  	} | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 | ||||
| +	pthread_testcancel();
 | ||||
|   | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 | ||||
|  	if (!authgss_get_private_data(auth, &pd)) { | ||||
|  		printerr(1, "WARNING: Failed to obtain authentication " | ||||
|  			    "data for user with uid %d for server %s\n", | ||||
|  			 uid, clp->servername); | ||||
|  		goto out_return_error; | ||||
|  	} | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 | ||||
| +	pthread_testcancel();
 | ||||
|   | ||||
|  	/* Grab the context lifetime and acceptor name out of the ctx. */ | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 | ||||
|  	maj_stat = gss_inquire_context(&min_stat, pd.pd_ctx, NULL, &gacceptor, | ||||
|  				       &lifetime_rec, &mech, NULL, NULL, NULL); | ||||
|   | ||||
| @@ -686,37 +746,35 @@ process_krb5_upcall(struct clnt_info *cl
 | ||||
|  		get_hostbased_client_buffer(gacceptor, mech, &acceptor); | ||||
|  		gss_release_name(&min_stat, &gacceptor); | ||||
|  	} | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 | ||||
| +	pthread_testcancel();
 | ||||
|   | ||||
|  	/* | ||||
|  	 * The serialization can mean turning pd.pd_ctx into a lucid context. If | ||||
|  	 * that happens then the pd.pd_ctx will be unusable, so we must never | ||||
|  	 * try to use it after this point. | ||||
|  	 */ | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 | ||||
|  	if (serialize_context_for_kernel(&pd.pd_ctx, &token, &krb5oid, NULL)) { | ||||
|  		printerr(1, "WARNING: Failed to serialize krb5 context for " | ||||
|  			    "user with uid %d for server %s\n", | ||||
|  			 uid, clp->servername); | ||||
|  		goto out_return_error; | ||||
|  	} | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 | ||||
| +	pthread_testcancel();
 | ||||
|   | ||||
|  	do_downcall(fd, uid, &pd, &token, lifetime_rec, &acceptor); | ||||
|   | ||||
|  out: | ||||
| -	gss_release_buffer(&min_stat, &acceptor);
 | ||||
| -	if (token.value)
 | ||||
| -		free(token.value);
 | ||||
| -#ifdef HAVE_AUTHGSS_FREE_PRIVATE_DATA
 | ||||
| -	if (pd.pd_ctx_hndl.length != 0 || pd.pd_ctx != 0)
 | ||||
| -		authgss_free_private_data(&pd);
 | ||||
| -#endif
 | ||||
| -	if (auth)
 | ||||
| -		AUTH_DESTROY(auth);
 | ||||
| -	if (rpc_clnt)
 | ||||
| -		clnt_destroy(rpc_clnt);
 | ||||
| +	pthread_cleanup_pop(1);
 | ||||
|   | ||||
|  	return; | ||||
|   | ||||
|  out_return_error: | ||||
| +	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 | ||||
| +	pthread_testcancel();
 | ||||
| +
 | ||||
|  	do_error_downcall(fd, uid, downcall_err); | ||||
|  	goto out; | ||||
|  } | ||||
| @@ -782,36 +840,69 @@ void free_upcall_info(struct clnt_upcall
 | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| -gssd_work_thread_fn(struct clnt_upcall_info *info)
 | ||||
| +cleanup_clnt_upcall_info(void *arg)
 | ||||
|  { | ||||
| -	process_krb5_upcall(info->clp, info->uid, info->fd, info->srchost, info->target, info->service);
 | ||||
| +	struct clnt_upcall_info *info = (struct clnt_upcall_info *)arg;
 | ||||
| +
 | ||||
|  	free_upcall_info(info); | ||||
|  } | ||||
|   | ||||
| +static void
 | ||||
| +gssd_work_thread_fn(struct clnt_upcall_info *info)
 | ||||
| +{
 | ||||
| +	pthread_cleanup_push(cleanup_clnt_upcall_info, info);
 | ||||
| +	process_krb5_upcall(info);
 | ||||
| +	pthread_cleanup_pop(1);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static struct upcall_thread_info *
 | ||||
| +alloc_upcall_thread_info(void)
 | ||||
| +{
 | ||||
| +	struct upcall_thread_info *info;
 | ||||
| +
 | ||||
| +	info = malloc(sizeof(struct upcall_thread_info));
 | ||||
| +	if (info == NULL)
 | ||||
| +		return NULL;
 | ||||
| +	memset(info, 0, sizeof(*info));
 | ||||
| +	return info;
 | ||||
| +}
 | ||||
| +
 | ||||
|  static int | ||||
| -start_upcall_thread(void (*func)(struct clnt_upcall_info *), void *info)
 | ||||
| +start_upcall_thread(void (*func)(struct clnt_upcall_info *), struct clnt_upcall_info *info)
 | ||||
|  { | ||||
|  	pthread_attr_t attr; | ||||
|  	pthread_t th; | ||||
| +	struct upcall_thread_info *tinfo;
 | ||||
|  	int ret; | ||||
|   | ||||
| +	tinfo = alloc_upcall_thread_info();
 | ||||
| +	if (!tinfo)
 | ||||
| +		return -ENOMEM;
 | ||||
| +	tinfo->fd = info->fd;
 | ||||
| +	tinfo->uid = info->uid;
 | ||||
| +
 | ||||
|  	ret = pthread_attr_init(&attr); | ||||
|  	if (ret != 0) { | ||||
|  		printerr(0, "ERROR: failed to init pthread attr: ret %d: %s\n", | ||||
|  			 ret, strerror(errno)); | ||||
| -		return ret;
 | ||||
| -	}
 | ||||
| -	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | ||||
| -	if (ret != 0) {
 | ||||
| -		printerr(0, "ERROR: failed to create pthread attr: ret %d: "
 | ||||
| -			 "%s\n", ret, strerror(errno));
 | ||||
| +		free(tinfo);
 | ||||
|  		return ret; | ||||
|  	} | ||||
|   | ||||
|  	ret = pthread_create(&th, &attr, (void *)func, (void *)info); | ||||
| -	if (ret != 0)
 | ||||
| +	if (ret != 0) {
 | ||||
|  		printerr(0, "ERROR: pthread_create failed: ret %d: %s\n", | ||||
|  			 ret, strerror(errno)); | ||||
| +		free(tinfo);
 | ||||
| +		return ret;
 | ||||
| +	}
 | ||||
| +	tinfo->tid = th;
 | ||||
| +	pthread_mutex_lock(&active_thread_list_lock);
 | ||||
| +	clock_gettime(CLOCK_MONOTONIC, &tinfo->timeout);
 | ||||
| +	tinfo->timeout.tv_sec += upcall_timeout;
 | ||||
| +	TAILQ_INSERT_TAIL(&active_thread_list, tinfo, list);
 | ||||
| +	pthread_mutex_unlock(&active_thread_list_lock);
 | ||||
| +
 | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
							
								
								
									
										116
									
								
								SOURCES/nfs-utils-2.3.3-mount-sloppy.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								SOURCES/nfs-utils-2.3.3-mount-sloppy.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| diff -up nfs-utils-2.3.3/utils/mount/nfs.man.save nfs-utils-2.3.3/utils/mount/nfs.man
 | ||||
| --- nfs-utils-2.3.3/utils/mount/nfs.man.save	2021-07-28 14:42:20.977740892 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/mount/nfs.man	2021-07-28 14:42:01.133212815 -0400
 | ||||
| @@ -525,6 +525,13 @@ using the FS-Cache facility. See cachefi
 | ||||
|  and <kernel_soruce>/Documentation/filesystems/caching | ||||
|  for detail on how to configure the FS-Cache facility. | ||||
|  Default value is nofsc. | ||||
| +.TP 1.5i
 | ||||
| +.B sloppy
 | ||||
| +The
 | ||||
| +.B sloppy
 | ||||
| +option is an alternative to specifying
 | ||||
| +.BR mount.nfs " -s " option.
 | ||||
| +
 | ||||
|  .SS "Options for NFS versions 2 and 3 only" | ||||
|  Use these options, along with the options in the above subsection, | ||||
|  for NFS versions 2 and 3 only. | ||||
| diff -up nfs-utils-2.3.3/utils/mount/parse_opt.c.save nfs-utils-2.3.3/utils/mount/parse_opt.c
 | ||||
| --- nfs-utils-2.3.3/utils/mount/parse_opt.c.save	2021-07-28 14:40:15.467400995 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/mount/parse_opt.c	2021-07-28 14:39:57.666927309 -0400
 | ||||
| @@ -178,6 +178,22 @@ static void options_tail_insert(struct m
 | ||||
|  	options->count++; | ||||
|  } | ||||
|   | ||||
| +static void options_head_insert(struct mount_options *options,
 | ||||
| +				struct mount_option *option)
 | ||||
| +{
 | ||||
| +	struct mount_option *ohead = options->head;
 | ||||
| +
 | ||||
| +	option->prev = NULL;
 | ||||
| +	option->next = ohead;
 | ||||
| +	if (ohead)
 | ||||
| +		ohead->prev = option;
 | ||||
| +	else
 | ||||
| +		options->tail = option;
 | ||||
| +	options->head = option;
 | ||||
| +
 | ||||
| +	options->count++;
 | ||||
| +}
 | ||||
| +
 | ||||
|  static void options_delete(struct mount_options *options, | ||||
|  			   struct mount_option *option) | ||||
|  { | ||||
| @@ -374,6 +390,23 @@ po_return_t po_join(struct mount_options
 | ||||
|  } | ||||
|   | ||||
|  /** | ||||
| + * po_insert - insert an option into a group of options
 | ||||
| + * @options: pointer to mount options
 | ||||
| + * @option: pointer to a C string containing the option to add
 | ||||
| + *
 | ||||
| + */
 | ||||
| +po_return_t po_insert(struct mount_options *options, char *str)
 | ||||
| +{
 | ||||
| +	struct mount_option *option = option_create(str);
 | ||||
| +
 | ||||
| +	if (option) {
 | ||||
| +		options_head_insert(options, option);
 | ||||
| +		return PO_SUCCEEDED;
 | ||||
| +	}
 | ||||
| +	return PO_FAILED;
 | ||||
| +}
 | ||||
| +
 | ||||
| +/**
 | ||||
|   * po_append - concatenate an option onto a group of options | ||||
|   * @options: pointer to mount options | ||||
|   * @option: pointer to a C string containing the option to add | ||||
| diff -up nfs-utils-2.3.3/utils/mount/parse_opt.h.save nfs-utils-2.3.3/utils/mount/parse_opt.h
 | ||||
| --- nfs-utils-2.3.3/utils/mount/parse_opt.h.save	2021-07-28 14:40:54.292434148 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/mount/parse_opt.h	2021-07-28 14:39:57.666927309 -0400
 | ||||
| @@ -43,6 +43,7 @@ void			po_replace(struct mount_options *
 | ||||
|  				   struct mount_options *); | ||||
|  po_return_t		po_join(struct mount_options *, char **); | ||||
|   | ||||
| +po_return_t		po_insert(struct mount_options *, char *);
 | ||||
|  po_return_t		po_append(struct mount_options *, char *); | ||||
|  po_found_t		po_contains(struct mount_options *, char *); | ||||
|  po_found_t		po_contains_prefix(struct mount_options *options, | ||||
| diff -up nfs-utils-2.3.3/utils/mount/stropts.c.save nfs-utils-2.3.3/utils/mount/stropts.c
 | ||||
| --- nfs-utils-2.3.3/utils/mount/stropts.c.save	2021-07-28 14:41:14.842981010 -0400
 | ||||
| +++ nfs-utils-2.3.3/utils/mount/stropts.c	2021-07-28 14:42:01.134212842 -0400
 | ||||
| @@ -336,13 +336,21 @@ static int nfs_verify_lock_option(struct
 | ||||
|  	return 1; | ||||
|  } | ||||
|   | ||||
| -static int nfs_append_sloppy_option(struct mount_options *options)
 | ||||
| +static int nfs_insert_sloppy_option(struct mount_options *options)
 | ||||
|  { | ||||
| -	if (!sloppy || linux_version_code() < MAKE_VERSION(2, 6, 27))
 | ||||
| +	if (linux_version_code() < MAKE_VERSION(2, 6, 27))
 | ||||
|  		return 1; | ||||
|   | ||||
| -	if (po_append(options, "sloppy") == PO_FAILED)
 | ||||
| -		return 0;
 | ||||
| +	if (po_contains(options, "sloppy")) {
 | ||||
| +		po_remove_all(options, "sloppy");
 | ||||
| +		sloppy++;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (sloppy) {
 | ||||
| +		if (po_insert(options, "sloppy") == PO_FAILED)
 | ||||
| +			return 0;
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	return 1; | ||||
|  } | ||||
|   | ||||
| @@ -424,7 +432,7 @@ static int nfs_validate_options(struct n
 | ||||
|  	if (!nfs_set_version(mi)) | ||||
|  		return 0; | ||||
|   | ||||
| -	if (!nfs_append_sloppy_option(mi->options))
 | ||||
| +	if (!nfs_insert_sloppy_option(mi->options))
 | ||||
|  		return 0; | ||||
|   | ||||
|  	return 1; | ||||
| @ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser | ||||
| Name: nfs-utils | ||||
| URL: http://linux-nfs.org/ | ||||
| Version: 2.3.3 | ||||
| Release: 41%{?dist} | ||||
| Release: 46%{?dist} | ||||
| Epoch: 1 | ||||
| 
 | ||||
| # group all 32bit related archs | ||||
| @ -73,6 +73,19 @@ Patch035: nfs-utils-2.3.3-exports-manpage-outdated.patch | ||||
| Patch036: nfs-utils-2.3.3-gssd-multithread-updates.patch | ||||
| Patch037: nfs-utils-2.3.3-mountd-pseudofs.patch | ||||
| 
 | ||||
| # | ||||
| # RHEL 8.5 | ||||
| # | ||||
| Patch038: nfs-utils-2.3.3-gssd-k5identity.patch | ||||
| Patch039: nfs-utils-2.3.3-gssd-man-tflag.patch | ||||
| Patch040: nfs-utils-2.3.3-exportfs-root.patch | ||||
| Patch041: nfs-utils-2.3.3-mount-sloppy.patch | ||||
| Patch042: nfs-utils-2.3.3-gssd-failed-thread.patch | ||||
| Patch043: nfs-utils-2.3.3-gssd-timeout-thread.patch | ||||
| Patch044: nfs-utils-2.3.3-gssd-debug-cleanup.patch | ||||
| Patch045: nfs-utils-2.3.3-gssd-mutex-refcnt.patch | ||||
| 
 | ||||
| 
 | ||||
| Patch100: nfs-utils-1.2.1-statdpath-man.patch | ||||
| Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch | ||||
| Patch102: nfs-utils-2.3.3-idmap-errmsg.patch | ||||
| @ -140,16 +153,8 @@ developing programs which use the libnfsidmap library. | ||||
| 
 | ||||
| 
 | ||||
| %description | ||||
| The nfs-utils package provides a daemon for the kernel NFS server and | ||||
| related tools, which provides a much higher level of performance than the | ||||
| traditional Linux NFS server used by most users. | ||||
| 
 | ||||
| This package also contains the showmount program.  Showmount queries the | ||||
| mount daemon on a remote host for information about the NFS (Network File | ||||
| System) server on the remote host.  For example, showmount can display the | ||||
| clients which are mounted on that host. | ||||
| 
 | ||||
| This package also contains the mount.nfs and umount.nfs program. | ||||
| The nfs-utils package provides various utilities for use with NFS | ||||
| clients and servers. | ||||
| 
 | ||||
| %prep | ||||
| %autosetup -p1 | ||||
| @ -355,6 +360,26 @@ fi | ||||
| %{_libdir}/libnfsidmap.so | ||||
| 
 | ||||
| %changelog | ||||
| * Wed Jul 28 2021 Steve Dickson <steved@redhat.com> 2.3.3-46 | ||||
| - mount.nfs: Fix the sloppy option processing (bz 1967883) | ||||
| 
 | ||||
| * Thu Jul 22 2021 Steve Dickson <steved@redhat.com> 2.3.3-45 | ||||
| - gssd: use mutex to protect decrement of refcount (bz 1511706) | ||||
| 
 | ||||
| * Mon Jul 19 2021 Steve Dickson <steved@redhat.com> 2.3.3-44 | ||||
| - gssd: Deal with failed thread creation (bz 1981400) | ||||
| - gssd: Add timeout for upcall threads (bz 1981403) | ||||
| - gssd: Cleaned up debug messages (bz 1961056) | ||||
| - spec: Updated description of the nfs-utils rpm (bz 1981419) | ||||
| 
 | ||||
| * Sat Jul 10 2021 Steve Dickson <steved@redhat.com> 2.3.3-43 | ||||
| - mount.nfs: insert 'sloppy' at beginning of the options (bz 1967883) | ||||
| 
 | ||||
| * Mon May 10 2021 Steve Dickson <steved@redhat.com> 2.3.3-42 | ||||
| - gssd: Add options to allow for the use of ~/.k5identity file (bz 1868087) | ||||
| - man: Correct gssd(8) description of rpc-timeout and context-timeout (bz 1908232) | ||||
| - exportfs: fix unexporting of '/' (bz 1944119) | ||||
| 
 | ||||
| * Wed Jan 20 2021 Steve Dickson <steved@redhat.com> 2.3.3-41 | ||||
| - mountd: never root squash on the pseudofs (bz 1804912) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user