From owner-freebsd-fs@FreeBSD.ORG Sat Feb 23 15:35:48 2013 Return-Path: Delivered-To: freebsd-fs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 4715A221 for ; Sat, 23 Feb 2013 15:35:48 +0000 (UTC) (envelope-from rmacklem@uoguelph.ca) Received: from esa-jnhn.mail.uoguelph.ca (esa-jnhn.mail.uoguelph.ca [131.104.91.44]) by mx1.freebsd.org (Postfix) with ESMTP id D792E1F7 for ; Sat, 23 Feb 2013 15:35:47 +0000 (UTC) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqAEABPhKFGDaFvO/2dsb2JhbABFhk+4KYJagR9zgh8BAQQBIwRSBRYYAgINGQJZBoggBq0ZhBCNcIEjjDSBAzQHgi2BEwOIaY1UkGWDJYIJ X-IronPort-AV: E=Sophos;i="4.84,721,1355115600"; d="scan'208";a="17925705" Received: from erie.cs.uoguelph.ca (HELO zcs3.mail.uoguelph.ca) ([131.104.91.206]) by esa-jnhn.mail.uoguelph.ca with ESMTP; 23 Feb 2013 10:35:47 -0500 Received: from zcs3.mail.uoguelph.ca (localhost.localdomain [127.0.0.1]) by zcs3.mail.uoguelph.ca (Postfix) with ESMTP id 1288CB3EE4; Sat, 23 Feb 2013 10:35:47 -0500 (EST) Date: Sat, 23 Feb 2013 10:35:47 -0500 (EST) From: Rick Macklem To: Momchil Ivanov Message-ID: <508324799.3234256.1361633747016.JavaMail.root@erie.cs.uoguelph.ca> In-Reply-To: <86hal3kzp8.wl%momchil@xaxo.eu> Subject: Re: NFS + Kerberos MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [172.17.91.203] X-Mailer: Zimbra 6.0.10_GA_2692 (ZimbraWebClient - FF3.0 (Win)/6.0.10_GA_2692) Cc: freebsd-fs@freebsd.org, Elias Martenson X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 Feb 2013 15:35:48 -0000 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