From owner-freebsd-hackers@FreeBSD.ORG Mon Oct 24 20:42:11 2011 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AEF7D1065674 for ; Mon, 24 Oct 2011 20:42:11 +0000 (UTC) (envelope-from dan@dan.emsphone.com) Received: from email2.allantgroup.com (email2.emsphone.com [199.67.51.116]) by mx1.freebsd.org (Postfix) with ESMTP id 810CA8FC08 for ; Mon, 24 Oct 2011 20:42:11 +0000 (UTC) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by email2.allantgroup.com (8.14.4/8.14.4) with ESMTP id p9OKgAUR071417 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 24 Oct 2011 15:42:10 -0500 (CDT) (envelope-from dan@dan.emsphone.com) Received: from dan.emsphone.com (smmsp@localhost [127.0.0.1]) by dan.emsphone.com (8.14.5/8.14.5) with ESMTP id p9OKgAhF067148 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 24 Oct 2011 15:42:10 -0500 (CDT) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.14.5/8.14.5/Submit) id p9OKgA4q067139; Mon, 24 Oct 2011 15:42:10 -0500 (CDT) (envelope-from dan) Date: Mon, 24 Oct 2011 15:42:10 -0500 From: Dan Nelson To: "Christopher J. Ruwe" Message-ID: <20111024204209.GF93709@dan.emsphone.com> References: <20111023235231.71f73ea3@dijkstra> <20111024001034.GE93709@dan.emsphone.com> <20111024213140.491467d9@dijkstra> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20111024213140.491467d9@dijkstra> X-OS: FreeBSD 8.2-STABLE User-Agent: Mutt/1.5.21 (2010-09-15) X-Virus-Scanned: clamav-milter 0.97.2 at email2.allantgroup.com X-Virus-Status: Clean X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.6 (email2.allantgroup.com [199.67.51.78]); Mon, 24 Oct 2011 15:42:10 -0500 (CDT) X-Scanned-By: MIMEDefang 2.68 on 199.67.51.78 Cc: freebsd-hackers@freebsd.org Subject: Re: _SC_GETPW_R_SIZE_MAX undefined in sysconf.c, what is correct value? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Oct 2011 20:42:11 -0000 In the last episode (Oct 24), Christopher J. Ruwe said: > On Sun, 23 Oct 2011 19:10:34 -0500 > Dan Nelson 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@allantgroup.com