Date: Tue, 19 Feb 2013 11:31:42 +0200 From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua> To: Elias Martenson <lokedhs@gmail.com> Cc: Rick Macklem <rmacklem@uoguelph.ca>, Benjamin Kaduk <kaduk@mit.edu>, freebsd-current@freebsd.org Subject: Re: Possible bug in NFSv4 with krb5p security? Message-ID: <20130219093142.GA1459@pm513-1.comsys.ntu-kpi.kiev.ua> In-Reply-To: <CADtN0WKVzbKxhaLQw8y2KLhhRJC9n4ht9wyPmGQ%2BpHqSjQkVNw@mail.gmail.com> References: <CADtN0WLs%2B=EtM4VnHcvxdihbKx4kjaoMQZK61F%2BnKx%2BDpAqrfg@mail.gmail.com> <477291850.3084864.1361113135205.JavaMail.root@erie.cs.uoguelph.ca> <CADtN0WKVzbKxhaLQw8y2KLhhRJC9n4ht9wyPmGQ%2BpHqSjQkVNw@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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);
}
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130219093142.GA1459>
