_SC_GETPW_R_SIZE_MAX undefined in sysconf.c, what is correct
value?
Dan Nelson
dnelson at allantgroup.com
Mon Oct 24 20:42:11 UTC 2011
In the last episode (Oct 24), Christopher J. Ruwe said:
> On Sun, 23 Oct 2011 19:10:34 -0500
> Dan Nelson <dnelson at allantgroup.com> wrote:
> > In the last episode (Oct 23), Christopher J. Ruwe said:
> > > I need to get the maximum size of an pwd-entry to determine the
> > > correct buffersize for calling getpwnam_r("uname",&pwd, buf, bufsize,
> > > &pwdp). I would like to use sysconf(_SC_GETPW_R_SIZE_MAX) to
> > > determine bufsize, which unfornutately fails (returns -1). Currently,
> > > I used 16384, which seems to be too much, bit works for the time
> > > being.
[..]
> > From looking at the libc/gen/getpwent.c file, it looks like a maximum
> > size might be 1MB. The wrapper functions that convert getpw*_r
> > functions into ones that simply return a pointer to malloced data all
> > use the getpw() helper function, which starts with a 1k buffer and keeps
> > doubling its size until the data fits or it hits PWD_STORAGE_MAX (1MB).
> > PWD_STORAGE_MAX is only checked within that getpw() function, though, so
> > it's possible that an nss library might return an even longer string to
> > a get*_r call. It's up to you to decide what your own limit is :)
>
> Uh ... it's just that I hoped I had not to decide ;-)
>
> However, 1M seems to be rather large to me. Let's see (pwd.h):
>
> 116 struct passwd {
> 117 char *pw_name; /* user name */
> 118 char *pw_passwd; /* encrypted password */
> 119 uid_t pw_uid; /* user uid */
> 120 gid_t pw_gid; /* user gid */
> 121 time_t pw_change; /* password change time */
> 122 char *pw_class; /* user access class */
> 123 char *pw_gecos; /* Honeywell login info */
> 124 char *pw_dir; /* home directory */
> 125 char *pw_shell; /* default shell */
> 126 time_t pw_expire; /* account expiration */
> 127 int pw_fields; /* internal: fields filled in */
> 128 };
>
> So pw_name -> MAXLOGNAME (from param.h) = 17. pw_passwd ->
> http://www.freebsd.org/doc/handbook/one-time-passwords.html = 129. pw_uid
> & pw_gid each sizeof(__uint32_t) ?= 32b. time_t -> sizeof(__int64_t) ?=
> 64b.
>
> At some point, I would just sum it up and reach some size which might be
> machine dependant, but should be somewhere (guessing/estimating now)
> between 4k and 16k. I am short on time just now, am I on the right track
> or am I missing something which should be obvious to someone with
> experience, but is not to me (lacking experience)?
The getpwnam_r function needs enough space to store the "struct passwd"
itself (which has a constant size) plus the strings pointed to by pw_name,
pw_class, pw_gecos, pw_dir, and pw_shell. If you have enough control over
your environment that you can guarantee that the sum of those strings won't
be larger than 4k, then you can just used a fixed buffer of that size. Even
1k is probably large enough for 99.999% of all systems. That's a really
long home directory or shell path :) On the other hand, the GECOS field is
theoretially free-form and could contain a lot of data. I've never see it
hold more than an office number myself, though.
--
Dan Nelson
dnelson at allantgroup.com
More information about the freebsd-hackers
mailing list