summaryrefslogtreecommitdiffstats
path: root/utils/svcgssd
diff options
context:
space:
mode:
authorneilbrown <neilbrown>2005-08-26 01:27:17 +0000
committerneilbrown <neilbrown>2005-08-26 01:27:17 +0000
commita980156c122e975cc185a6c41ef705f166a5765f (patch)
tree8b30d51307c9abc8fa3b307f66423054d0f0d289 /utils/svcgssd
parentc5ea2fbc9ab9d142aa867da594a66f4097df03d1 (diff)
downloadnfs-utils-a980156c122e975cc185a6c41ef705f166a5765f.tar.gz
nfs-utils-a980156c122e975cc185a6c41ef705f166a5765f.tar.xz
nfs-utils-a980156c122e975cc185a6c41ef705f166a5765f.zip
2005-08-26 Kevin Coffman <kwc@citi.umich.edu>
* utils/exportfs/exports.man: Document the "crossmnt" export export option * utils/gssd/krb5_util.c: Add better debugging and partially revert the function check for gss_krb5_ccache_name. For MIT Kerberos releases up to and including 1.3.1, we *must* use the routine gss_krb5_ccache_name to get the K5 gssapi code to use a different credentials cache. For releases 1.3.2 and on, we want to use the KRB5CCNAME environment variable to tell it what to use. (A problem was reported where 1.3.5 was being used, our code was using gss_krb5_ccache_name, but the underlying code continued to use the first (or default?) credentials cache. Switching to using the env variable fixed the problem. I cannot recreate this problem. *utils/gssd/krb5_util.c: Andrew Mahone <andrew.mahone@gmail.com> reported that reiser4 always has DT_UNKNOWN. He supplied patch to move the check for regular files after the stat() call to correctly find ccache files in reiser4 filesystem. Also change the name comparison so that the wrong file is not selected when the substring comparison is done. *utils/gssd/krb5_util.c: Limit the set of encryption types that can be negotiated by the Kerberos library to those that the kernel code currently supports. This should eventually query the kernel for the list of supported enctypes. *utils/gssd/gss_util.c, utils/svcgssd/svcgssd_main_loop.c: Print more information in error messages to help debugging failures. *utils/svcgssd/svcgssd_proc.c: Increase token buffer size and update error handling so that a response is always sent. *utils/svcgssd/svcgssd_proc.c: Add support to retrieve supplementary groups.
Diffstat (limited to 'utils/svcgssd')
-rw-r--r--utils/svcgssd/svcgssd_main_loop.c11
-rw-r--r--utils/svcgssd/svcgssd_proc.c54
2 files changed, 43 insertions, 22 deletions
diff --git a/utils/svcgssd/svcgssd_main_loop.c b/utils/svcgssd/svcgssd_main_loop.c
index 477a44c..280816d 100644
--- a/utils/svcgssd/svcgssd_main_loop.c
+++ b/utils/svcgssd/svcgssd_main_loop.c
@@ -58,19 +58,24 @@ gssd_run()
f = fopen(NULLRPC_FILE, "rw");
if (!f) {
- printerr(0, "failed to open %s\n", NULLRPC_FILE);
+ printerr(0, "failed to open %s: %s\n",
+ NULLRPC_FILE, strerror(errno));
exit(1);
}
pollfd.fd = fileno(f);
pollfd.events = POLLIN;
while (1) {
+ int save_err;
+
pollfd.revents = 0;
printerr(1, "entering poll\n");
ret = poll(&pollfd, 1, -1);
+ save_err = errno;
printerr(1, "leaving poll\n");
if (ret < 0) {
- if (errno != EINTR)
- printerr(0, "error return from poll\n");
+ if (save_err != EINTR)
+ printerr(0, "error return from poll: %s\n",
+ strerror(save_err));
} else if (ret == 0) {
/* timeout; shouldn't happen. */
} else {
diff --git a/utils/svcgssd/svcgssd_proc.c b/utils/svcgssd/svcgssd_proc.c
index 8faddc1..dfa3c4c 100644
--- a/utils/svcgssd/svcgssd_proc.c
+++ b/utils/svcgssd/svcgssd_proc.c
@@ -52,11 +52,6 @@
#include "context.h"
#include "cacheio.h"
-/* XXX: ? */
-#ifndef NGROUPS
-#define NGROUPS 32
-#endif
-
extern char * mech2file(gss_OID mech);
#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel"
#define SVCGSSD_INIT_CHANNEL "/proc/net/rpc/auth.rpcsec.init/channel"
@@ -162,6 +157,30 @@ send_response(FILE *f, gss_buffer_desc *in_handle, gss_buffer_desc *in_token,
#define rpcsec_gsserr_credproblem 13
#define rpcsec_gsserr_ctxproblem 14
+static void
+add_supplementary_groups(char *secname, char *name, struct svc_cred *cred)
+{
+ int ret;
+ static gid_t *groups = NULL;
+
+ cred->cr_ngroups = NGROUPS;
+ ret = nfs4_gss_princ_to_grouplist(secname, name,
+ cred->cr_groups, &cred->cr_ngroups);
+ if (ret < 0) {
+ groups = realloc(groups, cred->cr_ngroups*sizeof(gid_t));
+ ret = nfs4_gss_princ_to_grouplist(secname, name,
+ groups, &cred->cr_ngroups);
+ if (ret < 0)
+ cred->cr_ngroups = 0;
+ else {
+ if (cred->cr_ngroups > NGROUPS)
+ cred->cr_ngroups = NGROUPS;
+ memcpy(cred->cr_groups, groups,
+ cred->cr_ngroups*sizeof(gid_t));
+ }
+ }
+}
+
static int
get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred)
{
@@ -172,6 +191,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred)
uid_t uid, gid;
gss_OID name_type;
char *secname;
+ gid_t *groups;
maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
if (maj_stat != GSS_S_COMPLETE)
@@ -190,8 +210,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred)
goto out_free;
cred->cr_uid = uid;
cred->cr_gid = gid;
- /*XXX: want add_supplementary_groups(secname, sname, cred)? */
- cred->cr_ngroups = 0;
+ add_supplementary_groups(secname, sname, cred);
res = 0;
out_free:
free(sname);
@@ -243,7 +262,7 @@ handle_nullreq(FILE *f) {
/* XXX initialize to a random integer to reduce chances of unnecessary
* invalidation of existing ctx's on restarting svcgssd. */
static u_int32_t handle_seq = 0;
- char in_tok_buf[1023];
+ char in_tok_buf[8192];
char in_handle_buf[15];
char out_handle_buf[15];
gss_buffer_desc in_tok = {.value = in_tok_buf},
@@ -273,15 +292,16 @@ handle_nullreq(FILE *f) {
cp = lbuf;
- in_handle.length
- = qword_get(&cp, in_handle.value, sizeof(in_handle_buf));
+ in_handle.length = (size_t) qword_get(&cp, in_handle.value,
+ sizeof(in_handle_buf));
printerr(2, "in_handle: \n");
print_hexl(2, in_handle.value, in_handle.length);
handle_seq++;
out_handle.length = sizeof(handle_seq);
memcpy(out_handle.value, &handle_seq, sizeof(handle_seq));
- in_tok.length = qword_get(&cp, in_tok.value, sizeof(in_tok_buf));
+ in_tok.length = (size_t) qword_get(&cp, in_tok.value,
+ sizeof(in_tok_buf));
printerr(2, "in_tok: \n");
print_hexl(2, in_tok.value, in_tok.length);
@@ -294,8 +314,6 @@ handle_nullreq(FILE *f) {
if (in_handle.length != 0) { /* CONTINUE_INIT case */
printerr(0, "WARNING: handle_nullreq: "
"CONTINUE_INIT unsupported\n");
- send_response(f, &in_handle, &in_tok, -1, -1, &null_token,
- &null_token);
goto out_err;
}
@@ -306,14 +324,11 @@ handle_nullreq(FILE *f) {
printerr(0, "WARNING: gss_accept_sec_context failed\n");
pgsserr("handle_nullreq: gss_accept_sec_context",
maj_stat, min_stat, mech);
- send_response(f, &in_handle, &in_tok, maj_stat, min_stat,
- &null_token, &null_token);
goto out_err;
}
if (get_ids(client_name, mech, &cred)) {
printerr(0, "WARNING: handle_nullreq: get_uid failed\n");
- send_response(f, &in_handle, &in_tok, GSS_S_BAD_NAME /* XXX? */,
- 0, &null_token, &null_token);
+ maj_stat = GSS_S_BAD_NAME; /* XXX ? */
goto out_err;
}
@@ -322,8 +337,7 @@ handle_nullreq(FILE *f) {
if (serialize_context_for_kernel(ctx, &ctx_token)) {
printerr(0, "WARNING: handle_nullreq: "
"serialize_context_for_kernel failed\n");
- send_response(f, &in_handle, &in_tok, -1, /* XXX? */
- 0, &null_token, &null_token);
+ maj_stat = GSS_S_FAILURE;
goto out_err;
}
do_svc_downcall(&out_handle, &cred, mech, &ctx_token);
@@ -331,6 +345,8 @@ handle_nullreq(FILE *f) {
&out_handle, &out_tok);
goto out;
out_err:
+ send_response(f, &in_handle, &in_tok, maj_stat, min_stat,
+ &null_token, &null_token);
out:
if (ctx_token.value != NULL)
free(ctx_token.value);