PR/29849, PR/29850: Add getpwent_r and getgrent_r

This commit is contained in:
christos 2005-04-02 04:53:53 +00:00
parent 5f983b5879
commit 184974e05a
4 changed files with 377 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: getgrent.c,v 1.55 2005/03/31 23:58:28 lukem Exp $ */
/* $NetBSD: getgrent.c,v 1.56 2005/04/02 04:53:53 christos Exp $ */
/*-
* Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
@ -95,7 +95,7 @@
#if 0
static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
#else
__RCSID("$NetBSD: getgrent.c,v 1.55 2005/03/31 23:58:28 lukem Exp $");
__RCSID("$NetBSD: getgrent.c,v 1.56 2005/04/02 04:53:53 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -130,6 +130,7 @@ __RCSID("$NetBSD: getgrent.c,v 1.55 2005/03/31 23:58:28 lukem Exp $");
#ifdef __weak_alias
__weak_alias(endgrent,_endgrent)
__weak_alias(getgrent,_getgrent)
__weak_alias(getgrent_r,_getgrent_r)
__weak_alias(getgrgid,_getgrgid)
__weak_alias(getgrgid_r,_getgrgid_r)
__weak_alias(getgrnam,_getgrnam)
@ -457,6 +458,32 @@ _files_getgrent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_files_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct group *grp = va_arg(ap, struct group *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct group **result = va_arg(ap, struct group **);
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(grp != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
rv = __grscan_files(retval, grp, buffer, buflen,
&_files_state, 0, NULL, 0);
if (rv == NS_SUCCESS)
*result = grp;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_files_getgrgid(void *nsrv, void *nscb, va_list ap)
@ -747,6 +774,31 @@ _dns_getgrent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_dns_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct group *grp = va_arg(ap, struct group *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct group **result = va_arg(ap, struct group **);
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(grp != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
rv = __grscan_dns(retval, grp, buffer, buflen,
&_dns_state, 0, NULL, 0);
if (rv == NS_SUCCESS)
*result = grp;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_dns_getgrgid(void *nsrv, void *nscb, va_list ap)
@ -1063,6 +1115,32 @@ _nis_getgrent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_nis_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct group *grp = va_arg(ap, struct group *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct group **result = va_arg(ap, struct group **);
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(grp != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
rv = __grscan_nis(retval, grp, buffer, buflen,
&_nis_state, 0, NULL, 0);
if (rv == NS_SUCCESS)
*result = grp;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_nis_getgrgid(void *nsrv, void *nscb, va_list ap)
@ -1256,8 +1334,8 @@ __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen,
static const ns_dtab compatentdtab[] = {
NS_FILES_CB(__grbad_compat, "files")
NS_DNS_CB(_dns_getgrent, NULL)
NS_NIS_CB(_nis_getgrent, NULL)
NS_DNS_CB(_dns_getgrent_r, NULL)
NS_NIS_CB(_nis_getgrent_r, NULL)
NS_COMPAT_CB(__grbad_compat, "compat")
{ 0 }
};
@ -1306,15 +1384,15 @@ __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen,
free(state->name); /* (only check 1 grp) */
state->name = NULL;
} else if (!search) { /* any group */
/* XXXREENTRANT: need to implement and use getgrent_r() */
if (searchfunc) {
crv = searchfunc(searchcookie,
&cgrpres);
} else {
crv = nsdispatch(NULL, compatentdtab,
NSDB_GROUP_COMPAT, "getgrent",
NSDB_GROUP_COMPAT, "getgrent_r",
__nsdefaultnis,
&cgrpres);
&cretval, &cgrp, filebuf,
sizeof(filebuf), &cgrpres);
}
} else if (name) { /* specific group */
crv = nsdispatch(NULL, compatnamdtab,
@ -1499,6 +1577,32 @@ _compat_getgrent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_compat_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct group *grp = va_arg(ap, struct group *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct group **result = va_arg(ap, struct group **);
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(grp != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
rv = __grscan_compat(retval, grp, buffer, buflen,
&_compat_state, 0, NULL, 0, NULL, NULL);
if (rv == NS_SUCCESS)
*result = grp;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_compat_getgrgid(void *nsrv, void *nscb, va_list ap)
@ -1632,9 +1736,31 @@ getgrent(void)
rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent", __nsdefaultcompat,
&retval);
mutex_unlock(&__grmutex);
return (rv == NS_SUCCESS) ? retval : NULL;
return (rv == NS_SUCCESS) ? 0 : retval;
}
int
getgrent_r(struct group *grp, char *buffer, size_t buflen,
struct group **result)
{
int rv, retval;
static const ns_dtab dtab[] = {
NS_FILES_CB(_files_getgrent_r, NULL)
NS_DNS_CB(_dns_getgrent_r, NULL)
NS_NIS_CB(_nis_getgrent_r, NULL)
NS_COMPAT_CB(_compat_getgrent_r, NULL)
{ 0 }
};
mutex_lock(&__grmutex);
rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent_r", __nsdefaultcompat,
&retval, grp, buffer, buflen, result);
mutex_unlock(&__grmutex);
return (rv == NS_SUCCESS) ? 0 : retval;
}
struct group *
getgrgid(gid_t gid)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: getpwent.c,v 1.66 2005/02/28 00:40:05 lukem Exp $ */
/* $NetBSD: getpwent.c,v 1.67 2005/04/02 04:53:53 christos Exp $ */
/*-
* Copyright (c) 1997-2000, 2004-2005 The NetBSD Foundation, Inc.
@ -95,7 +95,7 @@
#if 0
static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
#else
__RCSID("$NetBSD: getpwent.c,v 1.66 2005/02/28 00:40:05 lukem Exp $");
__RCSID("$NetBSD: getpwent.c,v 1.67 2005/04/02 04:53:53 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -137,6 +137,7 @@ __RCSID("$NetBSD: getpwent.c,v 1.66 2005/02/28 00:40:05 lukem Exp $");
#ifdef __weak_alias
__weak_alias(endpwent,_endpwent)
__weak_alias(getpwent,_getpwent)
__weak_alias(getpwent_r,_getpwent_r)
__weak_alias(getpwnam,_getpwnam)
__weak_alias(getpwnam_r,_getpwnam_r)
__weak_alias(getpwuid,_getpwuid)
@ -564,6 +565,32 @@ _files_getpwent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_files_getpwent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct passwd *pw = va_arg(ap, struct passwd *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct passwd **result = va_arg(ap, struct passwd **);
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(pw != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
rv = _files_pwscan(retval, pw, buffer, buflen, &_files_state,
_PW_KEYBYNUM, NULL, 0);
if (rv == NS_SUCCESS)
*result = pw;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_files_getpwnam(void *nsrv, void *nscb, va_list ap)
@ -868,6 +895,71 @@ _dns_getpwent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_dns_getpwent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct passwd *pw = va_arg(ap, struct passwd *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct passwd **result = va_arg(ap, struct passwd **);
char **hp, *ep;
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(pw != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
*retval = 0;
if (_dns_state.num == -1) /* exhausted search */
return NS_NOTFOUND;
if (_dns_state.context == NULL) {
/* only start if Hesiod not setup */
rv = _dns_start(&_dns_state);
if (rv != NS_SUCCESS)
return rv;
}
next_dns_entry:
hp = NULL;
rv = NS_NOTFOUND;
/* find passwd-NNN */
snprintf(buffer, buflen, "passwd-%u", _dns_state.num);
_dns_state.num++;
hp = hesiod_resolve(_dns_state.context, buffer, "passwd");
if (hp == NULL) {
if (errno == ENOENT)
_dns_state.num = -1;
else
rv = NS_UNAVAIL;
} else {
if ((ep = strchr(hp[0], '\n')) != NULL)
*ep = '\0'; /* clear trailing \n */
/* validate line */
if (_pw_parse(hp[0], pw, buffer, buflen, 1))
rv = NS_SUCCESS;
else { /* dodgy entry, try again */
hesiod_free_list(_dns_state.context, hp);
goto next_dns_entry;
}
}
if (hp)
hesiod_free_list(_dns_state.context, hp);
if (rv == NS_SUCCESS)
*result = pw;
else
*result = NULL;
return rv;
}
static const char *_dns_uid_zones[] = {
"uid",
"passwd",
@ -1307,6 +1399,91 @@ _nis_getpwent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_nis_getpwent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct passwd *pw = va_arg(ap, struct passwd *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct passwd **result = va_arg(ap, struct passwd **);
char *key, *data;
int keylen, datalen, rv, nisr;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(pw != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
*retval = 0;
if (_nis_state.done) /* exhausted search */
return NS_NOTFOUND;
if (_nis_state.domain == NULL) {
/* only start if NIS not setup */
rv = _nis_start(&_nis_state);
if (rv != NS_SUCCESS)
return rv;
}
next_nis_entry:
key = NULL;
data = NULL;
rv = NS_NOTFOUND;
if (_nis_state.current) { /* already searching */
nisr = yp_next(_nis_state.domain, PASSWD_BYNAME(&_nis_state),
_nis_state.current, _nis_state.currentlen,
&key, &keylen, &data, &datalen);
free(_nis_state.current);
_nis_state.current = NULL;
switch (nisr) {
case 0:
_nis_state.current = key;
_nis_state.currentlen = keylen;
key = NULL;
break;
case YPERR_NOMORE:
_nis_state.done = 1;
goto nisent_out;
default:
rv = NS_UNAVAIL;
goto nisent_out;
}
} else { /* new search */
if (yp_first(_nis_state.domain, PASSWD_BYNAME(&_nis_state),
&_nis_state.current, &_nis_state.currentlen,
&data, &datalen)) {
rv = NS_UNAVAIL;
goto nisent_out;
}
}
data[datalen] = '\0'; /* clear trailing \n */
/* validate line */
if (_nis_parse(data, pw, buffer, buflen, &_nis_state))
rv = NS_SUCCESS;
else { /* dodgy entry, try again */
if (key)
free(key);
free(data);
goto next_nis_entry;
}
nisent_out:
if (key)
free(key);
if (data)
free(data);
if (rv == NS_SUCCESS)
*result = pw;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_nis_getpwuid(void *nsrv, void *nscb, va_list ap)
@ -1662,8 +1839,8 @@ _passwdcompat_pwscan(struct passwd *pw, char *buffer, size_t buflen,
{
static const ns_dtab compatentdtab[] = {
NS_FILES_CB(_passwdcompat_bad, "files")
NS_DNS_CB(_dns_getpwent, NULL)
NS_NIS_CB(_nis_getpwent, NULL)
NS_DNS_CB(_dns_getpwent_r, NULL)
NS_NIS_CB(_nis_getpwent_r, NULL)
NS_COMPAT_CB(_passwdcompat_bad, "compat")
{ 0 }
};
@ -1687,15 +1864,9 @@ _passwdcompat_pwscan(struct passwd *pw, char *buffer, size_t buflen,
switch (search) {
case _PW_KEYBYNUM:
/* XXXREENTRANT: implement & use getpwent_r */
rv = nsdispatch(NULL, compatentdtab,
NSDB_PASSWD_COMPAT, "getpwent", __nsdefaultnis,
&cpw);
if (rv == NS_SUCCESS &&
! _pw_copy(cpw, pw, buffer, buflen, NULL, 0)) {
errno = ERANGE;
rv = NS_UNAVAIL;
}
NSDB_PASSWD_COMPAT, "getpwent_r", __nsdefaultnis,
&crv, pw, buffer, buflen, &cpw);
break;
case _PW_KEYBYNAME:
_DIAGASSERT(name != NULL);
@ -2022,6 +2193,33 @@ _compat_getpwent(void *nsrv, void *nscb, va_list ap)
return rv;
}
/*ARGSUSED*/
static int
_compat_getpwent_r(void *nsrv, void *nscb, va_list ap)
{
int *retval = va_arg(ap, int *);
struct passwd *pw = va_arg(ap, struct passwd *);
char *buffer = va_arg(ap, char *);
size_t buflen = va_arg(ap, size_t);
struct passwd **result = va_arg(ap, struct passwd **);
int rv;
_DIAGASSERT(retval != NULL);
_DIAGASSERT(pw != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
rv = _compat_pwscan(retval, pw, buffer, buflen, &_compat_state,
_PW_KEYBYNUM, NULL, 0);
if (rv == NS_SUCCESS)
*result = pw;
else
*result = NULL;
return rv;
}
/*ARGSUSED*/
static int
_compat_getpwnam(void *nsrv, void *nscb, va_list ap)
@ -2158,6 +2356,34 @@ getpwent(void)
return (r == NS_SUCCESS) ? retval : NULL;
}
int
getpwent_r(struct passwd *pwd, char *buffer, size_t buflen,
struct passwd **result)
{
int r, retval;
static const ns_dtab dtab[] = {
NS_FILES_CB(_files_getpwent_r, NULL)
NS_DNS_CB(_dns_getpwent_r, NULL)
NS_NIS_CB(_nis_getpwent_r, NULL)
NS_COMPAT_CB(_compat_getpwent_r, NULL)
{ 0 }
};
_DIAGASSERT(pwd != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(result != NULL);
*result = NULL;
retval = 0;
mutex_lock(&_pwmutex);
r = nsdispatch(NULL, dtab, NSDB_PASSWD, "getpwent_r", __nsdefaultcompat,
&retval, pwd, buffer, buflen, result);
mutex_unlock(&_pwmutex);
return (r == NS_SUCCESS) ? 0 : retval ? retval : ENOENT;
}
struct passwd *
getpwnam(const char *name)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: namespace.h,v 1.98 2005/02/09 21:35:46 kleink Exp $ */
/* $NetBSD: namespace.h,v 1.99 2005/04/02 04:53:53 christos Exp $ */
/*-
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@ -225,6 +225,7 @@
#define getfsfile _getfsfile
#define getfsspec _getfsspec
#define getgrent _getgrent
#define getgrent_r _getgrent_r
#define getgrgid _getgrgid
#define getgrgid_r _getgrgid_r
#define getgrnam _getgrnam
@ -260,6 +261,7 @@
#define getprotoent _getprotoent
#define getprotoent_r _getprotoent_r
#define getpwent _getpwent
#define getpwent_r _getpwent_r
#define getpwnam _getpwnam
#define getpwnam_r _getpwnam_r
#define getpwuid _getpwuid

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.162 2005/03/18 11:23:44 kleink Exp $
# $NetBSD: shlib_version,v 1.163 2005/04/02 04:53:53 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@ -17,4 +17,4 @@
# - libc/net/getnet{ent,namadr}.c, netdb.h: remove __n_pad0
#
major=12
minor=127
minor=128