summaryrefslogtreecommitdiffstats
path: root/utils/svcgssd/svcgssd_proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/svcgssd/svcgssd_proc.c')
-rw-r--r--utils/svcgssd/svcgssd_proc.c54
1 files changed, 35 insertions, 19 deletions
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);