Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Feb 2013 10:35:47 -0500 (EST)
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        Momchil Ivanov <momchil@xaxo.eu>
Cc:        freebsd-fs@freebsd.org, Elias Martenson <lokedhs@gmail.com>
Subject:   Re: NFS + Kerberos
Message-ID:  <508324799.3234256.1361633747016.JavaMail.root@erie.cs.uoguelph.ca>
In-Reply-To: <86hal3kzp8.wl%momchil@xaxo.eu>

next in thread | previous in thread | raw e-mail | index | archive | help
Momchil Ivanov wrote:
> At Fri, 22 Feb 2013 19:04:23 -0500 (EST),
> Rick Macklem wrote:
> > You can run "gssd -d -d" and it will run in foreground and print
> > out messages related to resource allocation. This isn't much use,
> > except to tell you that it is doing something. (Adding a "verbose"
> > option is on my "to do" list, but I don't have any code at this
> > time.
> > If someone wants to do this, I think it would be great.)
> >
> > If you do this, don't have it started at boot (gssd_enable="NO" in
> > /etc/rc.conf) and then do the above command as root in a window
> > before attempting the mount command.
> >
> > Beyond that, you could add printfs to gssd.c. The main client side
> > function is gssd_init_sec_context(), which should get the Kerberos
> > ticket for a user via their TGT.
> 
> well, the server doesn't seem to start it at boot with
> gssd_enable="YES", I don't know why, but I cannot stop/restart nfsd
> until I manually start gssd :) the client starts it at boot, though
> 
> note: I can ssh into the server even when gssd is not running, I don't
> know if this is expected.
> 
Yes. The gssd only handles upcalls from the kernel and only NFS does
those at this time.

> "gssd -d -d" prints things like this on the client and the server:
> 
> 1 resources allocated
> 2 resources allocated
> 1 resources allocated
> 0 resources allocated
> 1 resources allocated
> 2 resources allocated
> 1 resources allocated
> 0 resources allocated
> 1 resources allocated
> 2 resources allocated
> 1 resources allocated
> 0 resources allocated
> 
> which doesn't tell me anything :) so here is what happens on the
> client without a kerberos ticket:
> 
> 1 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:279 FILE:/tmp/krb5cc_1001
> > init_sec_context_args
> uid: 1001
> cred: 0
> ctx: 0
> name: 5848115787646107649
> req_flags: 5848115787646107650
> > gss_resources
> i=0
> gr_id :5848115787646107649
> gr_res :0x28203060
> /usr/src/usr.sbin/gssd/gssd.c:307 argp->name
> /usr/src/usr.sbin/gssd/gssd.c:309 name=673198176
> /usr/src/usr.sbin/gssd/gssd.c:310 name=0x28203060
> 0 resources allocated
> 1 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:279 FILE:/tmp/krb5cc_1001
> > init_sec_context_args
> uid: 1001
> cred: 0
> ctx: 0
> name: 5848115787646107650
> req_flags: 5848115787646107650
> > gss_resources
> i=0
> gr_id :5848115787646107650
> gr_res :0x28203060
> /usr/src/usr.sbin/gssd/gssd.c:307 argp->name
> /usr/src/usr.sbin/gssd/gssd.c:309 name=673198176
> /usr/src/usr.sbin/gssd/gssd.c:310 name=0x28203060
> 0 resources allocated
> 1 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:279 FILE:/tmp/krb5cc_1001
> > init_sec_context_args
> uid: 1001
> cred: 0
> ctx: 0
> name: 5848115787646107651
> req_flags: 5848115787646107650
> > gss_resources
> i=0
> gr_id :5848115787646107651
> gr_res :0x28203060
> /usr/src/usr.sbin/gssd/gssd.c:307 argp->name
> /usr/src/usr.sbin/gssd/gssd.c:309 name=673198176
> /usr/src/usr.sbin/gssd/gssd.c:310 name=0x28203060
> 0 resources allocated
> 
> here is what happens with a kerberos ticket:
> 
> 1 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:279 FILE:/tmp/krb5cc_1001
> > init_sec_context_args
> uid: 1001
> cred: 0
> ctx: 0
> name: 5848116041049178113
> req_flags: 5848116041049178114
> > gss_resources
> i=0
> gr_id :5848116041049178113
> gr_res :0x28203060
> /usr/src/usr.sbin/gssd/gssd.c:307 argp->name
> /usr/src/usr.sbin/gssd/gssd.c:309 name=673198176
> /usr/src/usr.sbin/gssd/gssd.c:310 name=0x28203060
> 2 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:335 GSS_S_CONTINUE_NEEDED
> 1 resources allocated
> 0 resources allocated
> 1 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:279 FILE:/tmp/krb5cc_1001
> > init_sec_context_args
> uid: 1001
> cred: 0
> ctx: 0
> name: 5848116041049178115
> req_flags: 5848116041049178114
> > gss_resources
> i=0
> gr_id :5848116041049178115
> gr_res :0x28203060
> /usr/src/usr.sbin/gssd/gssd.c:307 argp->name
> /usr/src/usr.sbin/gssd/gssd.c:309 name=673198176
> /usr/src/usr.sbin/gssd/gssd.c:310 name=0x28203060
> 2 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:335 GSS_S_CONTINUE_NEEDED
> 1 resources allocated
> 0 resources allocated
> 1 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:279 FILE:/tmp/krb5cc_1001
> > init_sec_context_args
> uid: 1001
> cred: 0
> ctx: 0
> name: 5848116041049178117
> req_flags: 5848116041049178114
> > gss_resources
> i=0
> gr_id :5848116041049178117
> gr_res :0x28203060
> /usr/src/usr.sbin/gssd/gssd.c:307 argp->name
> /usr/src/usr.sbin/gssd/gssd.c:309 name=673198176
> /usr/src/usr.sbin/gssd/gssd.c:310 name=0x28203060
> 2 resources allocated
> /usr/src/usr.sbin/gssd/gssd.c:335 GSS_S_CONTINUE_NEEDED
> 1 resources allocated
> 0 resources allocated
> 
The above looks reasonable. Once the gssd_init_sec_context()
replies GSS_S_CONTINUE_NEEDED to the kernel with the token
that has the session ticket in it, then...
- The NFS client sends a Null RPC to the server with an
  authenticator of type RPCSEC_GSS with
  version: 1
  RPCSEC_GSS_INIT
  and the token as data on the Null RPC (a Null RPC woundn't
  normally have any data)
- the server processes this via an upcall to its gssd for
  gssd_accept_sec_context()
  - this would get a reply of GSS_S_COMPLETE I think (although
    there may be cases where a GSS_S_CONTINUE_NEEDED occurs
    and there is another cycle of Null RPC token passing)
- this would result in a reply to the Null RPC with an
  RPCSEC_GSS authenticator with roughly:
  - a credential handle (shorthand bits for the user principal)
  - GSS_S_COMPLETE status
- it has been a while, so I can't remember for sure, but I think
  a successful reply includes a token that is passed up to the
  gssd via gssd_init_sec_context() and then it would return
  GSS_S_COMPLETE when the token is processed.

My guess is that it is the server that is replying with some
failure status GSS_S_xxx.

At this point, you can either try and look at the Null RPC
in wireshark or add printfs to the server's gssd.c for
gssd_accept_sec_context() and gssd_acquire_cred().

Basically, the above looks ok, but the rest of the handshake
that generates a credential handle via the Kerberos session
ticket hasn't happened.

Good luck with it, rick

> here is what I have changed:
> 
> --- gssd.c.orig 2013-02-23 11:13:20.000000000 +0100
> +++ gssd.c 2013-02-23 12:34:33.000000000 +0100
> @@ -238,6 +238,33 @@
> return (TRUE);
> }
> 
> +static void
> +dump_resources(FILE *s)
> +{
> + struct gss_resource *gr;
> + int i;
> +
> + fprintf(s, "> gss_resources\n");
> +
> + i = 0;
> + LIST_FOREACH(gr, &gss_resources, gr_link) {
> + fprintf(s, "i=%d\n", i);
> + fprintf(s, "gr_id :%llu\n", gr->gr_id);
> + fprintf(s, "gr_res :%p\n", gr->gr_res);
> + }
> +}
> +
> +void
> +dump_init_sec_context_args(FILE *s, init_sec_context_args *p)
> +{
> + fprintf(s, "> init_sec_context_args\n");
> + fprintf(s, "uid: %d\n", p->uid);
> + fprintf(s, "cred: %llu\n", p->cred);
> + fprintf(s, "ctx: %llu\n", p->ctx);
> + fprintf(s, "name: %llu\n", p->name);
> + fprintf(s, "req_flags: %llu\n", p->req_flags);
> +}
> +
> bool_t
> gssd_init_sec_context_1_svc(init_sec_context_args *argp,
> init_sec_context_res *result, struct svc_req *rqstp)
> {
> @@ -248,27 +275,42 @@
> 
> snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_%d",
> (int) argp->uid);
> +
> + printf("%s:%d %s\n", __FILE__, __LINE__, ccname);
> + dump_init_sec_context_args(stdout, argp);
> + dump_resources(stdout);
> +
> setenv("KRB5CCNAME", ccname, TRUE);
> 
> memset(result, 0, sizeof(*result));
> if (argp->cred) {
> + printf("%s:%d argp->cred\n", __FILE__, __LINE__);
> cred = gssd_find_resource(argp->cred);
> + printf("%s:%d cred=%llu\n", __FILE__, __LINE__, cred);
> if (!cred) {
> result->major_status = GSS_S_CREDENTIALS_EXPIRED;
> + printf("%s:%d GSS_S_CREDENTIALS_EXPIRED\n", __FILE__, __LINE__);
> return (TRUE);
> }
> }
> if (argp->ctx) {
> + printf("%s:%d argp->ctx\n", __FILE__, __LINE__);
> ctx = gssd_find_resource(argp->ctx);
> + printf("%s:%d ctx=%llu\n", __FILE__, __LINE__, ctx);
> if (!ctx) {
> result->major_status = GSS_S_CONTEXT_EXPIRED;
> + printf("%s:%d GSS_S_CONTEXT_EXPIRED\n", __FILE__, __LINE__);
> return (TRUE);
> }
> }
> if (argp->name) {
> + printf("%s:%d argp->name\n", __FILE__, __LINE__);
> name = gssd_find_resource(argp->name);
> + printf("%s:%d name=%llu\n", __FILE__, __LINE__, name);
> + printf("%s:%d name=%p\n", __FILE__, __LINE__, name);
> if (!name) {
> result->major_status = GSS_S_BAD_NAME;
> + printf("%s:%d GSS_S_BAD_NAME\n", __FILE__, __LINE__);
> return (TRUE);
> }
> }
> @@ -286,6 +328,11 @@
> result->ctx = argp->ctx;
> else
> result->ctx = gssd_make_resource(ctx);
> +
> + if (result->major_status == GSS_S_COMPLETE)
> + printf("%s:%d GSS_S_COMPLETE\n", __FILE__, __LINE__);
> + else
> + printf("%s:%d GSS_S_CONTINUE_NEEDED\n", __FILE__, __LINE__);
> }
> 
> return (TRUE);
> 
> Ideas?
> 
> Thank you,
> Momchil



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?508324799.3234256.1361633747016.JavaMail.root>