On Mon, 24 Oct 2011 15:42:10 -0500
Dan Nelson <dnel...@allantgroup.com> wrote:

> In the last episode (Oct 24), Christopher J. Ruwe said:
> > On Sun, 23 Oct 2011 19:10:34 -0500
> > Dan Nelson <dnel...@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.
> 

Thanks for your help so far. Just assuming (I am not sufficiently clear about 
myself and my own intents) I want to be precise and am afraid of guessing: Can 
I assume that the gecos field is an entry in /etc/passwd and can therefore 
never exceed LINE_MAX, i.e., 2048B (limits.h, line 72)? Or, more precisely,  ( 
2048B - sum( lenght(all fields except passwd) ) )? Would that be an acceptable 
limit to set the getpwnam_r( ... ) buffer to and/or would that be an acceptable 
value to replace the following bit from sysconf.c?

    372    #if _POSIX_THREAD_SAFE_FUNCTIONS > -1
    373         case _SC_GETGR_R_SIZE_MAX:
    374         case _SC_GETPW_R_SIZE_MAX:
    375         #error "somebody needs to implement this"
    376    #endif

Thanks again, cheers,
-- 
Christopher J. Ruwe
TZ GMT + 2

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

Reply via email to