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