]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/svcgssd/svcgssd_proc.c
2005-08-26 Kevin Coffman <kwc@citi.umich.edu>
[nfs-utils.git] / utils / svcgssd / svcgssd_proc.c
index 8faddc1321ac3cded03e4ae9b63ae7912286a2b9..dfa3c4c8d7b69f4f1cfcaf2ff3585bc859ae88c2 100644 (file)
 #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);