2009-04-23  Ulrich Drepper  <drepper@redhat.com>
	[BZ #9955]
	* gshadow/Makefile: New file.
	* gshadow/Versions: New file.
	* gshadow/fgetsgent.c: New file.
	* gshadow/fgetsgent_r.c: New file.
	* gshadow/getsgent.c: New file.
	* gshadow/getsgent_r.c: New file.
	* gshadow/getsgnam.c: New file.
	* gshadow/getsgnam_r.c: New file.
	* gshadow/gshadow.h: New file.
	* gshadow/putsgent.c: New file.
	* gshadow/sgetsgent.c: New file.
	* gshadow/sgetsgent_r.c: New file.
	* gshadow/tst-gshadow.c: New file.
	* include/gshadow.h: New file.
	* Makeconfig (all-subdirs): Add gshadow.
	* Makefile (installed-headers): Add gshadow/gshadow.h.
	* nss/Makefile (databases): Add sgrp.
	* nss/Versions: Add gshadow functions as private exports.
	* nss/nsswitch.conf: Add gshadow entry.
	* nss/sgrp-lookup.c: New file.
	* nss/nss_files/files-parse.c: Add STRING_LIST macro.  Rewrite
	parse_list to handle STRING_LIST and TRAILING_LIST_PARSER.
	* nss/nss_files/files-sgrp.c: New file.
	* sysdeps/generic/paths.h: Add _PATH_GSHADOW.
	* sysdeps/unix/sysv/linux/paths.h: Likewise.
This commit is contained in:
Ulrich Drepper 2009-04-23 18:29:30 +00:00
parent 5497de87c9
commit 829fea4617
25 changed files with 1017 additions and 24 deletions

View File

@ -1,3 +1,32 @@
2009-04-23 Ulrich Drepper <drepper@redhat.com>
[BZ #9955]
* gshadow/Makefile: New file.
* gshadow/Versions: New file.
* gshadow/fgetsgent.c: New file.
* gshadow/fgetsgent_r.c: New file.
* gshadow/getsgent.c: New file.
* gshadow/getsgent_r.c: New file.
* gshadow/getsgnam.c: New file.
* gshadow/getsgnam_r.c: New file.
* gshadow/gshadow.h: New file.
* gshadow/putsgent.c: New file.
* gshadow/sgetsgent.c: New file.
* gshadow/sgetsgent_r.c: New file.
* gshadow/tst-gshadow.c: New file.
* include/gshadow.h: New file.
* Makeconfig (all-subdirs): Add gshadow.
* Makefile (installed-headers): Add gshadow/gshadow.h.
* nss/Makefile (databases): Add sgrp.
* nss/Versions: Add gshadow functions as private exports.
* nss/nsswitch.conf: Add gshadow entry.
* nss/sgrp-lookup.c: New file.
* nss/nss_files/files-parse.c: Add STRING_LIST macro. Rewrite
parse_list to handle STRING_LIST and TRAILING_LIST_PARSER.
* nss/nss_files/files-sgrp.c: New file.
* sysdeps/generic/paths.h: Add _PATH_GSHADOW.
* sysdeps/unix/sysv/linux/paths.h: Likewise.
2009-04-22 Ulrich Drepper <drepper@redhat.com>
* stdio-common/printf.h: Add missing const to register_printf_modifier.

View File

@ -918,7 +918,7 @@ endif
all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
stdlib stdio-common libio malloc string wcsmbs time dirent \
grp pwd posix io termios resource misc socket sysvipc gmon \
gnulib iconv iconvdata wctype manual shadow po argp \
gnulib iconv iconvdata wctype manual shadow gshadow po argp \
crypt nss localedata timezone rt conform debug \
$(add-on-subdirs) $(dlfcn) $(binfmt-subdir)

View File

@ -271,7 +271,7 @@ installed-headers = argp/argp.h assert/assert.h catgets/nl_types.h \
crypt/crypt.h ctype/ctype.h debug/execinfo.h \
dirent/dirent.h dlfcn/dlfcn.h elf/elf.h elf/link.h \
gmon/sys/gmon.h gmon/sys/gmon_out.h gmon/sys/profil.h \
grp/grp.h iconv/iconv.h iconv/gconv.h \
grp/grp.h gshadow/gshadow.h iconv/iconv.h iconv/gconv.h \
$(wildcard inet/netinet/*.h) \
$(wildcard inet/arpa/*.h inet/protocols/*.h) \
inet/aliases.h inet/ifaddrs.h inet/netinet/ip6.h \

38
gshadow/Makefile Normal file
View File

@ -0,0 +1,38 @@
# Copyright (C) 2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA.
#
# Makefile for gshadow.
#
subdir := gshadow
headers = gshadow.h
routines = getsgent getsgnam sgetsgent fgetsgent putsgent \
getsgent_r getsgnam_r sgetsgent_r fgetsgent_r
tests = tst-gshadow
CFLAGS-getsgent_r.c = -fexceptions
CFLAGS-getsgent.c = -fexceptions
CFLAGS-fgetsgent.c = -fexceptions
CFLAGS-fgetsgent_r.c = -fexceptions -D_IO_MTSAFE_IO
CFLAGS-putsgent.c = -fexceptions -D_IO_MTSAFE_IO
CFLAGS-getsgnam.c = -fexceptions
CFLAGS-getsgnam_r.c = -fexceptions
include ../Rules

21
gshadow/Versions Normal file
View File

@ -0,0 +1,21 @@
libc {
GLIBC_2.10 {
# e*
endsgent;
# f*
fgetsgent; fgetsgent_r;
# g*
getsgent; getsgent_r; getsgnam; getsgnam_r; getsgent_r; getsgnam_r;
# p*
putsgent;
# s*
setsgent;
# s*
sgetsgent; sgetsgent_r;
}
}

88
gshadow/fgetsgent.c Normal file
View File

@ -0,0 +1,88 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <bits/libc-lock.h>
#include <gshadow.h>
#include <stdio.h>
#include <stdlib.h>
/* A reasonable size for a buffer to start with. */
#define BUFLEN_SPWD 1024
/* We need to protect the dynamic buffer handling. */
__libc_lock_define_initialized (static, lock);
libc_freeres_ptr (static char *buffer);
/* Read one shadow entry from the given stream. */
struct sgrp *
fgetsgent (FILE *stream)
{
static size_t buffer_size;
static struct sgrp resbuf;
fpos_t pos;
struct sgrp *result;
int save;
if (fgetpos (stream, &pos) != 0)
return NULL;
/* Get lock. */
__libc_lock_lock (lock);
/* Allocate buffer if not yet available. */
if (buffer == NULL)
{
buffer_size = BUFLEN_SPWD;
buffer = malloc (buffer_size);
}
while (buffer != NULL
&& (__fgetsgent_r (stream, &resbuf, buffer, buffer_size, &result)
== ERANGE))
{
char *new_buf;
buffer_size += BUFLEN_SPWD;
new_buf = realloc (buffer, buffer_size);
if (new_buf == NULL)
{
/* We are out of memory. Free the current buffer so that the
process gets a chance for a normal termination. */
save = errno;
free (buffer);
__set_errno (save);
}
buffer = new_buf;
/* Reset the stream. */
if (fsetpos (stream, &pos) != 0)
buffer = NULL;
}
if (buffer == NULL)
result = NULL;
/* Release lock. Preserve error value. */
save = errno;
__libc_lock_unlock (lock);
__set_errno (save);
return result;
}

76
gshadow/fgetsgent_r.c Normal file
View File

@ -0,0 +1,76 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; 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 <gshadow.h>
#include <stdio.h>
/* Define a line parsing function using the common code
used in the nss_files module. */
#define STRUCTURE sgrp
#define ENTNAME sgent
#define EXTERN_PARSER 1
struct sgent_data {};
#include <nss/nss_files/files-parse.c>
/* Read one shadow entry from the given stream. */
int
__fgetsgent_r (FILE *stream, struct sgrp *resbuf, char *buffer, size_t buflen,
struct sgrp **result)
{
char *p;
_IO_flockfile (stream);
do
{
buffer[buflen - 1] = '\xff';
p = fgets_unlocked (buffer, buflen, stream);
if (p == NULL && feof_unlocked (stream))
{
_IO_funlockfile (stream);
*result = NULL;
__set_errno (ENOENT);
return errno;
}
if (p == NULL || buffer[buflen - 1] != '\xff')
{
_IO_funlockfile (stream);
*result = NULL;
__set_errno (ERANGE);
return errno;
}
/* Skip leading blanks. */
while (isspace (*p))
++p;
} while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
/* Parse the line. If it is invalid, loop to
get the next line of the file to parse. */
! parse_line (buffer, (void *) resbuf, (void *) buffer, buflen,
&errno));
_IO_funlockfile (stream);
*result = resbuf;
return 0;
}
weak_alias (__fgetsgent_r, fgetsgent_r)

30
gshadow/getsgent.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <gshadow.h>
#define LOOKUP_TYPE struct sgrp
#define SETFUNC_NAME setsgent
#define GETFUNC_NAME getsgent
#define ENDFUNC_NAME endsgent
#define DATABASE_NAME gshadow
#define BUFLEN 1024
#include "../nss/getXXent.c"

30
gshadow/getsgent_r.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <gshadow.h>
#define LOOKUP_TYPE struct sgrp
#define SETFUNC_NAME setsgent
#define GETFUNC_NAME getsgent
#define ENDFUNC_NAME endsgent
#define DATABASE_NAME gshadow
#define BUFLEN 1024
#include "../nss/getXXent_r.c"

30
gshadow/getsgnam.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <gshadow.h>
#define LOOKUP_TYPE struct sgrp
#define FUNCTION_NAME getsgnam
#define DATABASE_NAME gshadow
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
#define BUFLEN 1024
#include "../nss/getXXbyYY.c"

30
gshadow/getsgnam_r.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <gshadow.h>
#define LOOKUP_TYPE struct sgrp
#define FUNCTION_NAME getsgnam
#define DATABASE_NAME gshadow
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
#define BUFLEN 1024
#include "../nss/getXXbyYY_r.c"

131
gshadow/gshadow.h Normal file
View File

@ -0,0 +1,131 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Declaration of types and functions for shadow group suite. */
#ifndef _GSHADOW_H
#define _GSHADOW_H 1
#include <features.h>
#include <paths.h>
#define __need_FILE
#include <stdio.h>
#define __need_size_t
#include <stddef.h>
/* Path to the user database files. */
#define GSHADOW _PATH_GSHADOW
__BEGIN_DECLS
/* Structure of the group file. */
struct sgrp
{
char *sg_namp; /* Group name. */
char *sg_passwd; /* Encrypted password. */
char **sg_adm; /* Group administrator list. */
char **sg_mem; /* Group member list. */
};
/* Open database for reading.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern void setsgent (void);
/* Close database.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern void endsgent (void);
/* Get next entry from database, perhaps after opening the file.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern struct sgrp *getsgent (void);
/* Get shadow entry matching NAME.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern struct sgrp *getsgnam (__const char *__name);
/* Read shadow entry from STRING.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern struct sgrp *sgetsgent (__const char *__string);
/* Read next shadow entry from STREAM.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern struct sgrp *fgetsgent (FILE *__stream);
/* Write line containing shadow password entry to stream.
This function is not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation it is a cancellation point and
therefore not marked with __THROW. */
extern int putsgent (__const struct sgrp *__g, FILE *__stream);
#ifdef __USE_MISC
/* Reentrant versions of some of the functions above.
These functions are not part of POSIX and therefore no official
cancellation point. But due to similarity with an POSIX interface
or due to the implementation they are cancellation points and
therefore not marked with __THROW. */
extern int getsgent_r (struct sgrp *__result_buf, char *__buffer,
size_t __buflen, struct sgrp **__result);
extern int getsgnam_r (__const char *__name, struct sgrp *__result_buf,
char *__buffer, size_t __buflen,
struct sgrp **__result);
extern int sgetsgent_r (__const char *__string, struct sgrp *__result_buf,
char *__buffer, size_t __buflen,
struct sgrp **__result);
extern int fgetsgent_r (FILE *__stream, struct sgrp *__result_buf,
char *__buffer, size_t __buflen,
struct sgrp **__result);
#endif /* misc */
__END_DECLS
#endif /* gshadow.h */

71
gshadow/putsgent.c Normal file
View File

@ -0,0 +1,71 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdbool.h>
#include <stdio.h>
#include <gshadow.h>
#define _S(x) x ? x : ""
/* Write an entry to the given stream.
This must know the format of the group file. */
int
putsgent (const struct sgrp *g, FILE *stream)
{
int errors = 0;
_IO_flockfile (stream);
if (fprintf (stream, "%s:%s:", g->sg_namp, _S (g->sg_passwd)) < 0)
++errors;
bool first = true;
char **sp = g->sg_adm;
if (sp != NULL)
while (*sp != NULL)
{
if (fprintf (stream, "%s%s", first ? "" : ",", *sp++) < 0)
{
++errors;
break;
}
first = false;
}
if (putc_unlocked (':', stream) == EOF)
++errors;
first = true;
sp = g->sg_mem;
if (sp != NULL)
while (*sp != NULL)
{
if (fprintf (stream, "%s%s", first ? "" : ",", *sp++) < 0)
{
++errors;
break;
}
first = false;
}
if (putc_unlocked ('\n', stream) == EOF)
++errors;
_IO_funlockfile (stream);
return errors ? -1 : 0;
}

78
gshadow/sgetsgent.c Normal file
View File

@ -0,0 +1,78 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <bits/libc-lock.h>
#include <gshadow.h>
#include <stdlib.h>
/* A reasonable size for a buffer to start with. */
#define BUFLEN_SPWD 1024
/* We need to protect the dynamic buffer handling. */
__libc_lock_define_initialized (static, lock);
/* Read one shadow entry from the given stream. */
struct sgrp *
sgetsgent (const char *string)
{
static char *buffer;
static size_t buffer_size;
static struct sgrp resbuf;
struct sgrp *result;
int save;
/* Get lock. */
__libc_lock_lock (lock);
/* Allocate buffer if not yet available. */
if (buffer == NULL)
{
buffer_size = BUFLEN_SPWD;
buffer = malloc (buffer_size);
}
while (buffer != NULL
&& __sgetsgent_r (string, &resbuf, buffer, buffer_size, &result) != 0
&& errno == ERANGE)
{
char *new_buf;
buffer_size += BUFLEN_SPWD;
new_buf = realloc (buffer, buffer_size);
if (new_buf == NULL)
{
/* We are out of memory. Free the current buffer so that the
process gets a chance for a normal termination. */
save = errno;
free (buffer);
__set_errno (save);
}
buffer = new_buf;
}
if (buffer == NULL)
result = NULL;
/* Release lock. Preserve error value. */
save = errno;
__libc_lock_unlock (lock);
__set_errno (save);
return result;
}

70
gshadow/sgetsgent_r.c Normal file
View File

@ -0,0 +1,70 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; 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 <gshadow.h>
#include <stdio.h>
#include <string.h>
/* Define a line parsing function using the common code
used in the nss_files module. */
#define STRUCTURE sgrp
#define ENTNAME sgent
struct sgent_data {};
#define TRAILING_LIST_MEMBER sg_mem
#define TRAILING_LIST_SEPARATOR_P(c) ((c) == ',')
#include <nss/nss_files/files-parse.c>
LINE_PARSER
(,
STRING_FIELD (result->sg_namp, ISCOLON, 0);
if (line[0] == '\0'
&& (result->sg_namp[0] == '+' || result->sg_namp[0] == '-'))
{
result->sg_passwd = NULL;
result->sg_adm = NULL;
result->sg_mem = NULL;
}
else
{
STRING_FIELD (result->sg_passwd, ISCOLON, 0);
STRING_LIST (result->sg_adm, ':');
}
)
/* Read one shadow entry from the given stream. */
int
__sgetsgent_r (const char *string, struct sgrp *resbuf, char *buffer,
size_t buflen, struct sgrp **result)
{
char *sp;
if (string < buffer || string >= buffer + buflen)
sp = strncpy (buffer, string, buflen);
else
sp = (char *) string;
int parse_result = parse_line (sp, resbuf, (void *) buffer, buflen, &errno);
*result = parse_result > 0 ? resbuf : NULL;
return *result == NULL ? errno : 0;
}
weak_alias (__sgetsgent_r, sgetsgent_r)

138
gshadow/tst-gshadow.c Normal file
View File

@ -0,0 +1,138 @@
#include <gshadow.h>
#include <stdio.h>
#include <string.h>
static const struct sgrp data[] =
{
{ (char *) "one", (char *) "pwdone",
(char *[]) { (char *) "admoneone", (char *) "admonetwo",
(char *) "admonethree", NULL },
(char *[]) { (char *) "memoneone", (char *) "memonetwo",
(char *) "memonethree", NULL } },
{ (char *) "two", (char *) "pwdtwo",
(char *[]) { (char *) "admtwoone", (char *) "admtwotwo", NULL },
(char *[]) { (char *) "memtwoone", (char *) "memtwotwo",
(char *) "memtwothree", NULL } },
{ (char *) "three", (char *) "pwdthree",
(char *[]) { (char *) "admthreeone", (char *) "admthreetwo", NULL },
(char *[]) { (char *) "memthreeone", (char *) "memthreetwo", NULL } },
{ (char *) "four", (char *) "pwdfour",
(char *[]) { (char *) "admfourone", (char *) "admfourtwo", NULL },
(char *[]) { NULL } },
{ (char *) "five", (char *) "pwdfive",
(char *[]) { NULL },
(char *[]) { (char *) "memfiveone", (char *) "memfivetwo", NULL } },
};
#define ndata (sizeof (data) / sizeof (data[0]))
int
main (void)
{
FILE *fp = fopen ("/tmp/aaa", "w+");//tmpfile ();
if (fp == NULL)
{
puts ("cannot open temporary file");
return 1;
}
for (size_t i = 0; i < ndata; ++i)
if (putsgent (&data[i], fp) != 0)
{
printf ("putsgent call %zu failed\n", i + 1);
return 1;
}
rewind (fp);
int result = 0;
int seen = -1;
struct sgrp *g;
while ((g = fgetsgent (fp)) != NULL)
{
++seen;
if (strcmp (g->sg_namp, data[seen].sg_namp) != 0)
{
printf ("sg_namp of entry %d does not match: %s vs %s\n",
seen + 1, g->sg_namp, data[seen].sg_namp);
result = 1;
}
if (strcmp (g->sg_passwd, data[seen].sg_passwd) != 0)
{
printf ("sg_passwd of entry %d does not match: %s vs %s\n",
seen + 1, g->sg_passwd, data[seen].sg_passwd);
result = 1;
}
if (g->sg_adm == NULL)
{
printf ("sg_adm of entry %d is NULL\n", seen + 1);
result = 1;
}
else
{
int i = 1;
char **sp1 = g->sg_adm;
char **sp2 = data[seen].sg_adm;
while (*sp1 != NULL && *sp2 != NULL)
{
if (strcmp (*sp1, *sp2) != 0)
{
printf ("sg_adm[%d] of entry %d does not match: %s vs %s\n",
i, seen + 1, *sp1, *sp2);
result = 1;
}
++sp1;
++sp2;
++i;
}
if (*sp1 == NULL && *sp2 != NULL)
{
printf ("sg_adm of entry %d has too few entries\n", seen + 1);
result = 1;
}
else if (*sp1 != NULL && *sp2 == NULL)
{
printf ("sg_adm of entry %d has too many entries\n", seen + 1);
result = 1;
}
}
if (g->sg_mem == NULL)
{
printf ("sg_mem of entry %d is NULL\n", seen + 1);
result = 1;
}
else
{
int i = 1;
char **sp1 = g->sg_mem;
char **sp2 = data[seen].sg_mem;
while (*sp1 != NULL && *sp2 != NULL)
{
if (strcmp (*sp1, *sp2) != 0)
{
printf ("sg_mem[%d] of entry %d does not match: %s vs %s\n",
i, seen + 1, *sp1, *sp2);
result = 1;
}
++sp1;
++sp2;
++i;
}
if (*sp1 == NULL && *sp2 != NULL)
{
printf ("sg_mem of entry %d has too few entries\n", seen + 1);
result = 1;
}
else if (*sp1 != NULL && *sp2 == NULL)
{
printf ("sg_mem of entry %d has too many entries\n", seen + 1);
result = 1;
}
}
}
fclose (fp);
return result;
}

15
include/gshadow.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _GSHADOW_H
#include <gshadow/gshadow.h>
extern int __fgetsgent_r (FILE *stream, struct sgrp *resbuf, char *buffer,
size_t buflen, struct sgrp **result);
extern int __sgetsgent_r (const char *string, struct sgrp *resbuf,
char *buffer, size_t buflen, struct sgrp **result);
struct parser_data;
extern int _nss_files_parse_sgent (char *line, struct sgrp *result,
struct parser_data *data,
size_t datalen, int *errnop);
libc_hidden_proto (_nss_files_parse_sgent)
#endif

View File

@ -1,4 +1,4 @@
# Copyright (C) 1996-1998,2000,2001,2002,2007 Free Software Foundation, Inc.
# Copyright (C) 1996-1998,2000-2002,2007,2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@ -34,7 +34,7 @@ routines = nsswitch getnssent getnssent_r digits_dots \
# Caution: if you add a database here, you must add its real name
# in databases.def, too.
databases = proto service hosts network grp pwd rpc ethers \
spwd netgrp key alias
spwd netgrp key alias sgrp
others := getent
install-bin := getent

View File

@ -9,7 +9,7 @@ libc {
}
GLIBC_PRIVATE {
_nss_files_parse_grent; _nss_files_parse_pwent; _nss_files_parse_spent;
__nss_disable_nscd; __nss_lookup_function;
__nss_disable_nscd; __nss_lookup_function; _nss_files_parse_sgent;
__nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2;
__nss_services_lookup2; __nss_next2;
@ -87,6 +87,11 @@ libnss_files {
_nss_files_getspent_r;
_nss_files_getspnam_r;
_nss_files_setsgent;
_nss_files_endsgent;
_nss_files_getsgent_r;
_nss_files_getsgnam_r;
_nss_netgroup_parseline;
_nss_files_getpublickey;
_nss_files_getsecretkey;

View File

@ -103,6 +103,7 @@ parse_line (char *line, struct STRUCTURE *result, \
EXTRA_ARGS_DECL) \
{ \
ENTDATA_DECL (data) \
BUFFER_PREPARE \
char *p = strpbrk (line, EOLSET "\n"); \
if (p != NULL) \
*p = '\0'; \
@ -127,6 +128,21 @@ nss_files_parse_hidden_def (parse_line)
} \
}
# define STRING_LIST(variable, terminator_c) \
{ \
char **list = parse_list (&line, buf_start, buf_end, terminator_c, \
errnop); \
if (list) \
variable = list; \
else \
return -1; /* -1 indicates we ran out of space. */ \
\
/* Determine the new end of the buffer. */ \
while (*list != NULL) \
++list; \
buf_start = (char *) (list + 1); \
}
/* Helper function. */
static inline uint32_t
__attribute__ ((always_inline))
@ -178,12 +194,39 @@ strtou32 (const char *nptr, char **endptr, int base)
# ifndef TRAILING_LIST_MEMBER
# define BUFFER_PREPARE /* Nothing to do. */
# define TRAILING_LIST_PARSER /* Nothing to do. */
# else
# define TRAILING_LIST_PARSER \
# define BUFFER_PREPARE \
char *buf_start = NULL; \
char *buf_end = (char *) data + datalen; \
if (line >= data->linebuffer && line < buf_end) \
/* Find the end of the line buffer, we will use the space in \
DATA after it for storing the vector of pointers. */ \
buf_start = strchr (line, '\0') + 1; \
else \
/* LINE does not point within DATA->linebuffer, so that space is \
not being used for scratch space right now. We can use all of \
it for the pointer vector storage. */ \
buf_start = data->linebuffer; \
# define TRAILING_LIST_PARSER \
{ \
char **list = parse_list (line, data, datalen, errnop); \
if (buf_start == NULL) \
{ \
if (line >= data->linebuffer && line < buf_end) \
/* Find the end of the line buffer, we will use the space in \
DATA after it for storing the vector of pointers. */ \
buf_start = strchr (line, '\0') + 1; \
else \
/* LINE does not point within DATA->linebuffer, so that space is \
not being used for scratch space right now. We can use all of \
it for the pointer vector storage. */ \
buf_start = data->linebuffer; \
} \
\
char **list = parse_list (&line, buf_start, buf_end, '\0', errnop); \
if (list) \
result->TRAILING_LIST_MEMBER = list; \
else \
@ -192,19 +235,12 @@ strtou32 (const char *nptr, char **endptr, int base)
static inline char **
__attribute ((always_inline))
parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop)
parse_list (char **linep, char *eol, char *buf_end, int terminator_c,
int *errnop)
{
char *eol, **list, **p;
char *line = *linep;
char **list, **p;
if (line >= data->linebuffer && line < (char *) data + datalen)
/* Find the end of the line buffer, we will use the space in DATA after
it for storing the vector of pointers. */
eol = strchr (line, '\0') + 1;
else
/* LINE does not point within DATA->linebuffer, so that space is
not being used for scratch space right now. We can use all of
it for the pointer vector storage. */
eol = data->linebuffer;
/* Adjust the pointer so it is aligned for storing pointers. */
eol += __alignof__ (char *) - 1;
eol -= (eol - (char *) 0) % __alignof__ (char *);
@ -214,25 +250,30 @@ parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop)
p = list;
while (1)
{
char *elt;
if ((size_t) ((char *) &p[1] - (char *) data) > datalen)
if ((char *) (p + 2) > buf_end)
{
/* We cannot fit another pointer in the buffer. */
*errnop = ERANGE;
return NULL;
}
if (*line == '\0')
break;
if (*line == terminator_c)
{
++line;
break;
}
/* Skip leading white space. This might not be portable but useful. */
while (isspace (*line))
++line;
elt = line;
char *elt = line;
while (1)
{
if (*line == '\0' || TRAILING_LIST_SEPARATOR_P (*line))
if (*line == '\0' || *line == terminator_c
|| TRAILING_LIST_SEPARATOR_P (*line))
{
/* End of the next entry. */
if (line > elt)
@ -241,13 +282,20 @@ parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop)
/* Terminate string if necessary. */
if (*line != '\0')
*line++ = '\0';
{
char endc = *line;
*line++ = '\0';
if (endc == terminator_c)
goto out;
}
break;
}
++line;
}
}
out:
*p = NULL;
*linep = line;
return list;
}

View File

@ -0,0 +1,38 @@
/* User file parser in nss_files module.
Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <gshadow.h>
#define STRUCTURE sgrp
#define ENTNAME sgent
#define DATABASE "gshadow"
struct sgent_data {};
/* Our parser function is already defined in sgetspent_r.c, so use that
to parse lines from the database file. */
#define EXTERN_PARSER
#include "files-parse.c"
#include GENERIC
DB_LOOKUP (sgnam, 1 + strlen (name), (".%s", name),
{
if (name[0] != '+' && name[0] != '-'
&& ! strcmp (name, result->sg_namp))
break;
}, const char *name)

View File

@ -6,6 +6,7 @@
passwd: db files
group: db files
shadow: db files
gshadow: files
hosts: files dns
networks: files dns

24
nss/sgrp-lookup.c Normal file
View File

@ -0,0 +1,24 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#define DATABASE_NAME gshadow
#define ALTERNATE_NAME group
#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"

View File

@ -44,6 +44,7 @@
#define _PATH_DEVDB "/var/run/dev.db"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_DRUM "/dev/drum"
#define _PATH_GSHADOW "/etc/gshadow"
#define _PATH_KMEM "/dev/kmem"
#define _PATH_MAILDIR "/var/mail"
#define _PATH_LASTLOG "/var/log/lastlog"

View File

@ -44,6 +44,7 @@
#define _PATH_DEVDB "/var/run/dev.db"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_DRUM "/dev/drum"
#define _PATH_GSHADOW "/etc/gshadow"
#define _PATH_KLOG "/proc/kmsg"
#define _PATH_KMEM "/dev/kmem"
#define _PATH_LASTLOG "/var/log/lastlog"