mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 19:30:10 +00:00
0a55a28475
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.
271 lines
6.0 KiB
C
271 lines
6.0 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;
|
|
}
|