This is a port of uid_from_user() and gid_from_group() from NetBSD
(also present in FreeBSD). I did not port the pwcache_userdb() and
pwcache_groupdb() functions which we have no use for.
This is basically just the contents pax's cache.c moved to libc.
It replaces the existing pwcache.c functions user_from_uid(3) and
group_from_gid(3). The pax-derived version does not have a limit
to the size of the hash table.
Unlike the Net/Free version, this does not call setpassent(3) or
setgroupent(3) directly. If you want to keep the passwd or group
files open you need to call those directly. This is consistent
with rev 1.10 of pwcache.c.
The new functions can be used to speed up repeated user -> uid
lookups in mtree, newsyslog and others. Those diffs will be sent
separately.
- todd
Index: include/pwd.h
===================================================================
RCS file: /cvs/src/include/pwd.h,v
retrieving revision 1.25
diff -u -p -u -r1.25 pwd.h
--- include/pwd.h 9 Mar 2017 10:13:03 -0000 1.25
+++ include/pwd.h 10 Sep 2018 00:46:44 -0000
@@ -106,7 +106,8 @@ void endpwent(void);
#endif
#if __BSD_VISIBLE
int setpassent(int);
-char *user_from_uid(uid_t, int);
+int uid_from_user(const char *, uid_t *);
+const char *user_from_uid(uid_t, int);
char *bcrypt_gensalt(u_int8_t);
char *bcrypt(const char *, const char *);
int bcrypt_newhash(const char *, int, char *, size_t);
Index: include/grp.h
===================================================================
RCS file: /cvs/src/include/grp.h,v
retrieving revision 1.12
diff -u -p -u -r1.12 grp.h
--- include/grp.h 31 Aug 2014 04:04:38 -0000 1.12
+++ include/grp.h 10 Sep 2018 00:46:44 -0000
@@ -70,7 +70,8 @@ int getgrnam_r(const char *, struct gr
#endif
#if __BSD_VISIBLE
int setgroupent(int);
-char *group_from_gid(gid_t, int);
+int gid_from_group(const char *, gid_t *);
+const char *group_from_gid(gid_t, int);
#endif
__END_DECLS
Index: lib/libc/gen/pwcache.3
===================================================================
RCS file: /cvs/src/lib/libc/gen/pwcache.3,v
retrieving revision 1.13
diff -u -p -u -r1.13 pwcache.3
--- lib/libc/gen/pwcache.3 26 Mar 2016 14:36:37 -0000 1.13
+++ lib/libc/gen/pwcache.3 10 Sep 2018 00:46:44 -0000
@@ -32,14 +32,20 @@
.Os
.Sh NAME
.Nm user_from_uid ,
+.Nm uid_from_user ,
.Nm group_from_gid
+.Nm gid_from_group
.Nd cache password and group entries
.Sh SYNOPSIS
-.In grp.h
.In pwd.h
-.Ft char *
+.Ft int
+.Fn uid_from_user "const char *name" "uid_t *uid"
+.Ft const char *
.Fn user_from_uid "uid_t uid" "int nouser"
-.Ft char *
+.In grp.h
+.Ft int
+.Fn gid_from_group "const char *name" "gid_t *gid"
+.Ft const char *
.Fn group_from_gid "gid_t gid" "int nogroup"
.Sh DESCRIPTION
The
@@ -60,6 +66,22 @@ unless the argument
is non-zero, in which case a null pointer is returned.
.Pp
The
+.Fn uid_from_user
+function returns the uid associated with the argument
+.Fa name .
+The uid is cached so that multiple calls with the same
+.Fa name
+do not require additional calls to
+.Xr getpwnam 3 .
+If there is no uid associated with the
+.Fa name ,
+the
+.Fn uid_from_user
+function returns -1; otherwise it stores the uid at the location pointed to by
+.Fa uid
+and returns 0.
+.Pp
+The
.Fn group_from_gid
function returns the group name associated with the argument
.Fa gid .
@@ -75,6 +97,22 @@ to a string representation of the
unless the argument
.Fa nogroup
is non-zero, in which case a null pointer is returned.
+.Pp
+The
+.Fn gid_from_group
+function returns the gid associated with the argument
+.Fa name .
+The gid is cached so that multiple calls with the same
+.Fa name
+do not require additional calls to
+.Xr getgrnam 3 .
+If there is no gid associated with the
+.Fa name ,
+the
+.Fn gid_from_group
+function returns -1; otherwise it stores the gid at the location pointed to by
+.Fa gid
+and returns 0.
.Sh SEE ALSO
.Xr getgrgid 3 ,
.Xr getpwuid 3
@@ -85,3 +123,12 @@ and
.Fn group_from_gid
functions first appeared in
.Bx 4.4 .
+.Pp
+The
+.Fn uid_from_user
+and
+.Fn gid_from_group
+functions were ported from
+.Nx
+and first appeared in
+.Ox 6.4 .
Index: lib/libc/gen/pwcache.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/pwcache.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 pwcache.c
--- lib/libc/gen/pwcache.c 25 Nov 2015 23:16:01 -0000 1.13
+++ lib/libc/gen/pwcache.c 10 Sep 2018 15:04:35 -0000
@@ -1,8 +1,13 @@
-/* $OpenBSD: pwcache.c,v 1.13 2015/11/25 23:16:01 jcs Exp $ */
-/*
- * Copyright (c) 1989, 1993
+/* $OpenBSD: pwcache.c,v 1.13 2015/11/25 23:16:01 jcs Exp $ */
+
+/*-
+ * Copyright (c) 1992 Keith Muller.
+ * Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,102 +35,372 @@
#include <sys/types.h>
+#include <assert.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include "pwcache.h"
+
+/*
+ * routines that control user, group, uid and gid caches (for the archive
+ * member print routine).
+ * IMPORTANT:
+ * these routines cache BOTH hits and misses, a major performance improvement
+ */
+
+static UIDC **uidtb; /* uid to name cache */
+static GIDC **gidtb; /* gid to name cache */
+static UIDC **usrtb; /* user name to uid cache */
+static GIDC **grptb; /* group name to gid cache */
+
+static u_int
+st_hash(const char *name, size_t len, int tabsz)
+{
+ u_int key = 0;
+
+ assert(name != NULL);
+
+ while (len--) {
+ key += *name++;
+ key = (key << 8) | (key >> 24);
+ }
+
+ return key % tabsz;
+}
+
+/*
+ * uidtb_start
+ * creates an an empty uidtb
+ * Return:
+ * 0 if ok, -1 otherwise
+ */
+static int
+uidtb_start(void)
+{
+ static int fail = 0;
+
+ if (uidtb != NULL)
+ return 0;
+ if (fail)
+ return -1;
+ if ((uidtb = calloc(UID_SZ, sizeof(UIDC *))) == NULL) {
+ ++fail;
+ return -1;
+ }
+ return 0;
+}
-#define NCACHE 16 /* power of 2 */
-#define NLINES 4 /* associativity */
-#define MASK (NCACHE - 1) /* bits to store with */
-#define IDX(x, i) ((x & MASK) + i * NCACHE)
-
-char *
-user_from_uid(uid_t uid, int nouser)
-{
- static struct ncache {
- uid_t uid;
- short noname;
- char name[_PW_NAME_LEN + 1];
- } c_uid[NLINES * NCACHE];
+/*
+ * gidtb_start
+ * creates an an empty gidtb
+ * Return:
+ * 0 if ok, -1 otherwise
+ */
+static int
+gidtb_start(void)
+{
+ static int fail = 0;
+
+ if (gidtb != NULL)
+ return 0;
+ if (fail)
+ return -1;
+ if ((gidtb = calloc(GID_SZ, sizeof(GIDC *))) == NULL) {
+ ++fail;
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * usrtb_start
+ * creates an an empty usrtb
+ * Return:
+ * 0 if ok, -1 otherwise
+ */
+static int
+usrtb_start(void)
+{
+ static int fail = 0;
+
+ if (usrtb != NULL)
+ return 0;
+ if (fail)
+ return -1;
+ if ((usrtb = calloc(UNM_SZ, sizeof(UIDC *))) == NULL) {
+ ++fail;
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * grptb_start
+ * creates an an empty grptb
+ * Return:
+ * 0 if ok, -1 otherwise
+ */
+static int
+grptb_start(void)
+{
+ static int fail = 0;
+
+ if (grptb != NULL)
+ return 0;
+ if (fail)
+ return -1;
+ if ((grptb = calloc(GNM_SZ, sizeof(GIDC *))) == NULL) {
+ ++fail;
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * user_from_uid()
+ * caches the name (if any) for the uid. If noname clear, we always
+ * return the stored name (if valid or invalid match).
+ * We use a simple hash table.
+ * Return
+ * Pointer to stored name (or a empty string)
+ */
+const char *
+user_from_uid(uid_t uid, int noname)
+{
+ struct passwd pwstore, *pw = NULL;
char pwbuf[_PW_BUF_LEN];
- struct passwd pwstore, *pw;
- struct ncache *cp;
- unsigned int i;
-
- for (i = 0; i < NLINES; i++) {
- cp = &c_uid[IDX(uid, i)];
- if (!*cp->name) {
-fillit:
- cp->uid = uid;
- pw = NULL;
- getpwuid_r(uid, &pwstore, pwbuf, sizeof(pwbuf), &pw);
- if (pw == NULL) {
- snprintf(cp->name, sizeof(cp->name), "%u", uid);
- cp->noname = 1;
- } else {
- strlcpy(cp->name, pw->pw_name,
sizeof(cp->name));
- }
- }
- if (cp->uid == uid) {
- if (nouser && cp->noname)
- return NULL;
- return cp->name;
- }
- }
- /* move everybody down a slot */
- for (i = 0; i < NLINES - 1; i++) {
- struct ncache *next;
-
- cp = &c_uid[IDX(uid, i)];
- next = &c_uid[IDX(uid, i + 1)];
- memcpy(next, cp, sizeof(*cp));
- }
- cp = &c_uid[IDX(uid, 0)];
- goto fillit;
-}
-
-char *
-group_from_gid(gid_t gid, int nogroup)
-{
- static struct ncache {
- gid_t gid;
- short noname;
- char name[_PW_NAME_LEN + 1];
- } c_gid[NLINES * NCACHE];
+ UIDC *ptr, **pptr;
+
+ if ((uidtb == NULL) && (uidtb_start() < 0))
+ return NULL;
+
+ /*
+ * see if we have this uid cached
+ */
+ pptr = uidtb + (uid % UID_SZ);
+ ptr = *pptr;
+
+ if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
+ /*
+ * have an entry for this uid
+ */
+ if (!noname || (ptr->valid == VALID))
+ return ptr->name;
+ return NULL;
+ }
+
+ if (ptr == NULL)
+ *pptr = ptr = malloc(sizeof(UIDC));
+
+ getpwuid_r(uid, &pwstore, pwbuf, sizeof(pwbuf), &pw);
+ if (pw == NULL) {
+ /*
+ * no match for this uid in the local password file
+ * a string that is the uid in numeric format
+ */
+ if (ptr == NULL)
+ return NULL;
+ ptr->uid = uid;
+ (void)snprintf(ptr->name, UNMLEN, "%u", uid);
+ ptr->valid = INVALID;
+ if (noname)
+ return NULL;
+ } else {
+ /*
+ * there is an entry for this uid in the password file
+ */
+ if (ptr == NULL)
+ return pw->pw_name;
+ ptr->uid = uid;
+ (void)strlcpy(ptr->name, pw->pw_name, UNMLEN);
+ ptr->valid = VALID;
+ }
+ return ptr->name;
+}
+
+/*
+ * group_from_gid()
+ * caches the name (if any) for the gid. If noname clear, we always
+ * return the stored name (if valid or invalid match).
+ * We use a simple hash table.
+ * Return
+ * Pointer to stored name (or a empty string)
+ */
+const char *
+group_from_gid(gid_t gid, int noname)
+{
+ struct group grstore, *gr = NULL;
+ char grbuf[_GR_BUF_LEN];
+ GIDC *ptr, **pptr;
+
+ if ((gidtb == NULL) && (gidtb_start() < 0))
+ return NULL;
+
+ /*
+ * see if we have this gid cached
+ */
+ pptr = gidtb + (gid % GID_SZ);
+ ptr = *pptr;
+
+ if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
+ /*
+ * have an entry for this gid
+ */
+ if (!noname || (ptr->valid == VALID))
+ return ptr->name;
+ return NULL;
+ }
+
+ if (ptr == NULL)
+ *pptr = ptr = malloc(sizeof(GIDC));
+
+ getgrgid_r(gid, &grstore, grbuf, sizeof(grbuf), &gr);
+ if (gr == NULL) {
+ /*
+ * no match for this gid in the local group file, put in
+ * a string that is the gid in numeric format
+ */
+ if (ptr == NULL)
+ return NULL;
+ ptr->gid = gid;
+ (void)snprintf(ptr->name, GNMLEN, "%u", gid);
+ ptr->valid = INVALID;
+ if (noname)
+ return NULL;
+ } else {
+ /*
+ * there is an entry for this group in the group file
+ */
+ if (ptr == NULL)
+ return gr->gr_name;
+ ptr->gid = gid;
+ (void)strlcpy(ptr->name, gr->gr_name, GNMLEN);
+ ptr->valid = VALID;
+ }
+ return ptr->name;
+}
+
+/*
+ * uid_from_user()
+ * caches the uid for a given user name. We use a simple hash table.
+ * Return
+ * the uid (if any) for a user name, or a -1 if no match can be found
+ */
+int
+uid_from_user(const char *name, uid_t *uid)
+{
+ struct passwd pwstore, *pw = NULL;
+ char pwbuf[_PW_BUF_LEN];
+ UIDC *ptr, **pptr;
+ size_t namelen;
+
+ /*
+ * return -1 for mangled names
+ */
+ if (name == NULL || ((namelen = strlen(name)) == 0))
+ return -1;
+ if ((usrtb == NULL) && (usrtb_start() < 0))
+ return -1;
+
+ /*
+ * look up in hash table, if found and valid return the uid,
+ * if found and invalid, return a -1
+ */
+ pptr = usrtb + st_hash(name, namelen, UNM_SZ);
+ ptr = *pptr;
+
+ if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
+ if (ptr->valid == INVALID)
+ return -1;
+ *uid = ptr->uid;
+ return 0;
+ }
+
+ if (ptr == NULL)
+ *pptr = ptr = malloc(sizeof(UIDC));
+
+ /*
+ * no match, look it up, if no match store it as an invalid entry,
+ * or store the matching uid
+ */
+ getpwnam_r(name, &pwstore, pwbuf, sizeof(pwbuf), &pw);
+ if (ptr == NULL) {
+ if (pw == NULL)
+ return -1;
+ *uid = pw->pw_uid;
+ return 0;
+ }
+ (void)strlcpy(ptr->name, name, UNMLEN);
+ if (pw == NULL) {
+ ptr->valid = INVALID;
+ return -1;
+ }
+ ptr->valid = VALID;
+ *uid = ptr->uid = pw->pw_uid;
+ return 0;
+}
+
+/*
+ * gid_from_group()
+ * caches the gid for a given group name. We use a simple hash table.
+ * Return
+ * the gid (if any) for a group name, or a -1 if no match can be found
+ */
+int
+gid_from_group(const char *name, gid_t *gid)
+{
+ struct group grstore, *gr = NULL;
char grbuf[_GR_BUF_LEN];
- struct group grstore, *gr;
- struct ncache *cp;
- unsigned int i;
-
- for (i = 0; i < NLINES; i++) {
- cp = &c_gid[IDX(gid, i)];
- if (!*cp->name) {
-fillit:
- cp->gid = gid;
- gr = NULL;
- getgrgid_r(gid, &grstore, grbuf, sizeof(grbuf), &gr);
- if (gr == NULL) {
- snprintf(cp->name, sizeof(cp->name), "%u", gid);
- cp->noname = 1;
- } else {
- strlcpy(cp->name, gr->gr_name,
sizeof(cp->name));
- }
- }
- if (cp->gid == gid) {
- if (nogroup && cp->noname)
- return NULL;
- return cp->name;
- }
- }
- /* move everybody down a slot */
- for (i = 0; i < NLINES - 1; i++) {
- struct ncache *next;
-
- cp = &c_gid[IDX(gid, i)];
- next = &c_gid[IDX(gid, i + 1)];
- memcpy(next, cp, sizeof(*cp));
+ GIDC *ptr, **pptr;
+ size_t namelen;
+
+ /*
+ * return -1 for mangled names
+ */
+ if (name == NULL || ((namelen = strlen(name)) == 0))
+ return -1;
+ if ((grptb == NULL) && (grptb_start() < 0))
+ return -1;
+
+ /*
+ * look up in hash table, if found and valid return the uid,
+ * if found and invalid, return a -1
+ */
+ pptr = grptb + st_hash(name, namelen, GID_SZ);
+ ptr = *pptr;
+
+ if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
+ if (ptr->valid == INVALID)
+ return -1;
+ *gid = ptr->gid;
+ return 0;
+ }
+
+ if (ptr == NULL)
+ *pptr = ptr = malloc(sizeof(GIDC));
+
+ /*
+ * no match, look it up, if no match store it as an invalid entry,
+ * or store the matching gid
+ */
+ getgrnam_r(name, &grstore, grbuf, sizeof(grbuf), &gr);
+ if (ptr == NULL) {
+ if (gr == NULL)
+ return -1;
+ *gid = gr->gr_gid;
+ return 0;
+ }
+
+ (void)strlcpy(ptr->name, name, GNMLEN);
+ if (gr == NULL) {
+ ptr->valid = INVALID;
+ return -1;
}
- cp = &c_gid[IDX(gid, 0)];
- goto fillit;
+ ptr->valid = VALID;
+ *gid = ptr->gid = gr->gr_gid;
+ return 0;
}
Index: lib/libc/gen/pwcache.h
===================================================================
RCS file: lib/libc/gen/pwcache.h
diff -N lib/libc/gen/pwcache.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/gen/pwcache.h 10 Sep 2018 00:46:44 -0000
@@ -0,0 +1,72 @@
+/* $OpenBSD$ */
+
+/*-
+ * Copyright (c) 1992 Keith Muller.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cache.h 8.1 (Berkeley) 5/31/93
+ */
+
+/*
+ * Constants and data structures used to implement group and password file
+ * caches. Traditional passwd/group cache routines perform quite poorly with
+ * archives. The chances of hitting a valid lookup with an archive is quite a
+ * bit worse than with files already resident on the file system. These misses
+ * create a MAJOR performance cost. To adress this problem, these routines
+ * cache both hits and misses.
+ *
+ * NOTE: name lengths must be as large as those stored in ANY PROTOCOL and
+ * as stored in the passwd and group files. CACHE SIZES MUST BE PRIME
+ */
+#define UNMLEN 32 /* >= user name found in any protocol */
+#define GNMLEN 32 /* >= group name found in any protocol */
+#define UID_SZ 317 /* size of uid to user_name cache */
+#define UNM_SZ 317 /* size of user_name to uid cache */
+#define GID_SZ 251 /* size of gid to group_name cache */
+#define GNM_SZ 251 /* size of group_name to gid cache */
+#define VALID 1 /* entry and name are valid */
+#define INVALID 2 /* entry valid, name NOT valid */
+
+/*
+ * Node structures used in the user, group, uid, and gid caches.
+ */
+
+typedef struct uidc {
+ int valid; /* is this a valid or a miss entry */
+ char name[UNMLEN]; /* uid name */
+ uid_t uid; /* cached uid */
+} UIDC;
+
+typedef struct gidc {
+ int valid; /* is this a valid or a miss entry */
+ char name[GNMLEN]; /* gid name */
+ gid_t gid; /* cached gid */
+} GIDC;
Index: lib/libc/gen/getgrent.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/getgrent.c,v
retrieving revision 1.46
diff -u -p -u -r1.46 getgrent.c
--- lib/libc/gen/getgrent.c 1 Dec 2015 15:08:25 -0000 1.46
+++ lib/libc/gen/getgrent.c 10 Sep 2018 02:02:31 -0000
@@ -144,6 +144,7 @@ getgrnam_r(const char *name, struct grou
errno = errnosave;
return ret;
}
+DEF_WEAK(getgrnam_r);
static struct group *
getgrgid_gs(gid_t gid, struct group *p_gr, struct group_storage *gs)
Index: lib/libc/shlib_version
===================================================================
RCS file: /cvs/src/lib/libc/shlib_version,v
retrieving revision 1.199
diff -u -p -u -r1.199 shlib_version
--- lib/libc/shlib_version 13 Jul 2018 09:27:07 -0000 1.199
+++ lib/libc/shlib_version 10 Sep 2018 00:46:44 -0000
@@ -1,4 +1,4 @@
major=92
-minor=4
+minor=5
# note: If changes were made to include/thread_private.h or if system
# calls were added/changed then librthread/shlib_version also be updated.
Index: lib/libc/Symbols.list
===================================================================
RCS file: /cvs/src/lib/libc/Symbols.list,v
retrieving revision 1.63
diff -u -p -u -r1.63 Symbols.list
--- lib/libc/Symbols.list 13 Jul 2018 09:25:22 -0000 1.63
+++ lib/libc/Symbols.list 10 Sep 2018 00:46:44 -0000
@@ -663,6 +663,7 @@ getpwuid_shadow
getttyent
getttynam
getusershell
+gid_from_group
glob
globfree
group_from_gid
@@ -798,6 +799,7 @@ ttyname
ttyname_r
ttyslot
ualarm
+uid_from_user
uname
unvis
user_from_uid
Index: lib/libc/hidden/grp.h
===================================================================
RCS file: /cvs/src/lib/libc/hidden/grp.h,v
retrieving revision 1.2
diff -u -p -u -r1.2 grp.h
--- lib/libc/hidden/grp.h 24 Nov 2015 22:03:33 -0000 1.2
+++ lib/libc/hidden/grp.h 10 Sep 2018 00:46:44 -0000
@@ -29,7 +29,8 @@ PROTO_DEPRECATED(getgrent);
PROTO_DEPRECATED(getgrgid);
PROTO_NORMAL(getgrgid_r);
PROTO_DEPRECATED(getgrnam);
-PROTO_DEPRECATED(getgrnam_r);
+PROTO_NORMAL(getgrnam_r);
+PROTO_DEPRECATED(gid_from_group);
PROTO_DEPRECATED(group_from_gid);
PROTO_NORMAL(setgrent);
PROTO_NORMAL(setgroupent);
Index: lib/libc/hidden/pwd.h
===================================================================
RCS file: /cvs/src/lib/libc/hidden/pwd.h,v
retrieving revision 1.3
diff -u -p -u -r1.3 pwd.h
--- lib/libc/hidden/pwd.h 24 Nov 2015 22:03:33 -0000 1.3
+++ lib/libc/hidden/pwd.h 10 Sep 2018 00:46:44 -0000
@@ -40,6 +40,7 @@ PROTO_NORMAL(getpwuid_shadow);
PROTO_NORMAL(pw_dup);
PROTO_NORMAL(setpassent);
PROTO_DEPRECATED(setpwent);
+PROTO_DEPRECATED(uid_from_user);
PROTO_DEPRECATED(user_from_uid);
#endif /* !_LIBC_PWD_H_ */