glibc/hesiod/nss_hesiod/hesiod-grp.c
Ulrich Drepper 0a55a28475 Update.
2000-04-27  Ulrich Drepper  <drepper@redhat.com>

	* hesiod/nss_hesiod/hesiod-grp.c (_nss_hesiod_initgroups): Handle
	overflows in conversion from ASCII.

2000-04-26  Jakub Jelinek  <jakub@redhat.com>

	* Makeconfig (full_config_sysdirs): Renamed from full-config-sysdirs.
	* Makerules (full_config_sysdirs): Likewise.
	* MakeTAGS (full_config_sysdirs): Likewise.

2000-04-26  Jakub Jelinek  <jakub@redhat.com>

	* .cvsignore: Remove linuxthreads.
	* po/.cvsignore: Remove *.pot.
	* posix/glob/.cvsignore: Removed.
	* sysdeps/unix/bsd/osf/.cvsignore: Removed.

2000-04-25  Andreas Jaeger  <aj@suse.de>

	* conform/Makefile (distribute): Also distribute contents of
	subdirectories.

	* Makerules (no_deps): Remove abi-versions.h.

	* nis/nis_print_group_entry.c: Include alloca.h for alloca prototype.

2000-04-25  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/sparc/sparc64/elf/Dist: Remove.
	* sysdeps/sparc/sparc64/elf/crtbegin.S: Remove.
	* sysdeps/sparc/sparc64/elf/crtbeginS.S: Remove.
	* sysdeps/sparc/sparc64/elf/crtend.S: Remove.
	* sysdeps/sparc/sparc64/elf/crtendS.S: Remove.
	* sysdeps/sparc/sparc64/elf/Makefile: Don't build crtbegin/crtend
	objects.

2000-04-25  Thorsten Kukuk  <kukuk@suse.de>

	* nscd/grpcache.c: Fix gr_name pointer [PR/1702].

2000-04-23  Bruno Haible  <clisp.cons.org>

	* intl/dcigettext.c: Define _GNU_SOURCE as early as possible.
	* intl/l10nflist.c: Likewise.

2000-04-23  Bruno Haible  <clisp.cons.org>

	* intl/bindtextdom.c [!_LIBC]: Define __libc_rwlock_define,
	__libc_rwlock_wrlock, __libc_rwlock_unlock as empty.
	* intl/textdomain.c [!_LIBC]: Likewise.
	* intl/dcigettext.c [!_LIBC]: Define __libc_rwlock_define_initialized,
	__libc_rwlock_rdlock, __libc_rwlock_unlock as empty.
	* intl/loadmsgcat.c (_nl_load_domain) [!_LIBC, !HAVE_ICONV]: Avoid
	syntax error.

2000-04-23  Bruno Haible  <clisp.cons.org>

	* intl/dcigettext.c (_nl_find_msg): Do the plural treatment and
	character set conversion also in the case the translation was found
	after a hash collision or through binary search. Store the maximum
	index together with the converted message. Use iconv() when available.
	In case of out of memory during conversion, return the unconverted
	translated string, not NULL.
2000-04-28 05:12:30 +00:00

271 lines
6 KiB
C

/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <hesiod.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <nss.h>
#include <bits/libc-lock.h>
/* Get the declaration of the parser function. */
#define ENTNAME grent
#define STRUCTURE group
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
/* Locks the static variables in this file. */
__libc_lock_define_initialized (static, lock);
static void *context = NULL;
static enum nss_status
internal_setgrent (void)
{
if (!context)
{
if (hesiod_init (&context) == -1)
return NSS_STATUS_UNAVAIL;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_hesiod_setgrent (void)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_setgrent ();
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_hesiod_endgrent (void)
{
__libc_lock_lock (lock);
if (context)
{
hesiod_end (context);
context = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
lookup (const char *name, const char *type, struct group *grp,
char *buffer, size_t buflen, int *errnop)
{
enum nss_status status;
struct parser_data *data = (void *) buffer;
size_t linebuflen;
char **list;
int parse_res;
size_t len;
status = internal_setgrent ();
if (status != NSS_STATUS_SUCCESS)
return status;
list = hesiod_resolve (context, name, type);
if (list == NULL)
return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
linebuflen = buffer + buflen - data->linebuffer;
len = strlen (*list) + 1;
if (linebuflen < len)
{
hesiod_free_list (context, list);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
memcpy (data->linebuffer, *list, len);
hesiod_free_list (context, list);
parse_res = _nss_files_parse_grent (buffer, grp, data, buflen, errnop);
if (parse_res < 1)
return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_hesiod_getgrnam_r (const char *name, struct group *grp,
char *buffer, size_t buflen, int *errnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = lookup (name, "group", grp, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_hesiod_getgrgid_r (gid_t gid, struct group *grp,
char *buffer, size_t buflen, int *errnop)
{
enum nss_status status = NSS_STATUS_UNAVAIL;
char gidstr[21]; /* We will probably never have a gid_t with more
than 64 bits. */
snprintf (gidstr, sizeof gidstr, "%d", gid);
__libc_lock_lock (lock);
status = lookup (gidstr, "gid", grp, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
static int
internal_gid_in_list (const gid_t *list, const gid_t g, long int len)
{
while (len > 0)
{
if (*list == g)
return 1;
--len;
++list;
}
return 0;
}
static enum nss_status
internal_gid_from_group (void *context, const char *groupname, gid_t *group)
{
char **grp_res;
enum nss_status status = NSS_STATUS_NOTFOUND;
grp_res = hesiod_resolve (context, groupname, "group");
if (grp_res != NULL && *grp_res != NULL)
{
char *p = *grp_res;
while (*p != '\0' && *p != ':')
++p;
while (*p != '\0' && *p == ':')
++p;
while (*p != '\0' && *p != ':')
++p;
while (*p != '\0' && *p == ':')
++p;
if (*p == ':')
{
char *endp;
char *q = ++p;
long int val;
q = p;
while (*q != '\0' && *q != ':')
++q;
val = strtol (p, &endp, 10);
if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
{
*group = val;
if (endp == q && endp != p)
status = NSS_STATUS_SUCCESS;
}
}
hesiod_free_list (context, grp_res);
}
return status;
}
enum nss_status
_nss_hesiod_initgroups (const char *user, gid_t group, long int *start,
long int *size, gid_t *groups, long int limit,
int *errnop)
{
enum nss_status status = NSS_STATUS_SUCCESS;
char **list = NULL;
char *p;
void *context;
if (hesiod_init (&context) == -1)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, user, "grplist");
if (list == NULL)
{
hesiod_end (context);
return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
}
if (!internal_gid_in_list (groups, group, *start) && *start < limit)
groups[(*start)++] = group;
p = *list;
while (*p != '\0' && *start < limit)
{
char *endp;
char *q;
long int val;
status = NSS_STATUS_NOTFOUND;
q = p;
while (*q != '\0' && *q != ':')
++q;
if (*q != '\0')
*q++ = '\0';
val = strtol (p, &endp, 10);
if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
{
if (*endp == '\0' && endp != p)
status = NSS_STATUS_SUCCESS;
else
status = internal_gid_from_group (context, p, &group);
if (status == NSS_STATUS_SUCCESS
&& !internal_gid_in_list (groups, group, *start))
groups[(*start)++] = group;
}
p = q;
}
hesiod_free_list (context, list);
hesiod_end (context);
return NSS_STATUS_SUCCESS;
}