From owner-svn-src-all@FreeBSD.ORG Tue Jun 21 21:07:33 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77E2D1065672; Tue, 21 Jun 2011 21:07:33 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4E8318FC13; Tue, 21 Jun 2011 21:07:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p5LL7XI9017054; Tue, 21 Jun 2011 21:07:33 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p5LL7X07017052; Tue, 21 Jun 2011 21:07:33 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201106212107.p5LL7X07017052@svn.freebsd.org> From: Rick Macklem Date: Tue, 21 Jun 2011 21:07:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r223382 - head/usr.sbin/nfsuserd X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Jun 2011 21:07:33 -0000 Author: rmacklem Date: Tue Jun 21 21:07:33 2011 New Revision: 223382 URL: http://svn.freebsd.org/changeset/base/223382 Log: Change the NFSv4 nfsuserd(8) daemon so that it doesn't preload the uid<->username mapping cache with an entry when another entry for that uid is already loaded. This fixes a case where the mapping of "toor" would replace "root" when the daemon was started, resulting in no mapping for "root" until the cache entry for "toor" timed out. The algorithm is inefficient, but since it is only done once when the daemon is started up, I don't think that's an issue. MFC after: 2 weeks Modified: head/usr.sbin/nfsuserd/nfsuserd.c Modified: head/usr.sbin/nfsuserd/nfsuserd.c ============================================================================== --- head/usr.sbin/nfsuserd/nfsuserd.c Tue Jun 21 20:52:55 2011 (r223381) +++ head/usr.sbin/nfsuserd/nfsuserd.c Tue Jun 21 21:07:33 2011 (r223382) @@ -76,6 +76,8 @@ static bool_t xdr_retval(XDR *, caddr_t) #define MAXNAME 1024 #define MAXNFSUSERD 20 #define DEFNFSUSERD 4 +#define MAXUSERMAX 100000 +#define MINUSERMAX 10 #define DEFUSERMAX 200 #define DEFUSERTIMEOUT (1 * 60) struct info { @@ -96,8 +98,8 @@ pid_t slaves[MAXNFSUSERD]; int main(int argc, char *argv[]) { - int i; - int error, len, mustfreeai = 0; + int i, j; + int error, fnd_dup, len, mustfreeai = 0, start_uidpos; struct nfsd_idargs nid; struct passwd *pwd; struct group *grp; @@ -107,6 +109,7 @@ main(int argc, char *argv[]) sigset_t signew; char hostname[MAXHOSTNAMELEN + 1], *cp; struct addrinfo *aip, hints; + static uid_t check_dups[MAXUSERMAX]; if (modfind("nfscommon") < 0) { /* Not present in kernel, try loading it */ @@ -163,9 +166,10 @@ main(int argc, char *argv[]) argc--; argv++; i = atoi(*argv); - if (i < 10 || i > 100000) { + if (i < MINUSERMAX || i > MAXUSERMAX) { fprintf(stderr, - "usermax %d out of range 10<->100000\n", i); + "usermax %d out of range %d<->%d\n", i, + MINUSERMAX, MAXUSERMAX); usage(); } nid.nid_usermax = i; @@ -326,8 +330,25 @@ main(int argc, char *argv[]) /* * Loop around adding all users. */ + start_uidpos = i; setpwent(); while (i < nid.nid_usermax && (pwd = getpwent())) { + fnd_dup = 0; + /* + * Yes, this is inefficient, but it is only done once when + * the daemon is started and will run in a fraction of a second + * for nid_usermax at 10000. If nid_usermax is cranked up to + * 100000, it will take several seconds, depending on the CPU. + */ + for (j = 0; j < (i - start_uidpos); j++) + if (check_dups[j] == pwd->pw_uid) { + /* Found another entry for uid, so skip it */ + fnd_dup = 1; + break; + } + if (fnd_dup != 0) + continue; + check_dups[i - start_uidpos] = pwd->pw_uid; nid.nid_uid = pwd->pw_uid; nid.nid_name = pwd->pw_name; nid.nid_namelen = strlen(pwd->pw_name);