Re: Possible bug in NFSv4 with krb5p security?

2013-03-25 Thread Rick Macklem
Andrey Simonenko wrote:
> On Wed, Feb 20, 2013 at 06:29:07PM -0500, Rick Macklem wrote:
> > Andrey Simonnenko wrote:
> > >
> > > Another variant. This is a program that can be used for verifying
> > > correctness of the function, just change PWBUF_SIZE_* values and
> > > put
> > > some printfs to see when buffer is reallocated. sizehint is
> > > updated
> > > only when malloc() succeeded.
> > >
> > > -
> > > static int
> > > getpwnam_r_func(const char *name, uid_t *uidp)
> > > {
> > > #define PWBUF_SIZE_INI (2 * MAXLOGNAME + MAXPATHLEN +
> > > _PASSWORD_LEN)
> > > #define PWBUF_SIZE_INC 128
> > >
> > >   static size_t sizehint = PWBUF_SIZE_INI;
> > >
> > >   struct passwd pwd;
> > >   struct passwd *pw;
> > >   char *buf;
> > >   size_t size;
> > >   int error;
> > >   char lname[MAXLOGNAME];
> > >   char bufs[PWBUF_SIZE_INI];
> > >
> > >   strncpy(lname, name, sizeof(lname));
> > >
> > >   buf = bufs;
> > >   size = sizeof(bufs);
> > >   for (;;) {
> > >   error = getpwnam_r(lname, &pwd, buf, size, &pw);
> > >   if (buf != bufs)
> > >   free(buf);
> > >   if (pw != NULL) {
> > >   *uidp = pw->pw_uid;
> > >   return (GSS_S_COMPLETE);
> > >   } else if (error != ERANGE || size > SIZE_MAX - PWBUF_SIZE_INC)
> > >   return (GSS_S_FAILURE);
> > >   if (size != sizehint)
> > >   size = sizehint;
> > >   else
> > >   size += PWBUF_SIZE_INC;
> > >   buf = malloc(size);
> > >   if (buf == NULL)
> > >   return (GSS_S_FAILURE);
> > >   sizehint = size;
> > >   }
> > > }
> > >
> > All looks fine to me. (Before my mailer messed with the
> > whitespace;-)
> >
> > Thanks, rick
> > ps: I will commit it in April, unless someone else does so sooner.
> 
> I was thinking about this approach once again and made a conclusion
> that
> it is wrong. Using static buffer at first and then allocate memory for
> next calls can cause slowdown, depends on number of entries and used
> database backend of course. The libc code for getpwnam() allocates
> memory for the buffer and does not free it on exit from the function,
> 
Not sure what you were saying by the last sentence? Using a static
buffer here would make the code unsafe for multiple threads. Although
the gssd is currently single threaded, that might change someday, maybe?
(Using the static as a "hint" should be safe for multiple threads, since
 it is just a hint.)

> If the above written code or any of its modification is going to be
> committed to the source base (by you or by some another committer),
> then I ask and require to not write/mention my name and email address
> neither in source file nor in commit log message.
> 
Ok, that's your choice.

I think the code is fine, since the likelyhood
of the first getpwuid_r() with the buffer on the stack failing is nearly
0, given that it is much bigger than 128. (Although I think a loop on
ERANGE should be in the code, just making the buffer a lot bigger than
128 will fix the problem for 99.9% of the cases.)
The only change I was planning to the above was moving the free(buf)
down until after "pwd" has been used, so it is safe for fields like pw_name,
which I think will live in "buf". That way the code won't be broken if/when
someone uses it for pw_name.

rick

> Appropriate commit log message for the above written code can be the
> following:
> 
> --
> Since FreeBSD does not support sysconf(_SC_GETPW_R_SIZE_MAX), then
> allocate
> a buffer of sufficient size for getpwnam_r() as it is suggested in
> EXAMPLES
> of SUSv4 documentation for the getpwnam_r() function.
> --
> 
> since this documentation has similar code.
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
> "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-03-25 Thread Andrey Simonenko
On Wed, Feb 20, 2013 at 06:29:07PM -0500, Rick Macklem wrote:
> Andrey Simonnenko wrote:
> > 
> > Another variant. This is a program that can be used for verifying
> > correctness of the function, just change PWBUF_SIZE_* values and put
> > some printfs to see when buffer is reallocated. sizehint is updated
> > only when malloc() succeeded.
> > 
> > -
> > static int
> > getpwnam_r_func(const char *name, uid_t *uidp)
> > {
> > #define PWBUF_SIZE_INI (2 * MAXLOGNAME + MAXPATHLEN + _PASSWORD_LEN)
> > #define PWBUF_SIZE_INC 128
> > 
> > static size_t sizehint = PWBUF_SIZE_INI;
> > 
> > struct passwd pwd;
> > struct passwd *pw;
> > char *buf;
> > size_t size;
> > int error;
> > char lname[MAXLOGNAME];
> > char bufs[PWBUF_SIZE_INI];
> > 
> > strncpy(lname, name, sizeof(lname));
> > 
> > buf = bufs;
> > size = sizeof(bufs);
> > for (;;) {
> > error = getpwnam_r(lname, &pwd, buf, size, &pw);
> > if (buf != bufs)
> > free(buf);
> > if (pw != NULL) {
> > *uidp = pw->pw_uid;
> > return (GSS_S_COMPLETE);
> > } else if (error != ERANGE || size > SIZE_MAX - PWBUF_SIZE_INC)
> > return (GSS_S_FAILURE);
> > if (size != sizehint)
> > size = sizehint;
> > else
> > size += PWBUF_SIZE_INC;
> > buf = malloc(size);
> > if (buf == NULL)
> > return (GSS_S_FAILURE);
> > sizehint = size;
> > }
> > }
> > 
> All looks fine to me. (Before my mailer messed with the whitespace;-)
> 
> Thanks, rick
> ps: I will commit it in April, unless someone else does so sooner.

I was thinking about this approach once again and made a conclusion that
it is wrong.  Using static buffer at first and then allocate memory for
next calls can cause slowdown, depends on number of entries and used
database backend of course.  The libc code for getpwnam() allocates
memory for the buffer and does not free it on exit from the function,

If the above written code or any of its modification is going to be
committed to the source base (by you or by some another committer),
then I ask and require to not write/mention my name and email address
neither in source file nor in commit log message.

Appropriate commit log message for the above written code can be the
following:

--
Since FreeBSD does not support sysconf(_SC_GETPW_R_SIZE_MAX), then allocate
a buffer of sufficient size for getpwnam_r() as it is suggested in EXAMPLES
of SUSv4 documentation for the getpwnam_r() function.
--

since this documentation has similar code.
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-20 Thread Rick Macklem
Andrey Simonnenko wrote:
> On Tue, Feb 19, 2013 at 08:52:49PM -0500, Rick Macklem wrote:
> > >
> > > I cannot find how to get information about maximum buffer size for
> > > the getpwnam_r() function. This information should be returned by
> > > sysconf(_SC_GETPW_R_SIZE_MAX), but since it does not work on
> > > FreeBSD
> > > it is necessary to guess its size. Original value is 128 and it
> > > works
> > > for somebody, 1024 works for your environment, but it can fail for
> > > another environment.
> > >
> > > SUSv4 specifies "Storage referenced by the structure is allocated
> > > from
> > > the memory provided with the buffer parameter", but then tells
> > > about
> > > groups
> > > in EXAMPLE for getpwnam_r() "Note that
> > > sysconf(_SC_GETPW_R_SIZE_MAX)
> > > may
> > > return -1 if there is no hard limit on the size of the buffer
> > > needed
> > > to
> > > store all the groups returned".
> > >
> > > malloc() can give overhead, but that function can try to call
> > > getpwnam_r()
> > > with buffer allocated from stack and if getpwnam_r() failed with
> > > ERANGE
> > > use dynamically allocated buffer.
> > >
> > > #define PWBUF_SIZE_INI (2 * MAXLOGNAME + 2 * MAXPATHLEN +
> > > _PASSWORD_LEN + 1)
> > > #define PWBUF_SIZE_INC 128
> > >
> > > char bufs[2 * MAXLOGNAME + MAXPATHLEN + PASSWORD_LEN + 1 + 32];
> > >
> > > error = getpwnam_r(lname, &pwd, bufs, sizeof(bufs), &pw);
> > > if (pw != NULL) {
> > > *uidp = pw->pw_uid;
> > > return (GSS_S_COMPLETE);
> > > } else if (error != ERANGE)
> > > return (GSS_S_FAILURE);
> > >
> > > size = PWBUF_SIZE_INI;
> > > for (;;) {
> > > size += PWBUF_SIZE_INC;
> > > buf = malloc(size);
> > > if (buf == NULL)
> > > return (GSS_S_FAILURE);
> > > error = getpwnam_r(lname, &pwd, buf, size, &pw);
> > > free(buf);
> > > if (pw != NULL) {
> > > *uidp = pw->pw_uid;
> > > return (GSS_S_COMPLETE);
> > > } else {
> > > if (error == ERANGE &&
> > > size <= SIZE_MAX - PWBUF_SIZE_INC)
> > > continue;
> > > return (GSS_S_FAILURE);
> > > }
> > > }
> >
> > Just my opinion, but I think the above is a good approach.
> > (ie. First trying a fairly large buffer on the stack that
> >  will succeed 99.99% of the time, but check for ERANGE and
> >  loop trying progressively larger malloc'd buffers until
> >  it stops reporting ERANGE.)
> >
> > I suspect the overheads behind getpwnam_r() are larger than
> > the difference between using a buffer on the stack vs malloc,
> > so I think it should use a fairly large buffer the first time.
> >
> > Personally, I might have coded it as a single do { } while(),
> > with the first attempt in it, but that's just personal stylistic
> > taste. (You can check for buf != bufs before doing a free() of it.)
> > And, if you wanted to be clever, the code could use a static
> > "bufsiz_hint",
> > which is set to the largest size needed sofar and that is used as
> > the initial malloc size. That way it wouldn't loop as much for a
> > site with huge passwd entries. (An entire bio in the GECOS field or
> > ???)
> >
> 
> Thanks for the review.
> 
> Another variant. This is a program that can be used for verifying
> correctness of the function, just change PWBUF_SIZE_* values and put
> some printfs to see when buffer is reallocated. sizehint is updated
> only when malloc() succeeded.
> 
> -
> #include 
> #include 
> 
> #include 
> 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> 
> static int
> getpwnam_r_func(const char *name, uid_t *uidp)
> {
> #define PWBUF_SIZE_INI (2 * MAXLOGNAME + MAXPATHLEN + _PASSWORD_LEN)
> #define PWBUF_SIZE_INC 128
> 
> static size_t sizehint = PWBUF_SIZE_INI;
> 
> struct passwd pwd;
> struct passwd *pw;
> char *buf;
> size_t size;
> int error;
> char lname[MAXLOGNAME];
> char bufs[PWBUF_SIZE_INI];
> 
> strncpy(lname, name, sizeof(lname));
> 
> buf = bufs;
> size = sizeof(bufs);
> for (;;) {
> error = getpwnam_r(lname, &pwd, buf, size, &pw);
> if (buf != bufs)
> free(buf);
> if (pw != NULL) {
> *uidp = pw->pw_uid;
> return (GSS_S_COMPLETE);
> } else if (error != ERANGE || size > SIZE_MAX - PWBUF_SIZE_INC)
> return (GSS_S_FAILURE);
> if (size != sizehint)
> size = sizehint;
> else
> size += PWBUF_SIZE_INC;
> buf = malloc(size);
> if (buf == NULL)
> return (GSS_S_FAILURE);
> sizehint = size;
> }
> }
> 
All looks fine to me. (Before my mailer messed with the whitespace;-)

Thanks, rick
ps: I will commit it in April, unless someone else does so sooner.

> int
> main(void)
> {
> const char *str[] = { "man", "root", "q", "bin", NULL };
> uid_t uid;
> u_int i;
> 
> for (i = 0; str[i] != NULL; ++i) {
> printf("%-20s\t", str[i]);
> if (getpwnam_r_func(str[i], &uid) == GSS_S_COMPLETE)
> printf("%u\n", uid);
> else
> printf("not found\n");
> }
> return (0);
> }
> -
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
> "

Re: Possible bug in NFSv4 with krb5p security?

2013-02-20 Thread Andrey Simonenko
On Tue, Feb 19, 2013 at 08:52:49PM -0500, Rick Macklem wrote:
> > 
> > I cannot find how to get information about maximum buffer size for
> > the getpwnam_r() function. This information should be returned by
> > sysconf(_SC_GETPW_R_SIZE_MAX), but since it does not work on FreeBSD
> > it is necessary to guess its size. Original value is 128 and it works
> > for somebody, 1024 works for your environment, but it can fail for
> > another environment.
> > 
> > SUSv4 specifies "Storage referenced by the structure is allocated from
> > the memory provided with the buffer parameter", but then tells about
> > groups
> > in EXAMPLE for getpwnam_r() "Note that sysconf(_SC_GETPW_R_SIZE_MAX)
> > may
> > return -1 if there is no hard limit on the size of the buffer needed
> > to
> > store all the groups returned".
> > 
> > malloc() can give overhead, but that function can try to call
> > getpwnam_r()
> > with buffer allocated from stack and if getpwnam_r() failed with
> > ERANGE
> > use dynamically allocated buffer.
> > 
> > #define PWBUF_SIZE_INI (2 * MAXLOGNAME + 2 * MAXPATHLEN +
> > _PASSWORD_LEN + 1)
> > #define PWBUF_SIZE_INC 128
> > 
> > char bufs[2 * MAXLOGNAME + MAXPATHLEN + PASSWORD_LEN + 1 + 32];
> > 
> > error = getpwnam_r(lname, &pwd, bufs, sizeof(bufs), &pw);
> > if (pw != NULL) {
> > *uidp = pw->pw_uid;
> > return (GSS_S_COMPLETE);
> > } else if (error != ERANGE)
> > return (GSS_S_FAILURE);
> > 
> > size = PWBUF_SIZE_INI;
> > for (;;) {
> > size += PWBUF_SIZE_INC;
> > buf = malloc(size);
> > if (buf == NULL)
> > return (GSS_S_FAILURE);
> > error = getpwnam_r(lname, &pwd, buf, size, &pw);
> > free(buf);
> > if (pw != NULL) {
> > *uidp = pw->pw_uid;
> > return (GSS_S_COMPLETE);
> > } else {
> > if (error == ERANGE &&
> > size <= SIZE_MAX - PWBUF_SIZE_INC)
> > continue;
> > return (GSS_S_FAILURE);
> > }
> > }
> 
> Just my opinion, but I think the above is a good approach.
> (ie. First trying a fairly large buffer on the stack that
>  will succeed 99.99% of the time, but check for ERANGE and
>  loop trying progressively larger malloc'd buffers until
>  it stops reporting ERANGE.)
> 
> I suspect the overheads behind getpwnam_r() are larger than
> the difference between using a buffer on the stack vs malloc,
> so I think it should use a fairly large buffer the first time.
> 
> Personally, I might have coded it as a single do { } while(),
> with the first attempt in it, but that's just personal stylistic
> taste. (You can check for buf != bufs before doing a free() of it.)
> And, if you wanted to be clever, the code could use a static "bufsiz_hint",
> which is set to the largest size needed sofar and that is used as
> the initial malloc size. That way it wouldn't loop as much for a
> site with huge passwd entries. (An entire bio in the GECOS field or ???)
> 

Thanks for the review.

Another variant.  This is a program that can be used for verifying
correctness of the function, just change PWBUF_SIZE_* values and put
some printfs to see when buffer is reallocated.  sizehint is updated
only when malloc() succeeded.

-
#include 
#include 

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

static int
getpwnam_r_func(const char *name, uid_t *uidp)
{
#define PWBUF_SIZE_INI (2 * MAXLOGNAME + MAXPATHLEN + _PASSWORD_LEN)
#define PWBUF_SIZE_INC 128

static size_t sizehint = PWBUF_SIZE_INI;

struct passwd pwd;
struct passwd *pw;
char *buf;
size_t size;
int error;
char lname[MAXLOGNAME];
char bufs[PWBUF_SIZE_INI];

strncpy(lname, name, sizeof(lname));

buf = bufs;
size = sizeof(bufs);
for (;;) {
error = getpwnam_r(lname, &pwd, buf, size, &pw);
if (buf != bufs)
free(buf);
if (pw != NULL) {
*uidp = pw->pw_uid;
return (GSS_S_COMPLETE);
} else if (error != ERANGE || size > SIZE_MAX - PWBUF_SIZE_INC)
return (GSS_S_FAILURE);
if (size != sizehint)
size = sizehint;
else
size += PWBUF_SIZE_INC;
buf = malloc(size);
if (buf == NULL)
return (GSS_S_FAILURE);
sizehint = size;
}
}

int
main(void)
{
const char *str[] = { "man", "root", "q", "bin", NULL };
uid_t uid;
u_int i;

for (i = 0; str[i] != NULL; ++i) {
printf("%-20s\t", str[i]);
if (getpwnam_r_func(str[i], &uid) == GSS_S_COMPLETE)
printf("%u\n", uid);
else
printf("not found\n");
}
return (0);
}
-
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-curren

Re: Possible bug in NFSv4 with krb5p security?

2013-02-19 Thread Rick Macklem
Andrey Simonenko wrote:
> On Tue, Feb 19, 2013 at 05:35:50PM +0800, Elias Martenson wrote:
> > On 19 February 2013 17:31, Andrey Simonenko
> > wrote:
> >
> > It can require bigger buffer, since root can get the pw_password
> > field
> > > in the struct passwd{}.
> > >
> > > Since sysconf(_SC_GETPW_R_SIZE_MAX) does not work on FreeBSD, the
> > > buffer
> > > for getpwnam_r() call should have at least (2 * MAXLOGNAME + 2 *
> > > MAXPATHLEN +
> > > _PASSWORD_LEN + 1) bytes (it is unclear how much is required for
> > > pw_gecos).
> > >
> > > This buffer can be dynamically reallocated until getpwnam_r() is
> > > not
> > > return ERANGE error (the following code has not been compiled and
> > > verified):
> > >
> >
> > Is this really a better solution than to aim high right away? A
> > series of
> > malloc() calls should certainly have much higher overhead than the
> > previous
> > stack-allocated solution.
> >
> > A better compromise would be to do the lookup in a separate
> > function, that
> > allocates the buffer using alloca() instead, yes?
> 
> I cannot find how to get information about maximum buffer size for
> the getpwnam_r() function. This information should be returned by
> sysconf(_SC_GETPW_R_SIZE_MAX), but since it does not work on FreeBSD
> it is necessary to guess its size. Original value is 128 and it works
> for somebody, 1024 works for your environment, but it can fail for
> another environment.
> 
> SUSv4 specifies "Storage referenced by the structure is allocated from
> the memory provided with the buffer parameter", but then tells about
> groups
> in EXAMPLE for getpwnam_r() "Note that sysconf(_SC_GETPW_R_SIZE_MAX)
> may
> return -1 if there is no hard limit on the size of the buffer needed
> to
> store all the groups returned".
> 
> malloc() can give overhead, but that function can try to call
> getpwnam_r()
> with buffer allocated from stack and if getpwnam_r() failed with
> ERANGE
> use dynamically allocated buffer.
> 
> #define PWBUF_SIZE_INI (2 * MAXLOGNAME + 2 * MAXPATHLEN +
> _PASSWORD_LEN + 1)
> #define PWBUF_SIZE_INC 128
> 
> char bufs[2 * MAXLOGNAME + MAXPATHLEN + PASSWORD_LEN + 1 + 32];
> 
> error = getpwnam_r(lname, &pwd, bufs, sizeof(bufs), &pw);
> if (pw != NULL) {
> *uidp = pw->pw_uid;
> return (GSS_S_COMPLETE);
> } else if (error != ERANGE)
> return (GSS_S_FAILURE);
> 
> size = PWBUF_SIZE_INI;
> for (;;) {
> size += PWBUF_SIZE_INC;
> buf = malloc(size);
> if (buf == NULL)
> return (GSS_S_FAILURE);
> error = getpwnam_r(lname, &pwd, buf, size, &pw);
> free(buf);
> if (pw != NULL) {
> *uidp = pw->pw_uid;
> return (GSS_S_COMPLETE);
> } else {
> if (error == ERANGE &&
> size <= SIZE_MAX - PWBUF_SIZE_INC)
> continue;
> return (GSS_S_FAILURE);
> }
> }

Just my opinion, but I think the above is a good approach.
(ie. First trying a fairly large buffer on the stack that
 will succeed 99.99% of the time, but check for ERANGE and
 loop trying progressively larger malloc'd buffers until
 it stops reporting ERANGE.)

I suspect the overheads behind getpwnam_r() are larger than
the difference between using a buffer on the stack vs malloc,
so I think it should use a fairly large buffer the first time.

Personally, I might have coded it as a single do { } while(),
with the first attempt in it, but that's just personal stylistic
taste. (You can check for buf != bufs before doing a free() of it.)
And, if you wanted to be clever, the code could use a static "bufsiz_hint",
which is set to the largest size needed sofar and that is used as
the initial malloc size. That way it wouldn't loop as much for a
site with huge passwd entries. (An entire bio in the GECOS field or ???)

Btw, the same fix is needed in gssd.c, where it calls
getpwuid_r(). { Interesting that for Elias's case, it
must work for 128, although the getpwnam_r() didn't quite fit
in 128. }

Also, FYI, kuserok.c uses a 2048 byte buffer and doesn't check
for ERANGE.

rick

> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
> "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-19 Thread Andrey Simonenko
On Tue, Feb 19, 2013 at 05:35:50PM +0800, Elias Martenson wrote:
> On 19 February 2013 17:31, Andrey Simonenko 
> wrote:
> 
> It can require bigger buffer, since root can get the pw_password field
> > in the struct passwd{}.
> >
> > Since sysconf(_SC_GETPW_R_SIZE_MAX) does not work on FreeBSD, the buffer
> > for getpwnam_r() call should have at least (2 * MAXLOGNAME + 2 *
> > MAXPATHLEN +
> > _PASSWORD_LEN + 1) bytes (it is unclear how much is required for pw_gecos).
> >
> > This buffer can be dynamically reallocated until getpwnam_r() is not
> > return ERANGE error (the following code has not been compiled and
> > verified):
> >
> 
> Is this really a better solution than to aim high right away? A series of
> malloc() calls should certainly have much higher overhead than the previous
> stack-allocated solution.
> 
> A better compromise would be to do the lookup in a separate function, that
> allocates the buffer using alloca() instead, yes?

I cannot find how to get information about maximum buffer size for
the getpwnam_r() function.  This information should be returned by
sysconf(_SC_GETPW_R_SIZE_MAX), but since it does not work on FreeBSD
it is necessary to guess its size.  Original value is 128 and it works
for somebody, 1024 works for your environment, but it can fail for
another environment.

SUSv4 specifies "Storage referenced by the structure is allocated from
the memory provided with the buffer parameter", but then tells about groups
in EXAMPLE for getpwnam_r() "Note that sysconf(_SC_GETPW_R_SIZE_MAX) may
return -1 if there is no hard limit on the size of the buffer needed to
store all the groups returned".

malloc() can give overhead, but that function can try to call getpwnam_r()
with buffer allocated from stack and if getpwnam_r() failed with ERANGE
use dynamically allocated buffer.

#define PWBUF_SIZE_INI (2 * MAXLOGNAME + 2 * MAXPATHLEN + _PASSWORD_LEN + 1)
#define PWBUF_SIZE_INC 128

char bufs[2 * MAXLOGNAME + MAXPATHLEN + PASSWORD_LEN + 1 + 32];

error = getpwnam_r(lname, &pwd, bufs, sizeof(bufs), &pw);
if (pw != NULL) {
*uidp = pw->pw_uid;
return (GSS_S_COMPLETE);
} else if (error != ERANGE)
return (GSS_S_FAILURE);

size = PWBUF_SIZE_INI;
for (;;) {
size += PWBUF_SIZE_INC;
buf = malloc(size);
if (buf == NULL)
return (GSS_S_FAILURE);
error = getpwnam_r(lname, &pwd, buf, size, &pw);
free(buf);
if (pw != NULL) {
*uidp = pw->pw_uid;
return (GSS_S_COMPLETE);
} else {
if (error == ERANGE &&
size <= SIZE_MAX - PWBUF_SIZE_INC)
continue;
return (GSS_S_FAILURE);
}
}
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-19 Thread Elias Mårtenson
On 19 February 2013 17:31, Andrey Simonenko wrote:

It can require bigger buffer, since root can get the pw_password field
> in the struct passwd{}.
>
> Since sysconf(_SC_GETPW_R_SIZE_MAX) does not work on FreeBSD, the buffer
> for getpwnam_r() call should have at least (2 * MAXLOGNAME + 2 *
> MAXPATHLEN +
> _PASSWORD_LEN + 1) bytes (it is unclear how much is required for pw_gecos).
>
> This buffer can be dynamically reallocated until getpwnam_r() is not
> return ERANGE error (the following code has not been compiled and
> verified):
>

Is this really a better solution than to aim high right away? A series of
malloc() calls should certainly have much higher overhead than the previous
stack-allocated solution.

A better compromise would be to do the lookup in a separate function, that
allocates the buffer using alloca() instead, yes?

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-19 Thread Andrey Simonenko
On Tue, Feb 19, 2013 at 12:06:13AM +0800, Elias Martenson wrote:
> 
> You were right, the problem was in pname_to_uid.c. In it, the following
> code can be found:
> 
> char lname[MAXLOGNAME + 1], buf[1024];
> 
> /* some code snipped for brevity... */
> 
> getpwnam_r(lname, &pwd, buf, sizeof(buf), &pw);
> if (pw) {
> *uidp = pw->pw_uid;
> return (GSS_S_COMPLETE);
> } else {
> return (GSS_S_FAILURE);
> }
> 
> As it turns out, the getpwnam_r() call fails with ERANGE (I had to check
> the return value from getpwnam_r() in order to determine this, as pw is set
> to NULL both if there was an error or if the user name can't be found).
> 
> Now, increasing the size of buf to 1024 solved the problem, and now the
> lookup works correctly.
> 
> I wrote a small test program that issued the same call to getpwnam_r() and
> it worked. Until I su'ed to root, and then it failed.
> 
> It seems as though the buffer needs to be bigger if you're root. I have no
> idea why, but there you have it. Problem solved.

It can require bigger buffer, since root can get the pw_password field
in the struct passwd{}.

Since sysconf(_SC_GETPW_R_SIZE_MAX) does not work on FreeBSD, the buffer
for getpwnam_r() call should have at least (2 * MAXLOGNAME + 2 * MAXPATHLEN +
_PASSWORD_LEN + 1) bytes (it is unclear how much is required for pw_gecos).

This buffer can be dynamically reallocated until getpwnam_r() is not
return ERANGE error (the following code has not been compiled and verified):

#define PWBUF_SIZE_INI (2 * MAXLOGNAME + 2 * MAXPATHLEN + _PASSWORD_LEN + 1)
#define PWBUF_SIZE_INC 128

size = PWBUF_SIZE_INI;
for (;;) {
size += PWBUF_SIZE_INC;
buf = malloc(size);
if (buf == NULL)
return (GSS_S_FAILURE);
error = getpwnam_r(lname, &pwd, buf, size, &pw);
free(buf);
if (pw != NULL) {
*uidp = pw->pw_uid;
return (GSS_S_COMPLETE);
} else {
if (error == ERANGE &&
size <= SIZE_MAX - PWBUF_SIZE_INC)
continue;
return (GSS_S_FAILURE);
}
}
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-18 Thread Rick Macklem
Elias Martenson wrote:
> On 17 February 2013 22:58, Rick Macklem  wrote:
> 
> I think the Makefiles are in the kerberos5 directory.
> >
> > Since the only function you care about is the one in
> > kerberos5/lib/libgssapi_krb5/pname_to_uid.c, I'd
> > just put a copy of that file in usr.sbin/gssd and
> > modify the Makefile there to compile it and link
> > its .o into gssd, avoiding rebuilding any libraries.
> >
> > I'd put a couple of fprintf(stderr, ...) in it and
> > then run "gssd -d" and see what it says.
> >
> > Just how I'd attack it, rick
> 
> 
> Good news! The problem is solved!
> 
> You were right, the problem was in pname_to_uid.c. In it, the
> following
> code can be found:
> 
> char lname[MAXLOGNAME + 1], buf[1024];
> 
> /* some code snipped for brevity... */
> 
> getpwnam_r(lname, &pwd, buf, sizeof(buf), &pw);
> if (pw) {
> *uidp = pw->pw_uid;
> return (GSS_S_COMPLETE);
> } else {
> return (GSS_S_FAILURE);
> }
> 
> As it turns out, the getpwnam_r() call fails with ERANGE (I had to
> check
> the return value from getpwnam_r() in order to determine this, as pw
> is set
> to NULL both if there was an error or if the user name can't be
> found).
> 
> Now, increasing the size of buf to 1024 solved the problem, and now
> the
> lookup works correctly.
> 
> I wrote a small test program that issued the same call to getpwnam_r()
> and
> it worked. Until I su'ed to root, and then it failed.
> 
> It seems as though the buffer needs to be bigger if you're root. I
> have no
> idea why, but there you have it. Problem solved.
> 
> Should this be fixed in the main codebase?
> 
Yes, I would definitely say so.

I won't be able to do a commit until April, but meybe someone else
can do a commit sooner?

> Oh, and thanks so much to all of you for being patient with me while
> solving this. I really appreciate it. Also, I'd like to say that the
> code
> base was quite pleasant to work with. Thanks for that too. :-)
> 
And thanks for working through this, so we now have a fix, rick

> Regards,
> Elias
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
> "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-18 Thread Elias Mårtenson
On 19 February 2013 00:06, Elias Mårtenson  wrote:

char lname[MAXLOGNAME + 1], buf[1024];
>

Oops. Here I am, replying to myself.

The above is a typo. That's by modified code. In the original source, buf
is 128 bytes in size.

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-18 Thread Elias Mårtenson
On 17 February 2013 22:58, Rick Macklem  wrote:

I think the Makefiles are in the kerberos5 directory.
>
> Since the only function you care about is the one in
> kerberos5/lib/libgssapi_krb5/pname_to_uid.c, I'd
> just put a copy of that file in usr.sbin/gssd and
> modify the Makefile there to compile it and link
> its .o into gssd, avoiding rebuilding any libraries.
>
> I'd put a couple of fprintf(stderr, ...) in it and
> then run "gssd -d" and see what it says.
>
> Just how I'd attack it, rick


Good news! The problem is solved!

You were right, the problem was in pname_to_uid.c. In it, the following
code can be found:

char lname[MAXLOGNAME + 1], buf[1024];

/* some code snipped for brevity... */

getpwnam_r(lname, &pwd, buf, sizeof(buf), &pw);
if (pw) {
*uidp = pw->pw_uid;
return (GSS_S_COMPLETE);
} else {
return (GSS_S_FAILURE);
}

As it turns out, the getpwnam_r() call fails with ERANGE (I had to check
the return value from getpwnam_r() in order to determine this, as pw is set
to NULL both if there was an error or if the user name can't be found).

Now, increasing the size of buf to 1024 solved the problem, and now the
lookup works correctly.

I wrote a small test program that issued the same call to getpwnam_r() and
it worked. Until I su'ed to root, and then it failed.

It seems as though the buffer needs to be bigger if you're root. I have no
idea why, but there you have it. Problem solved.

Should this be fixed in the main codebase?

Oh, and thanks so much to all of you for being patient with me while
solving this. I really appreciate it. Also, I'd like to say that the code
base was quite pleasant to work with. Thanks for that too. :-)

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-17 Thread Rick Macklem
Elias Martenson wrote:
> On 17 February 2013 02:17, Doug Rabson  wrote:
> 
> >
> > I think it was Rick that mentioned the patch. I would apply the
> > patch and
> > rebuild your kernel in the interests of changing as little as
> > possible
> > while debugging the original issue.
> >
> 
> Fair enough. I did this. Thanks.
> 
> Now, I'm sorry for asking something that should be obvious, but how
> can I
> rebuild crypto/heimdal?
I think the Makefiles are in the kerberos5 directory.

Since the only function you care about is the one in
kerberos5/lib/libgssapi_krb5/pname_to_uid.c, I'd
just put a copy of that file in usr.sbin/gssd and
modify the Makefile there to compile it and link
its .o into gssd, avoiding rebuilding any libraries.

I'd put a couple of fprintf(stderr, ...) in it and
then run "gssd -d" and see what it says.

Just how I'd attack it, rick

> There is no Makefile in this directory, but
> when I
> did "make world" it did build it. So how does this actually work? Is
> there
> a special Makefile somewhere else that I should use? I need to be able
> to
> rebuild these things withou thaving to do a full "make world", which
> is the
> only way I figured out so far.
> 
> (of course, I could do a automake/configure/make sequence, but it
> seems as
> though the official FreeBSD build doesn't do this (I couldn't find any
> config.log file dropped from the configure script)).
> 
> Regards,
> Elias
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
> "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-17 Thread Elias Mårtenson
On 17 February 2013 02:17, Doug Rabson  wrote:

>
> I think it was Rick that mentioned the patch. I would apply the patch and
> rebuild your kernel in the interests of changing as little as possible
> while debugging the original issue.
>

Fair enough. I did this. Thanks.

Now, I'm sorry for asking something that should be obvious, but how can I
rebuild crypto/heimdal? There is no Makefile in this directory, but when I
did "make world" it did build it. So how does this actually work? Is there
a special Makefile somewhere else that I should use? I need to be able to
rebuild these things withou thaving to do a full "make world", which is the
only way I figured out so far.

(of course, I could do a automake/configure/make sequence, but it seems as
though the official FreeBSD build doesn't do this (I couldn't find any
config.log file dropped from the configure script)).

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Rick Macklem
Doug Rabson wrote:
> On 16 February 2013 13:57, Elias Mårtenson  wrote:
> 
> > On 16 February 2013 18:58, Doug Rabson  wrote:
> >
> >> This may be a stupid question but does the user 'elias' exist in
> >> the
> >> local password database?
> >>
> >> If you are using heimdal from the base distribution and you have
> >> source,
> >> you should be able to build them with debug information which may
> >> help.
> >> When I was writing gssd, I mostly ran it under gdb to debug
> >> problems like
> >> this. To build something in the base with debug information, go to
> >> the
> >> directory in the source tree for that component and type something
> >> like
> >> 'make DEBUG_FLAGS=-g clean all install'.
> >>
> >
> > No worries. I do have that user (and everything else, specifically
> > single
> > sign-on ssh) works with it. I do agree that if I had not that user,
> > the
> > behaviour I see would be neatly explained.
> >
> > When it comes to gssd, I've got its behaviour pretty well nailed
> > down. It
> > does what it's supposed to do.
> >
> > However, when I tried rebuilding libgssapi.so.10, I ended up with
> > gssd
> > hanging when it used the new library. I have no idea why.
> >
> > Would it be wise to upgrade from 9.1-RELEASE to something newer?
> > I've seen
> > references to 10-CURRENT. I'd like to be debugging the latest
> > version of
> > everything, but this machine also needs to serve as a fileserver for
> > my
> > home office, so some degree of stability is needed.
> >
> >
> I don't think much (if anything) has changed with gssd between 9.1 and
> current.
Nothing that would affect this, as far as I know. The changes were done
to add support for searching for credential cache files with different
names. This should affect client side behaviour only and only if the
new command line options are used to enable this code.

> When your gssd hangs, you can try to get a stack trace using
> gdb's
> attach command.
> 
> 
> 
> > Regards,
> > Elias
> >
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
> "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Doug Rabson
On 16 February 2013 16:18, Elias Mårtenson  wrote:

> On 17 February 2013 00:03, Doug Rabson  wrote:
>
>> I don't think much (if anything) has changed with gssd between 9.1 and
>> current. When your gssd hangs, you can try to get a stack trace using gdb's
>> attach command.
>>
>> Fair enough. However, when it hangs, I have at least a 50% chance of
> hitting the gssd-realted kerberl panic. Should I apply the patch you gave
> me, or would you suggest an upgrade?
>

I think it was Rick that mentioned the patch. I would apply the patch and
rebuild your kernel in the interests of changing as little as possible
while debugging the original issue.
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Elias Mårtenson
On 17 February 2013 00:03, Doug Rabson  wrote:

> I don't think much (if anything) has changed with gssd between 9.1 and
> current. When your gssd hangs, you can try to get a stack trace using gdb's
> attach command.
>
> Fair enough. However, when it hangs, I have at least a 50% chance of
hitting the gssd-realted kerberl panic. Should I apply the patch you gave
me, or would you suggest an upgrade?
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Doug Rabson
On 16 February 2013 13:57, Elias Mårtenson  wrote:

> On 16 February 2013 18:58, Doug Rabson  wrote:
>
>> This may be a stupid question but does the user 'elias' exist in the
>> local password database?
>>
>> If you are using heimdal from the base distribution and you have source,
>> you should be able to build them with debug information which may help.
>> When I was writing gssd, I mostly ran it under gdb to debug problems like
>> this. To build something in the base with debug information, go to the
>> directory in the source tree for that component and type something like
>> 'make DEBUG_FLAGS=-g clean all install'.
>>
>
> No worries. I do have that user (and everything else, specifically single
> sign-on ssh) works with it. I do agree that if I had not that user, the
> behaviour I see would be neatly explained.
>
> When it comes to gssd, I've got its behaviour pretty well nailed down. It
> does what it's supposed to do.
>
> However, when I tried rebuilding libgssapi.so.10, I ended up with gssd
> hanging when it used the new library. I have no idea why.
>
> Would it be wise to upgrade from 9.1-RELEASE to something newer? I've seen
> references to 10-CURRENT. I'd like to be debugging the latest version of
> everything, but this machine also needs to serve as a fileserver for my
> home office, so some degree of stability is needed.
>
>
I don't think much (if anything) has changed with gssd between 9.1 and
current. When your gssd hangs, you can try to get a stack trace using gdb's
attach command.



> Regards,
> Elias
>
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Elias Mårtenson
On 16 February 2013 18:58, Doug Rabson  wrote:

> This may be a stupid question but does the user 'elias' exist in the local
> password database?
>
> If you are using heimdal from the base distribution and you have source,
> you should be able to build them with debug information which may help.
> When I was writing gssd, I mostly ran it under gdb to debug problems like
> this. To build something in the base with debug information, go to the
> directory in the source tree for that component and type something like
> 'make DEBUG_FLAGS=-g clean all install'.
>

No worries. I do have that user (and everything else, specifically single
sign-on ssh) works with it. I do agree that if I had not that user, the
behaviour I see would be neatly explained.

When it comes to gssd, I've got its behaviour pretty well nailed down. It
does what it's supposed to do.

However, when I tried rebuilding libgssapi.so.10, I ended up with gssd
hanging when it used the new library. I have no idea why.

Would it be wise to upgrade from 9.1-RELEASE to something newer? I've seen
references to 10-CURRENT. I'd like to be debugging the latest version of
everything, but this machine also needs to serve as a fileserver for my
home office, so some degree of stability is needed.

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Doug Rabson
This may be a stupid question but does the user 'elias' exist in the local
password database?

If you are using heimdal from the base distribution and you have source,
you should be able to build them with debug information which may help.
When I was writing gssd, I mostly ran it under gdb to debug problems like
this. To build something in the base with debug information, go to the
directory in the source tree for that component and type something like
'make DEBUG_FLAGS=-g clean all install'.


On 16 February 2013 09:24, Elias Mårtenson  wrote:

> OK, here I am replying to my own email. I just want to mention that I
> removed the ports version of Heimdal, but with no change in behaviour.
>
>
> On 16 February 2013 09:38, Elias Mårtenson  wrote:
>
> >
> > On 16 Feb, 2013 1:42 AM, "Benjamin Kaduk"  wrote:
> > >
> > >> And yet one more thing: Heimdal ships with its own version of
> > libgssapi. I
> > >> can link gssd to it, but it won't run properly (it hangs pretty
> early).
> > >
> > > I have forgotten: you are using Heimdal from ports, not from the base
> > system?  I remember it being easy to get into subtly-broken
> configurations
> > when both a ports and a base version are present.
> >
> > I am indeed using Heimdal from ports. This machine is also the KDC. I
> > wasn't aware that there was a non-ports version available.
> >
> > What do you suggest I do? Simply remove the one from ports? Do I have to
> > do something to activate the other one?
> >
> > (I have a hard time checking this as I am nowhere near the computers now)
> >
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
>
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-16 Thread Elias Mårtenson
OK, here I am replying to my own email. I just want to mention that I
removed the ports version of Heimdal, but with no change in behaviour.


On 16 February 2013 09:38, Elias Mårtenson  wrote:

>
> On 16 Feb, 2013 1:42 AM, "Benjamin Kaduk"  wrote:
> >
> >> And yet one more thing: Heimdal ships with its own version of
> libgssapi. I
> >> can link gssd to it, but it won't run properly (it hangs pretty early).
> >
> > I have forgotten: you are using Heimdal from ports, not from the base
> system?  I remember it being easy to get into subtly-broken configurations
> when both a ports and a base version are present.
>
> I am indeed using Heimdal from ports. This machine is also the KDC. I
> wasn't aware that there was a non-ports version available.
>
> What do you suggest I do? Simply remove the one from ports? Do I have to
> do something to activate the other one?
>
> (I have a hard time checking this as I am nowhere near the computers now)
>
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-15 Thread Elias Mårtenson
On 16 Feb, 2013 1:42 AM, "Benjamin Kaduk"  wrote:
>
>> And yet one more thing: Heimdal ships with its own version of libgssapi.
I
>> can link gssd to it, but it won't run properly (it hangs pretty early).
>
> I have forgotten: you are using Heimdal from ports, not from the base
system?  I remember it being easy to get into subtly-broken configurations
when both a ports and a base version are present.

I am indeed using Heimdal from ports. This machine is also the KDC. I
wasn't aware that there was a non-ports version available.

What do you suggest I do? Simply remove the one from ports? Do I have to do
something to activate the other one?

(I have a hard time checking this as I am nowhere near the computers now)
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-15 Thread Elias Mårtenson
On 16 Feb, 2013 8:57 AM, "Rick Macklem"  wrote:
>
> Benjamin Kaduk wrote:
> > On Sat, 16 Feb 2013, Elias Mårtenson wrote:
> >
> > >
> > > Thank you. I did exactly that and I found out some more.
> > >
> > > The problem occurss in file gss.c, in the
> > > function gssd_pname_to_uid_1_svc(). This function is responsible for
> > > taking
> > > a principal and returning the Unix user ID that this principal
> > > corresponds
> > > to. I did confirm that this function is called with elias@REALM,
> > > which is
> > > the correct principal. It then calls the libgssapi function
> > > gss_pname_to_uid() which does the actual lookup.
> > >
> > > The problem is that after the lookup (which succeeds by the way), it
> > > returns user ID 0 (i.e. root, what!?). Of course, this uid later
> > > gets
> > > mapped to nobody, resulting in the behaviour that I see.
> > >
> > > I tried to add more debugging information in libgssapi.so.10, but if
> > > I just
> > > try to add some printf() statements, the entire thing hangs. I'm not
> > > sure
> > > how to proceed from there.
> > >
> > > Oh, and the libgssapi function gss_pname_to_uid() actually delegates
> > > the
> > > actual lookup to a function that depends on what security mechanism
> > > is in
> > > place. My printf()'s (that caused the hang) attempted to print what
> > > mechanism was actually used.
> >
> > Unless things are very messed up, it should be using the krb5
> > mechanism,
> > which I believe will boil down to krb5_aname_to_localname, per
> > heimdal/lib/gssapi/krb5/pname_to_uid.c. I'm not sure how this would
> > end
> > up with success but uid 0, though.
> > Do you have the default realm set in krb5.conf? Having it set to a
> > different value than the realm of elias@REALM could result in strange
> > behavior.
> >
> > > And yet one more thing: Heimdal ships with its own version of
> > > libgssapi. I
> > > can link gssd to it, but it won't run properly (it hangs pretty
> > > early).
> >
> > I have forgotten: you are using Heimdal from ports, not from the base
> > system? I remember it being easy to get into subtly-broken
> > configurations
> > when both a ports and a base version are present.
> >
> > -Ben Kaduk
> Well, here's the aname_to_localname function sources. After this, it just
> calls getpwnam_r() to get the password database entry for the name.
> I've put "***" in front of what I suspect is causing your problem.
> I have no idea when there is a name_string.len == 2 with "root" as the
> second string. Maybe Benjamin knows?
>
> krb5_error_code KRB5_LIB_FUNCTION
> krb5_aname_to_localname (krb5_context context,
>  krb5_const_principal aname,
>  size_t lnsize,
>  char *lname)
> {
> krb5_error_code ret;
> krb5_realm *lrealms, *r;
> int valid;
> size_t len;
> const char *res;
>
> ret = krb5_get_default_realms (context, &lrealms);
> if (ret)
> return ret;
>
> valid = 0;
> for (r = lrealms; *r != NULL; ++r) {
> if (strcmp (*r, aname->realm) == 0) {
> valid = 1;
> break;
> }
> }
> krb5_free_host_realm (context, lrealms);
> if (valid == 0)
> return KRB5_NO_LOCALNAME;
>
> if (aname->name.name_string.len == 1)
> res = aname->name.name_string.val[0];
> *** else if (aname->name.name_string.len == 2
>  && strcmp (aname->name.name_string.val[1], "root") == 0) {
> krb5_principal rootprinc;
> krb5_boolean userok;
>
> res = "root";
>
> ret = krb5_copy_principal(context, aname, &rootprinc);
> if (ret)
> return ret;
>
> userok = krb5_kuserok(context, rootprinc, res);
> krb5_free_principal(context, rootprinc);
> if (!userok)
> return KRB5_NO_LOCALNAME;
>
> } else
> return KRB5_NO_LOCALNAME;
>
> len = strlen (res);
> if (len >= lnsize)
> return ERANGE;
> strlcpy (lname, res, lnsize);
>
> return 0;
> }
>
> I've never seen Kerberos map to "root" like the above would for
> name.name_string.len == 2, but I'm guessing that's how you get
> uid == 0.

Sorry for bad formatting, I'm typing this on my phone.

Wouldn't the case you quoted cover the case where you gave a principal name
like foo/root which would be mapped to root?

I've never seen such principals, but it makes sense based on what I see in
the code.

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-15 Thread Rick Macklem
Benjamin Kaduk wrote:
> On Sat, 16 Feb 2013, Elias Mårtenson wrote:
> 
> >
> > Thank you. I did exactly that and I found out some more.
> >
> > The problem occurss in file gss.c, in the
> > function gssd_pname_to_uid_1_svc(). This function is responsible for
> > taking
> > a principal and returning the Unix user ID that this principal
> > corresponds
> > to. I did confirm that this function is called with elias@REALM,
> > which is
> > the correct principal. It then calls the libgssapi function
> > gss_pname_to_uid() which does the actual lookup.
> >
> > The problem is that after the lookup (which succeeds by the way), it
> > returns user ID 0 (i.e. root, what!?). Of course, this uid later
> > gets
> > mapped to nobody, resulting in the behaviour that I see.
> >
> > I tried to add more debugging information in libgssapi.so.10, but if
> > I just
> > try to add some printf() statements, the entire thing hangs. I'm not
> > sure
> > how to proceed from there.
> >
> > Oh, and the libgssapi function gss_pname_to_uid() actually delegates
> > the
> > actual lookup to a function that depends on what security mechanism
> > is in
> > place. My printf()'s (that caused the hang) attempted to print what
> > mechanism was actually used.
> 
> Unless things are very messed up, it should be using the krb5
> mechanism,
> which I believe will boil down to krb5_aname_to_localname, per
> heimdal/lib/gssapi/krb5/pname_to_uid.c. I'm not sure how this would
> end
> up with success but uid 0, though.
> Do you have the default realm set in krb5.conf? Having it set to a
> different value than the realm of elias@REALM could result in strange
> behavior.
> 
> > And yet one more thing: Heimdal ships with its own version of
> > libgssapi. I
> > can link gssd to it, but it won't run properly (it hangs pretty
> > early).
> 
> I have forgotten: you are using Heimdal from ports, not from the base
> system? I remember it being easy to get into subtly-broken
> configurations
> when both a ports and a base version are present.
> 
> -Ben Kaduk
Well, here's the aname_to_localname function sources. After this, it just
calls getpwnam_r() to get the password database entry for the name.
I've put "***" in front of what I suspect is causing your problem.
I have no idea when there is a name_string.len == 2 with "root" as the
second string. Maybe Benjamin knows?

krb5_error_code KRB5_LIB_FUNCTION
krb5_aname_to_localname (krb5_context context,
 krb5_const_principal aname,
 size_t lnsize,
 char *lname)
{
krb5_error_code ret;
krb5_realm *lrealms, *r;
int valid;
size_t len;
const char *res;

ret = krb5_get_default_realms (context, &lrealms);
if (ret)
return ret;

valid = 0;
for (r = lrealms; *r != NULL; ++r) {
if (strcmp (*r, aname->realm) == 0) {
valid = 1;
break;
}
}
krb5_free_host_realm (context, lrealms);
if (valid == 0)
return KRB5_NO_LOCALNAME;

if (aname->name.name_string.len == 1)
res = aname->name.name_string.val[0];
*** else if (aname->name.name_string.len == 2
 && strcmp (aname->name.name_string.val[1], "root") == 0) {
krb5_principal rootprinc;
krb5_boolean userok;

res = "root";

ret = krb5_copy_principal(context, aname, &rootprinc);
if (ret)
return ret;

userok = krb5_kuserok(context, rootprinc, res);
krb5_free_principal(context, rootprinc);
if (!userok)
return KRB5_NO_LOCALNAME;

} else
return KRB5_NO_LOCALNAME;

len = strlen (res);
if (len >= lnsize)
return ERANGE;
strlcpy (lname, res, lnsize);

return 0;
}

I've never seen Kerberos map to "root" like the above would for
name.name_string.len == 2, but I'm guessing that's how you get
uid == 0.

rick
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Re: Possible bug in NFSv4 with krb5p security?

2013-02-15 Thread Benjamin Kaduk

On Sat, 16 Feb 2013, Elias Mårtenson wrote:



Thank you. I did exactly that and I found out some more.

The problem occurss in file gss.c, in the
function gssd_pname_to_uid_1_svc(). This function is responsible for taking
a principal and returning the Unix user ID that this principal corresponds
to. I did confirm that this function is called with elias@REALM, which is
the correct principal. It then calls the libgssapi function
gss_pname_to_uid() which does the actual lookup.

The problem is that after the lookup (which succeeds by the way), it
returns user ID 0 (i.e. root, what!?). Of course, this uid later gets
mapped to nobody, resulting in the behaviour that I see.

I tried to add more debugging information in libgssapi.so.10, but if I just
try to add some printf() statements, the entire thing hangs. I'm not sure
how to proceed from there.

Oh, and the libgssapi function gss_pname_to_uid() actually delegates the
actual lookup to a function that depends on what security mechanism is in
place. My printf()'s (that caused the hang) attempted to print what
mechanism was actually used.


Unless things are very messed up, it should be using the krb5 mechanism, 
which I believe will boil down to krb5_aname_to_localname, per 
heimdal/lib/gssapi/krb5/pname_to_uid.c.  I'm not sure how this would end 
up with success but uid 0, though.
Do you have the default realm set in krb5.conf?  Having it set to a 
different value than the realm of elias@REALM could result in strange 
behavior.



And yet one more thing: Heimdal ships with its own version of libgssapi. I
can link gssd to it, but it won't run properly (it hangs pretty early).


I have forgotten: you are using Heimdal from ports, not from the base 
system?  I remember it being easy to get into subtly-broken configurations 
when both a ports and a base version are present.


-Ben Kaduk___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Re: Possible bug in NFSv4 with krb5p security?

2013-02-15 Thread Elias Mårtenson
On 14 February 2013 07:42, Rick Macklem  wrote:

Elias Martenson wrote:> Secondly, what if the issue is gssd not correctly
> mapping the
> > principals to
> > Unix usernames? How can I determine if this is the case. There seems
> > to be
> > no logging options for gssd (-d does absolutely nothing other than
> > prevent
> > the process from detaching. It still doesn't log anything).
> >
> Yep. I added a few cases that output debugging, but they're all on the
> client side. (I wasn't the original author of this gssd.)
>
> You could easily add some. It's the function with pname_to_uid in it
> that does the translation. It basically does a gss_pname_to_uid()
> followed by a getpwuid() to do the translation from principal name
> to uid + gid list. If this fails, then it maps uid == 65534, which
> is usually "nobody". (Why does the code has 65534 hardwired in it?
> I have no idea.;-)
>
> Just add fprintf()s and run it with "-d" to see what it is doing.
>
> If the initiator principal is "nfs/client-host.domain" it will get
> mapped to "nobody" as above.


Thank you. I did exactly that and I found out some more.

The problem occurss in file gss.c, in the
function gssd_pname_to_uid_1_svc(). This function is responsible for taking
a principal and returning the Unix user ID that this principal corresponds
to. I did confirm that this function is called with elias@REALM, which is
the correct principal. It then calls the libgssapi function
gss_pname_to_uid() which does the actual lookup.

The problem is that after the lookup (which succeeds by the way), it
returns user ID 0 (i.e. root, what!?). Of course, this uid later gets
mapped to nobody, resulting in the behaviour that I see.

I tried to add more debugging information in libgssapi.so.10, but if I just
try to add some printf() statements, the entire thing hangs. I'm not sure
how to proceed from there.

Oh, and the libgssapi function gss_pname_to_uid() actually delegates the
actual lookup to a function that depends on what security mechanism is in
place. My printf()'s (that caused the hang) attempted to print what
mechanism was actually used.

And yet one more thing: Heimdal ships with its own version of libgssapi. I
can link gssd to it, but it won't run properly (it hangs pretty early).

Does anyone have any idea what might be going on here?

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-14 Thread Rick Macklem
Elias Martenson wrote:
> Thank you for your help. I'm currently in the process of analysing
> what is happening inside gssd during these operations. I'll get back
> later with a summary of my findings.
> 
> 
> However, I have found a real bug this time. An honest to FSM kernel
> crash. This is how I reproduced it:
> 
> 
> - Kill gssd
> - Attempt to mount a kerberised NFS mount from the Linux machine
> - The mount attempt will hang because gssd isn't running
> - While the mount is hung, start gssd
> - Kernel crash
> 
> 
> What should I do about that one?
> 
There was a patch applied to head about 2 months ago (r244370) to
stop crashes when the gssd was restarted. The patch is also here:
 http://people.freebsd.org/~rmacklem/kgssapi.patch

I don't remember if you mentioned which kernel version you are
running, but this would also be in stable/9 of about 6 weeks ago,
but not in 9.1-release.

If your system has this patch and still crashes, please email
the backtrace for the crash. You can take a photo of it, if it
is a screen console.

rick

> 
> Regards,
> Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-14 Thread Elias Mårtenson
Thank you for your help. I'm currently in the process of analysing what is
happening inside gssd during these operations. I'll get back later with a
summary of my findings.

However, I have found a real bug this time. An honest to FSM kernel crash.
This is how I reproduced it:

  - Kill gssd
  - Attempt to mount a kerberised NFS mount from the Linux machine
  - The mount attempt will hang because gssd isn't running
  - While the mount is hung, start gssd
  - Kernel crash

What should I do about that one?

Regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: Possible bug in NFSv4 with krb5p security?

2013-02-13 Thread Rick Macklem
Elias Martenson wrote:
> Thanks for the information. I was looking a bit further into the
> tcpdump
> log, and this is what happens:
> 
> Here are some relevant packets:
> 
>  115 
> NULL call establishing a mutual context(?)
> GSS-API:
> Kerberos AP-REQ:
> Ticket: Server Name (Principal): nfs/domainname
>  117 
> NULL reply to packet 115
>  169 
> NFSV4 Call. OPEN DH:.../foo.txt
> Credentials:
> Procedure: RPCSEC_GSS_DATA
> GSS Context: (reference to the context created in the request from
> frame 115)
> Verifier:
> GSS Token: (some long sequence of binary data)
> GSS-API: krb5_blob (more binary data)
>  170 
> NFSV4 Reply
> OPEN Status: NFS4ERR_ACCESS
> =
> 
> The weird thing here is that the OPEN request in packet 169 refers to
> a
> context that was created for the principal name "nfs/domainname" (i.e.
> the
> service principal).
Normally the client will get a service ticket for "nfs/server-host.domain" using
initiator credentials that are either "user" (via their TGT) or
"nfs/client-host.domain" via its keytab entry. The important part is what the
initiator principal is. (Watching what gets logged in your KDC's log as you
do the mount and access attempt might answer this if the wireshark trace 
doesn't.)

> Am I correct in my understanding that this context
> is
> different from the user principal that is accessing the data?
Ok, it sounds like the Linux client might be using a "host based initiator 
credential"
for this request, but I'm not sure. (This is the credential where the
initiator principal was "nfs/client-host.domain".)

Most NFSv4 clients use a "host based initiator credential" in a keytab file
for system operations. (The FreeBSD client can only do this if it is patched.)
(By system operations, I am referring to NFSv4 Operations that are related to
 maintenance of lock state: SetClientID, SetClientIDConfirm, Renew, 
ReleaseLockOwner
 and maybe a couple of others.)
This is done so that the mount doesn't break when a user's TGT expires and also
because few Kerberos setups have a user principal for root and root is usually
doing the mounts.

Now, what I think the client should be doing is a separate Null RPC sequence
for each user (like "elias") when that user first attempts to access files
within the mount. The user must have a valid TGT at this point for it to work.
Then it should use the credential handle acquired from that exchange for file
accesses (including Opens) for that user.

If wireshark understands the RPCSEC_GSS authenticator, try and look for the
credential handle field and also look for a separate Null RPC sequence for
user principal "elias" or whoever you are logged in as when trying to open
the file.

If you are correct and the Linux client is using the credential handle it
acquired for nfs/client-host.domain, then the FreeBSD gssd would map that to
"nobody" and it would explain what your problem is. I would consider that
a Linux client bug. Linux clients have been successfully tested against
the FreeBSD server (did not do the above) in the past, but things change/break.

> And if
> so,
> where is the details regarding that principal? Is it in the "verifier"
> part
> in packet 169?
> 
There is a credential handle (I might not have the correct name since I
haven't looked at the RFC in years) which identifies which principal it
is referred to. (The same credential handle is in the reply to the Null RPC
for the RPCSEC_GSS init.) So you need to find the Null RPC sequence that
creates the particular credential handle (just bits that are the same) used
in the RPCSEC_GSS data authenticator. The principal is in the ticket inside
the GSSAPI token in the Null RPC data.

> Secondly, what if the issue is gssd not correctly mapping the
> principals to
> Unix usernames? How can I determine if this is the case. There seems
> to be
> no logging options for gssd (-d does absolutely nothing other than
> prevent
> the process from detaching. It still doesn't log anything).
> 
Yep. I added a few cases that output debugging, but they're all on the
client side. (I wasn't the original author of this gssd.)

You could easily add some. It's the function with pname_to_uid in it
that does the translation. It basically does a gss_pname_to_uid()
followed by a getpwuid() to do the translation from principal name
to uid + gid list. If this fails, then it maps uid == 65534, which
is usually "nobody". (Why does the code has 65534 hardwired in it?
I have no idea.;-)

Just add fprintf()s and run it with "-d" to see what it is doing.

If the initiator principal is "nfs/client-host.domain" it will get
mapped to "nobody" as above.

Good luck with it, rick

> Regards,
> Elias
> 
> On 13 February 2013 06:47, Rick Macklem  wrote:
> 
> > Elias Martenson wrote:
> > > On 12 February 2013 23:20, Rick Macklem < rmack...@uoguelph.ca >
> > > wrote:
> > >
> > >
> > >
> > >
> > >
> > >
> > > There is (in case you missed it on google):
> > > http://code.google.com/p/macnfsv4/wiki/FreeBS

Re: Possible bug in NFSv4 with krb5p security?

2013-02-13 Thread Elias Mårtenson
Thanks for the information. I was looking a bit further into the tcpdump
log, and this is what happens:

Here are some relevant packets:

 115 
NULL call establishing a mutual context(?)
  GSS-API:
Kerberos AP-REQ:
  Ticket: Server Name (Principal): nfs/domainname
 117 
NULL reply to packet 115
 169 
NFSV4 Call. OPEN DH:.../foo.txt
  Credentials:
Procedure: RPCSEC_GSS_DATA
GSS Context: (reference to the context created in the request from
frame 115)
  Verifier:
GSS Token: (some long sequence of binary data)
GSS-API: krb5_blob (more binary data)
 170 
NFSV4 Reply
  OPEN Status: NFS4ERR_ACCESS
=

The weird thing here is that the OPEN request in packet 169 refers to a
context that was created for the principal name "nfs/domainname" (i.e. the
service principal). Am I correct in my understanding that this context is
different from the user principal that is accessing the data? And if so,
where is the details regarding that principal? Is it in the "verifier" part
in packet 169?

Secondly, what if the issue is gssd not correctly mapping the principals to
Unix usernames? How can I determine if this is the case. There seems to be
no logging options for gssd (-d does absolutely nothing other than prevent
the process from detaching. It still doesn't log anything).

Regards,
Elias

On 13 February 2013 06:47, Rick Macklem  wrote:

> Elias Martenson wrote:
> > On 12 February 2013 23:20, Rick Macklem < rmack...@uoguelph.ca >
> > wrote:
> >
> >
> >
> >
> >
> >
> > There is (in case you missed it on google):
> > http://code.google.com/p/macnfsv4/wiki/FreeBSD8KerberizedNFSSetup
> > (Nothing much has changed since FreeBSD8, except the name of the
> > client
> > side patch for host based initiator credentials in the keytab file.)
> > I was hoping others would add/update the wiki and it would eventually
> > become FreeBSD doc, but that hasn't happened.
> >
> >
> >
> >
> > Thank you for the link. I have indeed found that, and I have followed
> > it to the letter.
> >
> >
> > I have up the exact same thing from Ubuntu machines as well as from
> > Solaris, and I do have a fairly good understanding of Kerberos.
> > FreeBSD however, is pretty new to me.
> >
> >
> > Other than that, the various discussions in the archive on this list
> > may help. Unfortunately, I don't know of an easy way to figure out
> > what is busted. I always suggest looking at the packets in wireshark,
> > but for some reason, I get the impression that folk don't like
> > doing this? It is what I do first when I run into NFS issues.
> >
> >
> >
> > I've been looking at the dumps using Wireshark. Well, I had to drop
> > down the security since everything is encrypted when using keb5p. I do
> > get the same errors using sec=krb5.
> >
> >
> > When looking at this trace, I see a normal OPEN request followed by a
> > NFS4ERR_ACCESS as a reply. The Kerberos credentials are of course
> > encrypted, so I can't really say anything about that part.
> >
> Well, it sounds like you are doing all the right stuff, so I don't know
> why it is returning EACCES?
>
> I'm not a ZFS person, so I never test that. If you have a UFS file system
> you could export for testing, that might be worth a try. ZFS likes to do
> things differently;-)
>
> You can look at the authentication stuff in the RPC header:
> Actually, the credentials in the RPC header aren't encrypted, although
> they are binary data. It's been a while since I looked at the RFC, but
> the authenticator is basically:
> - an RPCSEC_GSS version (must be 1 for FreeBSD to be able to use it)
> - a type that will be DATA in this case
> - a credential handle (just a blob of bits the server uses as a shorthand
> for the principal)
> - a sequence# used to subvert replay attempts
>
> Then the authentication verifier is an encrypted checksum of the above,
> that the server uses to verify it.
>
> All the Kerberos stuff happens via NFS Null RPCs, where the GSSAPI tokens
> are passed as data (a Null RPC has no arguments) and the credential handle
> and a session key get established. (The Kerberos ticket is inside the
> GSSAPI
> token for the first of these Null RPCs.)
>
> >
> > Note that NFS4 with Kerberos security never uses the user ID numbers.
> > They purely use the Kerberos principals for authorisation. This is
> > different from the default "sys" security model that blindly uses user
> > ID's.
> >
> Yep, of course. The Kerberos user principal "name@REALM" is translated
> to a uid + gid list by the gssd via a lookup of "name" as the username.
> The uid + gid list is then associated with that credential handle I
> mentioned
> above.
>
> >
> >
> >
> > > nfscbd_enable="YES"
> > Needed for client side only, and only if delegations are
> > enabled at the server and you want the client to acquire
> > delegations. (Delegations are not enabled by default on the
> > FreeBSD NFSv4 server.)
> >
> >
> >
> > Noted. Thank you. I will change this.
> >
> >
> >
> > > rpc_lockd_

Re: Possible bug in NFSv4 with krb5p security?

2013-02-12 Thread Rick Macklem
Elias Martenson wrote:
> On 12 February 2013 23:20, Rick Macklem < rmack...@uoguelph.ca >
> wrote:
> 
> 
> 
> 
> 
> 
> There is (in case you missed it on google):
> http://code.google.com/p/macnfsv4/wiki/FreeBSD8KerberizedNFSSetup
> (Nothing much has changed since FreeBSD8, except the name of the
> client
> side patch for host based initiator credentials in the keytab file.)
> I was hoping others would add/update the wiki and it would eventually
> become FreeBSD doc, but that hasn't happened.
> 
> 
> 
> 
> Thank you for the link. I have indeed found that, and I have followed
> it to the letter.
> 
> 
> I have up the exact same thing from Ubuntu machines as well as from
> Solaris, and I do have a fairly good understanding of Kerberos.
> FreeBSD however, is pretty new to me.
> 
> 
> Other than that, the various discussions in the archive on this list
> may help. Unfortunately, I don't know of an easy way to figure out
> what is busted. I always suggest looking at the packets in wireshark,
> but for some reason, I get the impression that folk don't like
> doing this? It is what I do first when I run into NFS issues.
> 
> 
> 
> I've been looking at the dumps using Wireshark. Well, I had to drop
> down the security since everything is encrypted when using keb5p. I do
> get the same errors using sec=krb5.
> 
> 
> When looking at this trace, I see a normal OPEN request followed by a
> NFS4ERR_ACCESS as a reply. The Kerberos credentials are of course
> encrypted, so I can't really say anything about that part.
> 
Well, it sounds like you are doing all the right stuff, so I don't know
why it is returning EACCES?

I'm not a ZFS person, so I never test that. If you have a UFS file system
you could export for testing, that might be worth a try. ZFS likes to do
things differently;-)

You can look at the authentication stuff in the RPC header:
Actually, the credentials in the RPC header aren't encrypted, although
they are binary data. It's been a while since I looked at the RFC, but
the authenticator is basically:
- an RPCSEC_GSS version (must be 1 for FreeBSD to be able to use it)
- a type that will be DATA in this case
- a credential handle (just a blob of bits the server uses as a shorthand
for the principal)
- a sequence# used to subvert replay attempts

Then the authentication verifier is an encrypted checksum of the above,
that the server uses to verify it.

All the Kerberos stuff happens via NFS Null RPCs, where the GSSAPI tokens
are passed as data (a Null RPC has no arguments) and the credential handle
and a session key get established. (The Kerberos ticket is inside the GSSAPI
token for the first of these Null RPCs.)

> 
> Note that NFS4 with Kerberos security never uses the user ID numbers.
> They purely use the Kerberos principals for authorisation. This is
> different from the default "sys" security model that blindly uses user
> ID's.
> 
Yep, of course. The Kerberos user principal "name@REALM" is translated
to a uid + gid list by the gssd via a lookup of "name" as the username.
The uid + gid list is then associated with that credential handle I mentioned
above.

> 
> 
> 
> > nfscbd_enable="YES"
> Needed for client side only, and only if delegations are
> enabled at the server and you want the client to acquire
> delegations. (Delegations are not enabled by default on the
> FreeBSD NFSv4 server.)
> 
> 
> 
> Noted. Thank you. I will change this.
> 
> 
> 
> > rpc_lockd_enable="YES"
> > rpc_statd_enable="YES"
> You shouldn't need rpc_lockd or rpc_statd for NFSv4,
> since they are only used for NFSv3.
> 
> 
> 
> Good point. I'll disable those too.
> 
> 
> 
> I don't know why a Linux client would mix NFSv3 RPCs with NFSv4 ones,
> 
> 
> I was suggested to set vfs.nfsd.server_min_nfsvers to 4 in order to
> completely disable NFS version below 4. I did this and got rid of the
> stray NFS3 requests. It didn't solve the original problem though.
> 
> 
> 
> > If anyone is able to confirm whether or not this actually has been
> > tested
> > in 9.1-CURRENT, I'd appreciate it. Also, if not, then I'd love to
> > know
> > where I should start looking for a solution. I'm experienced in
> > system
> > level programming (having worked on Solaris at Sun in a previous
> > life), but
> > a pointer where to start would be helpful.
> >
> Usually, when everything is being done by "nobody", it indicates that
> the mapping between  <-> name@domain isn't working
> correctly.
> (Looking at the packets in wireshark, you need to look at the
> attributes
> called Owner and Owner_Group to see what they are being set to.)
> 
> 
> 
> I actually doubt this. First of all, I have the correct idmapd setup
> working from FreeBSD to Ubuntu (I can see that since I can see the
> correct user names in "ls" even though the user ID's differ). On OSX I
> haven't got it to work yet.
> 
> 
> But, the behaviour is the same on both systems.
> 
> 
> This is actually expected, as the permission checks are orthogonal to
> the ID mapping.
> 
> 
> The most com

Re: Possible bug in NFSv4 with krb5p security?

2013-02-12 Thread Elias Mårtenson
On 12 February 2013 23:20, Rick Macklem  wrote:

There is (in case you missed it on google):
> http://code.google.com/p/macnfsv4/wiki/FreeBSD8KerberizedNFSSetup
> (Nothing much has changed since FreeBSD8, except the name of the client
>  side patch for host based initiator credentials in the keytab file.)
> I was hoping others would add/update the wiki and it would eventually
> become FreeBSD doc, but that hasn't happened.
>
>
Thank you for the link. I have indeed found that, and I have followed it to
the letter.

I have up the exact same thing from Ubuntu machines as well as from
Solaris, and I do have a fairly good understanding of Kerberos. FreeBSD
however, is pretty new to me.


> Other than that, the various discussions in the archive on this list
> may help. Unfortunately, I don't know of an easy way to figure out
> what is busted. I always suggest looking at the packets in wireshark,
> but for some reason, I get the impression that folk don't like
> doing this? It is what I do first when I run into NFS issues.
>

I've been looking at the dumps using Wireshark. Well, I had to drop down
the security since everything is encrypted when using keb5p. I do get the
same errors using sec=krb5.

When looking at this trace, I see a normal OPEN request followed by a
NFS4ERR_ACCESS as a reply. The Kerberos credentials are of course
encrypted, so I can't really say anything about that part.

Note that NFS4 with Kerberos security never uses the user ID numbers. They
purely use the Kerberos principals for authorisation. This is different
from the default "sys" security model that blindly uses user ID's.


> > nfscbd_enable="YES"
> Needed for client side only, and only if delegations are
> enabled at the server and you want the client to acquire
> delegations. (Delegations are not enabled by default on the
> FreeBSD NFSv4 server.)
>

Noted. Thank you. I will change this.


> > rpc_lockd_enable="YES"
> > rpc_statd_enable="YES"
> You shouldn't need rpc_lockd or rpc_statd for NFSv4,
> since they are only used for NFSv3.
>

Good point. I'll disable those too.


> I don't know why a Linux client would mix NFSv3 RPCs with NFSv4 ones,
>

I was suggested to set vfs.nfsd.server_min_nfsvers to 4 in order to
completely disable NFS version below 4. I did this and got rid of the stray
NFS3 requests. It didn't solve the original problem though.


> > If anyone is able to confirm whether or not this actually has been
> > tested
> > in 9.1-CURRENT, I'd appreciate it. Also, if not, then I'd love to know
> > where I should start looking for a solution. I'm experienced in system
> > level programming (having worked on Solaris at Sun in a previous
> > life), but
> > a pointer where to start would be helpful.
> >
> Usually, when everything is being done by "nobody", it indicates that
> the mapping between  <-> name@domain isn't working correctly.
> (Looking at the packets in wireshark, you need to look at the attributes
>  called Owner and Owner_Group to see what they are being set to.)
>

I actually doubt this. First of all, I have the correct idmapd setup
working from FreeBSD to Ubuntu (I can see that since I can see the correct
user names in "ls" even though the user ID's differ). On OSX I haven't got
it to work yet.

But, the behaviour is the same on both systems.

This is actually expected, as the permission checks are orthogonal to the
ID mapping.


> The most common problem (since you do have nfsuserd running on the server)
> is for the "domain" spec to be different between client and server.
> FreeBSD's nfsuserd defaults to the domain part of the machine's hostname.
> Linux's rpc.idmapd sets the domain from /etc/idmapd.conf (at least I think
> that's what it is called) and many distros ship with it set to "my.domain"
> or something like that.
>

Correct. I have set this correctly. I know this, since once I did, "ls"
started giving me the correct user names.


> As such, I'd start by checking the Linux client and seeing what it has for
> the domain spec. in /etc/idmapd.conf.
>
> If you want to override the default for FreeBSD, there is a command line
> option for nfsuserd to do this. I can't remember what it is, but "man
> nfsuserd"
> will give you the answer and it can be set in /etc/rc.conf using
> nfsuserd_flags.
>

Thank you. I'm definitely willing to double-check this and I am not going
to claim to know exactly what's going on in the realms of NFS security. :-)


> If this is configured correctly, then looking at the packets in wireshark
> is
> the best starting point w.r.t. figuring out what is broken. I do limited
> testing of this and it works for me. I don't know how many others use it,
> although some definitely have fun getting it working. (Usually it is the
> Kerberos part on the client side that causes the most grief.)
>

It certainly is fun. But it gets frustrating when one fights a single
problem for weeks on end.

Far too few shops use Kerberos though.

Regards,
Elias
__

Re: Possible bug in NFSv4 with krb5p security?

2013-02-12 Thread Rick Macklem
Elias Martenson wrote:
> First of all, I used the "bug" word in the subject, and I'm not doing
> that
> lightly. I fully understand that the initial reaction to such claim is
> "he
> did something wrong", and frankly, that's what I'm hoping.
> 
> I've spent the last two weeks trying to get an NFS share working with
> krb5p
> security from a FreeBSD server to OSX and Ubuntu clients. I've
> followed all
> the documentation, read everything Google could find for me, asked on
> the
> IRC channel and even asked on Stackexchange, all to no avail.
> 
There is (in case you missed it on google):
http://code.google.com/p/macnfsv4/wiki/FreeBSD8KerberizedNFSSetup
(Nothing much has changed since FreeBSD8, except the name of the client
 side patch for host based initiator credentials in the keytab file.)
I was hoping others would add/update the wiki and it would eventually
become FreeBSD doc, but that hasn't happened.

Feel free to add to the wiki. All you need is a google login.

Other than that, the various discussions in the archive on this list
may help. Unfortunately, I don't know of an easy way to figure out
what is busted. I always suggest looking at the packets in wireshark,
but for some reason, I get the impression that folk don't like
doing this? It is what I do first when I run into NFS issues.

> In all my reading, something struck me as odd: Nowhere did I find any
> indication that anyone has actually set this up on 9.1-CURRENT. After
> receiving zero replies on Stackexchange I started to think that
> perhaps
> this is actually a bug.
> 
> Now, after all this talk, please let me explain what I've done. Most
> of
> this text is taken verbatim from my Stackexchange question here:
> 
> http://serverfault.com/questions/477118/permissions-are-not-taking-effect-with-kerberised-nfsv4-on-freebsd
> 
> Problem summary
> ===
> 
> My goal is to achieve the following:
> 
> - Files served from the FreeBSD system
> - The only security model should be krb5p
> - Clients are Linux (Ubuntu) and OSX
> 
> The problem that I'm facing is that even though the Kerberos
> authentication
> works, all accesses are performed using the user "nobody".
> 
> I can see the permissions when I do "ls -l". Even the user mapping
> works
> correctly, but unless "nobody" has permission to do anything with the
> files, I get a permission denied.
> 
> Here's an example interaction from the client (Ubuntu in this case,
> but the
> same thing happens from OSX). In this example,
> /export/shared/testshare is
> the shared directory from the FreeBSD server:
> 
> (I have changed the actual domain name to `domain` and the Kerberos
> realm
> name to `REALM`)
> 
> $ kinit
> Password for elias@REALM:
> $ klist
> Ticket cache: FILE:/tmp/krb5cc_1000_GBjtDP
> Default principal: elias@REALM
> 
> Valid starting Expires Service principal
> 09/02/2013 09:40:47 10/02/2013 09:40:44 krbtgt/REALM@REALM
> $ sudo mount -t nfs4 -osec=krb5p,vers=4 lion:/export/shared/testshare
> /mnt
> $ ls -l /mnt
> total 4
> -rw-r--r-- 1 nobody nogroup 5 Feb 7 18:17 bar.txt
> -rw--- 1 elias nogroup 4 Feb 5 23:09 foo.txt
> $ cat /mnt/bar.txt
> blah
> $ echo foo >>/mnt/bar.txt
> bash: /mnt/bar.txt: Permission denied
> $ cat /mnt/foo.txt
> cat: /mnt/foo.txt: Permission denied
> $ klist
> Ticket cache: FILE:/tmp/krb5cc_1000_GBjtDP
> Default principal: elias@REALM
> 
> Valid starting Expires Service principal
> 09/02/2013 09:40:47 10/02/2013 09:40:44 krbtgt/REALM@REALM
> 09/02/2013 09:41:56 10/02/2013 09:40:44 nfs/lion.domain@REALM
> 
> Server configuration
> 
> 
> I have had quite some problems in finding a comprehensive guide to
> setting
> up NFSv4 on FreeBSD. This is somewhat surprising in itself as I have
> found
> that information on how to do things in FreeBSD to be very good.
> 
> Here are the relevant lines in /etc/rc.conf:
> 
> rpcbind_enable="YES"
> nfs_server_enable="YES"
> nfsv4_server_enable="YES"
> nfsuserd_enable="YES"
> nfscbd_enable="YES"
Needed for client side only, and only if delegations are
enabled at the server and you want the client to acquire
delegations. (Delegations are not enabled by default on the
FreeBSD NFSv4 server.)

> mountd_enable="YES"
> gssd_enable="YES"
> rpc_lockd_enable="YES"
> rpc_statd_enable="YES"
You shouldn't need rpc_lockd or rpc_statd for NFSv4,
since they are only used for NFSv3.

> zfs_enable="YES"
> 
> Here is the content of /etc/exports:
> 
> /export/shared/testshare -sec=krb5p
> V4: / -sec=krb5p
> 
> Another interesting aspect is that when I used `tcpdump` to record the
> NFS
> network traffic between the client and the server, I saw NFS3 packets
> together with the NFS4 packets. Both of these packet types contained
> encrypted data, so I still think Kerberos was used, but given the
> configuration above, I would have expected there to be nothing but
> NFS4
> traffic.
> 
I don't know why a Linux client would mix NFSv3 RPCs with NFSv4 ones,
but you can look at a raw packet capture done by tcpdump in wiresh

Possible bug in NFSv4 with krb5p security?

2013-02-12 Thread Elias Mårtenson
First of all, I used the "bug" word in the subject, and I'm not doing that
lightly. I fully understand that the initial reaction to such claim is "he
did something wrong", and frankly, that's what I'm hoping.

I've spent the last two weeks trying to get an NFS share working with krb5p
security from a FreeBSD server to OSX and Ubuntu clients. I've followed all
the documentation, read everything Google could find for me, asked on the
IRC channel and even asked on Stackexchange, all to no avail.

In all my reading, something struck me as odd: Nowhere did I find any
indication that anyone has actually set this up on 9.1-CURRENT. After
receiving zero replies on Stackexchange I started to think that perhaps
this is actually a bug.

Now, after all this talk, please let me explain what I've done. Most of
this text is taken verbatim from my Stackexchange question here:

http://serverfault.com/questions/477118/permissions-are-not-taking-effect-with-kerberised-nfsv4-on-freebsd

Problem summary
===

My goal is to achieve the following:

 - Files served from the FreeBSD system
 - The only security model should be krb5p
 - Clients are Linux (Ubuntu) and OSX

The problem that I'm facing is that even though the Kerberos authentication
works, all accesses are performed using the user "nobody".

I can see the permissions when I do "ls -l". Even the user mapping works
correctly, but unless "nobody" has permission to do anything with the
files, I get a permission denied.

Here's an example interaction from the client (Ubuntu in this case, but the
same thing happens from OSX). In this example, /export/shared/testshare is
the shared directory from the FreeBSD server:

(I have changed the actual domain name to `domain` and the Kerberos realm
name to `REALM`)

$ kinit
Password for elias@REALM:
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000_GBjtDP
Default principal: elias@REALM

Valid starting   Expires  Service principal
09/02/2013 09:40:47  10/02/2013 09:40:44  krbtgt/REALM@REALM
$ sudo mount -t nfs4 -osec=krb5p,vers=4 lion:/export/shared/testshare
/mnt
$ ls -l /mnt
total 4
-rw-r--r-- 1 nobody nogroup   5 Feb  7 18:17 bar.txt
-rw--- 1 elias  nogroup   4 Feb  5 23:09 foo.txt
$ cat /mnt/bar.txt
blah
$ echo foo >>/mnt/bar.txt
bash: /mnt/bar.txt: Permission denied
$ cat /mnt/foo.txt
cat: /mnt/foo.txt: Permission denied
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000_GBjtDP
Default principal: elias@REALM

Valid starting   Expires  Service principal
09/02/2013 09:40:47  10/02/2013 09:40:44  krbtgt/REALM@REALM
09/02/2013 09:41:56  10/02/2013 09:40:44  nfs/lion.domain@REALM

Server configuration


I have had quite some problems in finding a comprehensive guide to setting
up NFSv4 on FreeBSD. This is somewhat surprising in itself as I have found
that information on how to do things in FreeBSD to be very good.

Here are the relevant lines in /etc/rc.conf:

rpcbind_enable="YES"
nfs_server_enable="YES"
nfsv4_server_enable="YES"
nfsuserd_enable="YES"
nfscbd_enable="YES"
mountd_enable="YES"
gssd_enable="YES"
rpc_lockd_enable="YES"
rpc_statd_enable="YES"
zfs_enable="YES"

Here is the content of /etc/exports:

/export/shared/testshare -sec=krb5p
V4: / -sec=krb5p

Another interesting aspect is that when I used `tcpdump` to record the NFS
network traffic between the client and the server, I saw NFS3 packets
together with the NFS4 packets. Both of these packet types contained
encrypted data, so I still think Kerberos was used, but given the
configuration above, I would have expected there to be nothing but NFS4
traffic.

If anyone is able to confirm whether or not this actually has been tested
in 9.1-CURRENT, I'd appreciate it. Also, if not, then I'd love to know
where I should start looking for a solution. I'm experienced in system
level programming (having worked on Solaris at Sun in a previous life), but
a pointer where to start would be helpful.

Thanks and regards,
Elias
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"