From owner-freebsd-hackers@FreeBSD.ORG Tue Oct 25 20:07:33 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 C52FF1065674 for ; Tue, 25 Oct 2011 20:07:33 +0000 (UTC) (envelope-from cjr@cruwe.de) Received: from cruwe.de (cruwe.de [188.40.164.98]) by mx1.freebsd.org (Postfix) with ESMTP id 2551A8FC08 for ; Tue, 25 Oct 2011 20:07:33 +0000 (UTC) Received: from cruwe.de (unknown [127.0.0.4]) by cruwe.de (Postfix) with ESMTP id 662802855E for ; Tue, 25 Oct 2011 20:07:31 +0000 (UTC) Received: by cruwe.de (Postfix, from userid 65534) id 4CEE82855B; Tue, 25 Oct 2011 20:07:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.cruwe.de X-Spam-Level: X-Spam-Status: No, score=-1.0 required=4.0 tests=ALL_TRUSTED autolearn=unavailable version=3.3.1 Received: from dijkstra (p5B37B6CE.dip.t-dialin.net [91.55.182.206]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by cruwe.de (Postfix) with ESMTPSA id 4F6362854A; Tue, 25 Oct 2011 20:07:28 +0000 (UTC) Date: Tue, 25 Oct 2011 22:07:25 +0200 From: "Christopher J. Ruwe" To: Dan Nelson Message-ID: <20111025220725.7327fd57@dijkstra> In-Reply-To: <20111024204209.GF93709@dan.emsphone.com> References: <20111023235231.71f73ea3@dijkstra> <20111024001034.GE93709@dan.emsphone.com> <20111024213140.491467d9@dijkstra> <20111024204209.GF93709@dan.emsphone.com> X-Mailer: Claws Mail 3.7.10 (GTK+ 2.24.6; amd64-portbld-freebsd8.2) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV on mail.cruwe.de using ClamSMTP 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: Tue, 25 Oct 2011 20:07:33 -0000 On Mon, 24 Oct 2011 15:42:10 -0500 Dan Nelson wrote: > 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. > 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