mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-19 19:40:06 +00:00
2303f5fdd9
Sun Nov 10 02:37:15 1996 Ulrich Drepper <drepper@cygnus.com> * inet/gethstent_r.c: Update copyright. * nss/getXXbyYY_r.c: Likewise. * nss/nsswitch.c: Likewise. * nss/getXXent_r.c: Likewise. * nss/nss_files/files-XXX.c: Likewise. * nss/nss_files/files-netgroup.c: Likewise. * nss/nss_files/files-parse.c: Likewise. * nss/getXXent_r.c: Change implementation. It's not necessary to call all setXXent functions. Just find first available and when necessary let getXXent_r call the others. * nss/nss_files/files-XXX.c: Make really reentrant. Now calls of getXXent and getXXbyYY can be mixed. The cursor for traversing the database with getXXent will be remembered. * stdlib/test-canon.c (cwd): Change size to PATH_MAX. Sat Nov 9 15:34:48 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/Dist: Add sys/mtio.h. * sysdeps/unix/sysv/linux/sys/mtio.h: New file. * signal/signal.h [__USE_BSD]: Add prototype for siggetmask. Fri Nov 8 13:29:30 1996 Ulrich Drepper <drepper@cygnus.com> * ctype/ctype.h (__isascii): Don't test for seventh bit not to be set. Instead for none beside the first seven bits to be set. X/Open allows the argument to be an `int' value. Reported by Alain Williams <addw@phcomp.co.uk>. (toascii, isascii): Define macro also when __USE_XOPEN. * sysdeps/posix/fpathconf.c: Use fstatfs to compute NAME_MAX, not PATH_MAX. Thu Nov 7 03:04:29 1996 Ulrich Drepper <drepper@cygnus.com> * nss/getXXXent_r.c (SETFUNC_NAME): Reset `nip' after loop to NULL so that GETFUNC will see first entry. (ENDFUNC_NAME): Likewise. Rewrite Netgroups implementation to avoid global data. * inet/netgroup.h: Add definition of name_list and struct __netgrent. Add prototypes for internal netgroup functions. * nss/nss_files/files-netgroup.c (_nss_files_setnetgrent): Take extra argument and use the included data instead of global vars. (_nss_files_endnetgrent): Likewise. (_nss_netgroup_parseline): Change to be static and use data included in the RESULT structure. * inet/getnetgrent_r.c (startp): Move into setup function. (known_groups, needed_groups): new part of the __netgrent sruct. (freememory): Take extra argument and use included data. (__internal_endnetgrent): Likewise. (internal_setnetgrent): Renamed to __internal_setnetgrent_reuse and take extra argument. (__internal_setnetgrent): New function. Call __internal_setnetgrent_reuse after calling free_memory. (setnetgrent): Only call __internal_setnetgrent. (__getnetgrent_r): Split into two functions. __getnetgrent_r calls __internal_getnetgrent after locking. (innetgr): Use dynamic data only. I.e., innetgr now is fully reentrant. Thu Nov 7 00:15:14 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/stub/setenv.c: Correct typo: unseenv -> unsetenv. Reported by Joshua Cowan <jcowan@jcowan.reslife.okstate.edu>. Wed Nov 6 13:13:37 1996 Ulrich Drepper <drepper@cygnus.com> * manual/creature.texi: Document that _GNU_SOURCE is no longer the default when no *_SOURCE macro is given. Reported by Karsten Weiss <karsten@addx.au.s.shuttle.de>. * NOTES: remade from manual/creature.texi. * manual/libc.texinfo: Add back line about GPL translation which somehow got lost. * Make-dist (dist.tar): Depend on README being updated. * rellns-sh: Correct thinko in removing leading /. Reported by Andreas Jaeger <aj@arthur.pfalz.de>. * pwd/fgetpwent_r.c: Recognize lines containing only names starting with `+' or `-' in parser. * grp/fgetgrent_r.c: Likewise. * shadow/sgetspent_r.c: Likewise. * nss/nss_files/files-spwd.c: Don't accept entries starting with `+' or `-'. * sysdeps/stub/lchown.c: New file.
270 lines
6.6 KiB
C
270 lines
6.6 KiB
C
/* Netgroup file parser in nss_files modules.
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
|
|
|
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 <netdb.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "nsswitch.h"
|
|
#include "netgroup.h"
|
|
|
|
#define DATAFILE "/etc/netgroup"
|
|
|
|
|
|
#define EXPAND(needed) \
|
|
do \
|
|
{ \
|
|
size_t old_cursor = result->cursor - result->data; \
|
|
\
|
|
result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \
|
|
result->data = realloc (result->data, result->data_size); \
|
|
\
|
|
if (result->data == NULL) \
|
|
{ \
|
|
status = NSS_STATUS_UNAVAIL; \
|
|
goto the_end; \
|
|
} \
|
|
\
|
|
result->cursor = result->data + old_cursor; \
|
|
} \
|
|
while (0)
|
|
|
|
|
|
enum nss_status
|
|
_nss_files_setnetgrent (const char *group, struct __netgrent *result)
|
|
{
|
|
FILE *fp;
|
|
enum nss_status status;
|
|
|
|
if (group[0] == '\0')
|
|
return NSS_STATUS_UNAVAIL;
|
|
|
|
/* Find the netgroups file and open it. */
|
|
fp = fopen (DATAFILE, "r");
|
|
if (fp == NULL)
|
|
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
|
else
|
|
{
|
|
/* Read the file line by line and try to find the description
|
|
GROUP. We must take care for long lines. */
|
|
char *line = NULL;
|
|
size_t line_len = 0;
|
|
const ssize_t group_len = strlen (group);
|
|
|
|
status = NSS_STATUS_NOTFOUND;
|
|
result->cursor = result->data;
|
|
|
|
while (!feof (fp))
|
|
{
|
|
ssize_t curlen = getline (&line, &line_len, fp);
|
|
int found;
|
|
|
|
if (curlen < 0)
|
|
{
|
|
status = NSS_STATUS_NOTFOUND;
|
|
break;
|
|
}
|
|
|
|
found = (curlen > group_len && strncmp (line, group, group_len) == 0
|
|
&& isspace (line[group_len]));
|
|
|
|
/* Read the whole line (including continuation) and store it
|
|
if FOUND in nonzero. Otherwise we don't need it. */
|
|
if (found)
|
|
{
|
|
/* Store the data from the first line. */
|
|
EXPAND (curlen - group_len);
|
|
memcpy (result->cursor, &line[group_len + 1],
|
|
curlen - group_len);
|
|
result->cursor += (curlen - group_len) - 1;
|
|
}
|
|
|
|
while (line[curlen - 1] == '\n' && line[curlen - 2] == '\\')
|
|
{
|
|
/* Yes, we have a continuation line. */
|
|
if (found)
|
|
/* Remove these characters from the stored line. */
|
|
result->cursor -= 2;
|
|
|
|
/* Get netxt line. */
|
|
curlen = getline (&line, &line_len, fp);
|
|
if (curlen <= 0)
|
|
break;
|
|
|
|
if (found)
|
|
{
|
|
/* Make sure we have enough room. */
|
|
EXPAND (1 + curlen + 1);
|
|
|
|
/* Add separator in case next line starts immediately. */
|
|
*result->cursor++ = ' ';
|
|
|
|
/* Copy new line. */
|
|
memcpy (result->cursor, line, curlen + 1);
|
|
result->cursor += curlen;
|
|
}
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
/* Now we have read the line. */
|
|
status = NSS_STATUS_SUCCESS;
|
|
result->cursor = result->data;
|
|
result->first = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
the_end:
|
|
/* We don't need the file and the line buffer anymore. */
|
|
free (line);
|
|
fclose (fp);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
int
|
|
_nss_files_endnetgrent (struct __netgrent *result)
|
|
{
|
|
/* Free allocated memory for data if some is present. */
|
|
if (result->data != NULL)
|
|
{
|
|
free (result->data);
|
|
result->data = NULL;
|
|
result->data_size = 0;
|
|
result->cursor = NULL;
|
|
}
|
|
|
|
return NSS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static enum nss_status
|
|
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
|
|
char *buffer, int buflen)
|
|
{
|
|
enum nss_status status;
|
|
const char *host, *user, *domain;
|
|
char *cp = *cursor;
|
|
|
|
/* Some sanity checks. */
|
|
if (cp == NULL)
|
|
/* User bug. setnetgrent() wasn't called before. */
|
|
abort ();
|
|
|
|
/* First skip leading spaces. */
|
|
while (isspace (*cp))
|
|
++cp;
|
|
|
|
if (*cp != '(')
|
|
{
|
|
/* We have a list of other netgroups. */
|
|
char *name = cp;
|
|
|
|
while (*cp != '\0' && ! isspace (*cp))
|
|
++cp;
|
|
|
|
if (name != cp)
|
|
{
|
|
/* It is another netgroup name. */
|
|
int last = *cp == '\0';
|
|
|
|
result->type = group_val;
|
|
result->val.group = name;
|
|
*cp = '\0';
|
|
if (! last)
|
|
++cp;
|
|
*cursor = cp;
|
|
result->first = 0;
|
|
|
|
return NSS_STATUS_SUCCESS;
|
|
}
|
|
|
|
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
|
}
|
|
|
|
/* Match host name. */
|
|
host = ++cp;
|
|
while (*cp != ',')
|
|
if (*cp++ == '\0')
|
|
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
|
|
|
/* Match user name. */
|
|
user = ++cp;
|
|
while (*cp != ',')
|
|
if (*cp++ == '\0')
|
|
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
|
|
|
/* Match domain name. */
|
|
domain = ++cp;
|
|
while (*cp != ')')
|
|
if (*cp++ == '\0')
|
|
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
|
++cp;
|
|
|
|
|
|
/* When we got here we have found an entry. Before we can copy it
|
|
to the private buffer we have to make sure it is big enough. */
|
|
if (cp - host > buflen)
|
|
{
|
|
__set_errno (ERANGE);
|
|
status = NSS_STATUS_UNAVAIL;
|
|
}
|
|
else
|
|
{
|
|
memcpy (buffer, host, cp - host);
|
|
result->type = triple_val;
|
|
|
|
buffer[(user - host) - 1] = '\0';
|
|
result->val.triple.host = *host == ',' ? NULL : buffer;
|
|
|
|
buffer[(domain - host) - 1] = '\0';
|
|
result->val.triple.user = *user == ',' ? NULL : buffer + (user - host);
|
|
|
|
buffer[(cp - host) - 1] = '\0';
|
|
result->val.triple.domain =
|
|
*domain == ')' ? NULL : buffer + (domain - host);
|
|
|
|
status = NSS_STATUS_SUCCESS;
|
|
|
|
/* Rememember where we stopped reading. */
|
|
*cursor = cp;
|
|
|
|
result->first = 0;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
enum nss_status
|
|
_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
|
|
{
|
|
enum nss_status status;
|
|
|
|
status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen);
|
|
|
|
return status;
|
|
}
|