summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornalin <nalin>2002-11-18 19:53:21 +0000
committernalin <nalin>2002-11-18 19:53:21 +0000
commitfa50831c92f4849af7b1e8cc95e87555b06d2ca6 (patch)
tree92c3c9fcc0032f7f3381baeed40394b01872564d
downloadnss_directories-fa50831c92f4849af7b1e8cc95e87555b06d2ca6.tar.gz
nss_directories-fa50831c92f4849af7b1e8cc95e87555b06d2ca6.tar.xz
nss_directories-fa50831c92f4849af7b1e8cc95e87555b06d2ca6.zip
- initial checkin
-rw-r--r--AUTHORS0
-rw-r--r--ChangeLog0
-rw-r--r--Makefile.am3
-rw-r--r--NEWS0
-rw-r--r--README12
-rwxr-xr-xautogen.sh7
-rw-r--r--configure.ac36
-rw-r--r--nss_directories.spec37
-rw-r--r--src/Makefile.am22
-rw-r--r--src/generic.c400
-rw-r--r--src/group.c40
-rw-r--r--src/parsers.h48
-rw-r--r--src/passwd.c40
-rw-r--r--src/protocols.c41
-rw-r--r--src/services.c45
-rw-r--r--src/shadow.c36
16 files changed, 767 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/AUTHORS
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ChangeLog
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..4771b57
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+EXTRA_DIST = README nss_directories.spec
+DISTCHECK_CONFIGURE_FLAGS = --with-moduledir=$$dc_install_base/modules
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..f1f6703
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+nss_directories
+
+nss_directories is a set of C library extensions which allow a directory
+full of files to be used as a primary source of user, group, and service
+information instead of or in addition to flat files or NIS.
+
+nss_files nss_directories
+========= ===============
+/etc/passwd /etc/passwd.d/*
+/etc/shadow /etc/shadow.d/*
+/etc/group /etc/group.d/*
+/etc/services /etc/services.d/*
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..cc4da66
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,7 @@
+set -x
+libtoolize -f -c
+aclocal
+automake -a
+autoheader
+autoconf
+./configure --sysconfdir=/etc --with-moduledir=/lib/`gcc -print-multi-directory` $@
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..0d4bb7f
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,36 @@
+AC_INIT(README)
+AM_INIT_AUTOMAKE(nss_directories,0.1)
+AM_PROG_LIBTOOL
+
+MYPREFIX=`eval echo $prefix`
+if test "$MYPREFIX" = NONE ; then
+ MYPREFIX="$ac_default_prefix"
+ MYSYSCONFDIR=`eval echo $sysconfdir | sed "s|NONE|$MYPREFIX|g"`
+else
+ MYSYSCONFDIR=`eval echo $sysconfdir`
+fi
+
+AC_DEFINE_UNQUOTED(SYSCONFDIR,"$MYSYSCONFDIR",[Define to the top-level data directory.])
+
+AC_ARG_WITH(moduledir,[ --with-moduledir=DIR directory to install modules in (default /lib)],[moduledir="$withval"])
+if ! test -n "$moduledir"
+then
+ moduledir=/lib
+fi
+AC_SUBST(moduledir)
+
+AC_CHECK_LIB(nss_files,_nss_files_parse_pwent)
+AC_CHECK_LIB(nss_files,_nss_files_parse_grent)
+AC_CHECK_LIB(nss_files,_nss_files_parse_spent)
+AC_CHECK_LIB(nss_files,_nss_files_parse_servent)
+AC_CHECK_LIB(nss_files,_nss_files_parse_protoent)
+
+nss_files=`ls -1 "$moduledir"/libnss_files-*.so | head -1`
+GLIBC_VERSION=`basename "$nss_files" .so | cut -f2 -d-`
+AC_SUBST(GLIBC_VERSION)
+
+AM_CONFIG_HEADER(config.h)
+AC_OUTPUT(Makefile src/Makefile)
+
+AC_MSG_RESULT([Reading data from sysconfdir = "$MYSYSCONFDIR".])
+AC_MSG_RESULT([Installing modules to "$moduledir".])
diff --git a/nss_directories.spec b/nss_directories.spec
new file mode 100644
index 0000000..793a586
--- /dev/null
+++ b/nss_directories.spec
@@ -0,0 +1,37 @@
+Name: nss_directories
+Version: 0.1
+Release: 1
+Source: %{name}-%{version}.tar.gz
+License: LGPL
+Group: System Environment/Libraries
+Summary: An NSS library which searches directories.
+BuildRoot: %{_tmppath}/%{name}-root
+
+%description
+Nss_directories is a set of C library extensions which allow a set of
+files in a directory to be used as a primary source of groups, users,
+services, and shadow passwords (instead of or in addition to using flat
+files or NIS).
+
+%prep
+%setup -q
+%configure --with-moduledir=/%{_lib}
+
+%build
+make
+
+%install
+rm -fr $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -fr $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%doc README
+/%{_lib}/libnss_directories-*.so
+
+%changelog
+* Sun Nov 17 2002 Nalin Dahyabhai <nalin@redhat.com> 0.1-1
+- initial version
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..07e0264
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,22 @@
+moduleexecdir = @moduledir@
+moduleexec_LTLIBRARIES = libnss_directories.la
+
+EXTRA_libnss_directories_la_SOURCES = \
+ generic.c
+libnss_directories_la_SOURCES = \
+ parsers.h \
+ group.c \
+ passwd.c \
+ protocols.c \
+ services.c \
+ shadow.c
+
+libnss_directories_la_LDFLAGS = \
+ -version-info 2 -export-symbols-regex "_nss_directories.*"
+
+install-exec-hook:
+ mv $(DESTDIR)/$(moduleexecdir)/libnss_directories.so.2.0.0 \
+ $(DESTDIR)/$(moduleexecdir)/libnss_directories-@GLIBC_VERSION@.so
+ $(RM) -f $(DESTDIR)/$(moduleexecdir)/libnss_directories.so*
+ $(RM) -f $(DESTDIR)/$(moduleexecdir)/libnss_directories.a
+ $(RM) -f $(DESTDIR)/$(moduleexecdir)/libnss_directories.la
diff --git a/src/generic.c b/src/generic.c
new file mode 100644
index 0000000..f23792d
--- /dev/null
+++ b/src/generic.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: generic.c,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#include "../config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fnmatch.h>
+#include <limits.h>
+#include <nss.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "parsers.h"
+#include <pwd.h>
+
+#define CHUNK_SIZE LINE_MAX
+#define FALSE 0
+#define TRUE (!FALSE)
+
+static const char *skip_names[] = {
+ "*~",
+ "*.rpmsave",
+ "*.rpmorig",
+ "*.rpmnew",
+};
+
+static int
+skip_file_by_name(const char *filename)
+{
+ int i;
+ for (i = 0; i < sizeof(skip_names) / sizeof(skip_names[0]); i++) {
+ if (fnmatch(skip_names[i], filename, 0) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static char *
+read_line(FILE *fp)
+{
+ char *buffer;
+ size_t buflen, length;
+
+ buflen = CHUNK_SIZE;
+ length = 0;
+ buffer = malloc(CHUNK_SIZE);
+ if (buffer == NULL) {
+ return NULL;
+ }
+ memset(buffer, 0, buflen);
+
+ while (fgets(buffer + length, buflen - length, fp) != NULL) {
+ length = strlen(buffer);
+ if (length > 0) {
+ if (buffer[length - 1] == '\n') {
+ break;
+ } else {
+ buflen += CHUNK_SIZE;
+ buffer = realloc(buffer, buflen);
+ if (buffer == NULL) {
+ return NULL;
+ }
+ memset(buffer + length, 0, buflen - length);
+ }
+ }
+ }
+
+ if (strlen(buffer) == 0) {
+ free(buffer);
+ return NULL;
+ }
+
+ if ((length > 0) && (buffer[length - 1] == '\n')) {
+ buffer[length - 1] = '\0';
+ }
+
+ return buffer;
+}
+
+static enum nss_status
+getgen(struct STRUCTURE *result,
+#ifdef GET_EXTRA_CRITERIA
+ GET_EXTRA_CRITERIA,
+#endif
+ char *buffer, size_t buflen, int *errnop,
+ int (*compare)(const void *compare_data, struct STRUCTURE *structure),
+ const void *compare_data)
+{
+ DIR *dir = NULL;
+ FILE *fp = NULL;
+ struct STRUCTURE structure;
+ struct dirent *ent = NULL;
+ struct stat st;
+ char path[PATH_MAX], *line;
+
+ /* Start reading the directory. */
+ dir = opendir(SYSCONFDIR "/" FILENAME ".d");
+ if (dir == NULL) {
+ *errnop = errno;
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Iterate over each file in the directory. */
+ while ((ent = readdir(dir)) != NULL) {
+ /* If the file has a certain name, skip it. */
+ if (skip_file_by_name(ent->d_name)) {
+ continue;
+ }
+
+ /* Figure out the full name of the file. */
+ snprintf(path, sizeof(path), SYSCONFDIR "/" FILENAME ".d/%s",
+ ent->d_name);
+
+ /* If we can't open it, skip it. */
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ continue;
+ }
+
+ /* If we can't stat() it, or it's not a regular file or
+ * a symlink, skip it. */
+ if ((fstat(fileno(fp), &st) != 0) ||
+ (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))) {
+ fclose(fp);
+ continue;
+ }
+
+ /* Read the next line. */
+ while ((line = read_line(fp)) != NULL) {
+ /* If we had trouble parsing it, continue. */
+ if (parser(line, &structure,
+ (struct parser_data*) buffer, buflen,
+ errnop) == 0) {
+ free(line);
+ continue;
+ }
+ /* If it matches, close the file and the directory,
+ * and return the answer. */
+ if ((compare(compare_data, &structure) == 0) &&
+#ifdef CHECK_EXTRA_CRITERIA
+ CHECK_EXTRA_CRITERIA(&structure) &&
+#endif
+ TRUE) {
+ *result = structure;
+ free(line);
+ fclose(fp);
+ closedir(dir);
+ return NSS_STATUS_SUCCESS;
+ }
+
+ /* Free this line. */
+ free(line);
+ }
+
+ /* Close this file. */
+ fclose(fp);
+ }
+
+ /* Close this directory. */
+ closedir(dir);
+
+ /* Tell the caller that we didn't find anything. */
+ return NSS_STATUS_NOTFOUND;
+}
+#if defined(getnam) && defined(getnam_field)
+static int
+compare_name(const void *compare_data, struct STRUCTURE *structure)
+{
+#ifdef getnam_fields
+ int i;
+ if (structure->getnam_fields != NULL) {
+ for (i = 0; structure->getnam_fields[i] != NULL; i++) {
+ if (strcmp(structure->getnam_fields[i],
+ (const char *)compare_data) == 0) {
+ return 0;
+ }
+ }
+ }
+#endif
+ return strcmp(structure->getnam_field, (const char *)compare_data);
+}
+enum nss_status
+getnam(const char *name,
+#ifdef GET_EXTRA_CRITERIA
+ GET_EXTRA_CRITERIA,
+#endif
+ struct STRUCTURE *result, char *buffer, size_t buflen, int *errnop )
+{
+ return getgen(result,
+#ifdef EXTRA_CRITERIA_NAMES
+ EXTRA_CRITERIA_NAMES,
+#endif
+ buffer, buflen, errnop,
+ compare_name, (const void*) name);
+}
+#endif
+#if defined(getnum) && defined(getnum_type) && defined(getnum_field)
+static int
+compare_number(const void *compare_data, struct STRUCTURE *structure)
+{
+ return (structure->getnum_field != (getnum_type) compare_data);
+}
+enum nss_status
+getnum(getnum_type number,
+#ifdef GET_EXTRA_CRITERIA
+ GET_EXTRA_CRITERIA,
+#endif
+ struct STRUCTURE *result, char *buffer, size_t buflen, int *errnop )
+{
+ return getgen(result,
+#ifdef EXTRA_CRITERIA_NAMES
+ EXTRA_CRITERIA_NAMES,
+#endif
+ buffer, buflen, errnop,
+ compare_number, (const void*) number);
+}
+#endif
+#if defined(setent) && defined(getent) && defined(endent)
+
+static pthread_mutex_t enumeration_lock = PTHREAD_MUTEX_INITIALIZER;
+#define LOCK() pthread_mutex_lock(&enumeration_lock)
+#define UNLOCK() pthread_mutex_unlock(&enumeration_lock)
+static DIR *dir = NULL;
+static FILE *fp = NULL;
+
+enum nss_status
+endent(void)
+{
+ /* Close the directory and the current file. */
+ LOCK();
+ if (fp != NULL) {
+ fclose(fp);
+ fp = NULL;
+ }
+ if (dir != NULL) {
+ closedir(dir);
+ dir = NULL;
+ }
+ UNLOCK();
+ return NSS_STATUS_UNAVAIL;
+}
+enum nss_status
+setent(int stayopen)
+{
+ /* Close and reopen the directory. */
+ endent();
+ LOCK();
+ dir = opendir(SYSCONFDIR "/" FILENAME ".d");
+ UNLOCK();
+ return NSS_STATUS_UNAVAIL;
+}
+enum nss_status
+getent(struct STRUCTURE *result, char *buffer, size_t buflen, int *errnop)
+{
+ char path[PATH_MAX], *line;
+ struct dirent *ent;
+ struct stat st;
+ struct STRUCTURE structure;
+
+ LOCK();
+
+ /* If we don't have a current directory, try to reset. */
+ if (dir == NULL) {
+ setent(TRUE);
+ /* If we couldn't open the directory, then we'd better just
+ * give up now. */
+ if (dir == NULL) {
+ UNLOCK();
+ return NSS_STATUS_NOTFOUND;
+ }
+ }
+
+ do {
+ /* If we don't have a current file, try to open the next file
+ * in the directory. */
+ if ((fp == NULL) || feof(fp)) {
+ if (fp != NULL) {
+ fclose(fp);
+ fp = NULL;
+ }
+
+ do {
+ /* Read the next entry in the directory. */
+ ent = readdir(dir);
+ if (ent == NULL) {
+ closedir(dir);
+ dir = NULL;
+ continue;
+ }
+
+ /* If the file has a certain name, skip it. */
+ if (skip_file_by_name(ent->d_name)) {
+ continue;
+ }
+
+ /* Formulate the full path name and try to
+ * open it. */
+ snprintf(path, sizeof(path),
+ SYSCONFDIR "/" FILENAME ".d/%s",
+ ent->d_name);
+ fp = fopen(path, "r");
+
+ /* If we failed to open the file, move on. */
+ if (fp == NULL) {
+ continue;
+ }
+
+ /* If we can't stat() the file, move on. */
+ if (fstat(fileno(fp), &st) != 0) {
+ fclose(fp);
+ fp = NULL;
+ continue;
+ }
+
+ /* If the file isn't normal or a symlink,
+ * move on. */
+ if (!S_ISREG(st.st_mode) &&
+ !S_ISLNK(st.st_mode)) {
+ fclose(fp);
+ fp = NULL;
+ continue;
+ }
+ } while ((dir != NULL) && (fp == NULL));
+ }
+
+ /* If we're out of data, return NOTFOUND. */
+ if ((dir == NULL) || (fp == NULL)) {
+ UNLOCK();
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Read a line from the file. */
+ line = read_line(fp);
+ if (line == NULL) {
+ fclose(fp);
+ fp = NULL;
+ continue;
+ }
+
+ /* Try to parse the line. */
+ if (parser(line, &structure,
+ (struct parser_data*) buffer, buflen,
+ errnop) != 0) {
+ free(line);
+ *result = structure;
+ UNLOCK();
+ return NSS_STATUS_SUCCESS;
+ }
+
+ /* Try the next entry. */
+ free(line);
+ } while (1);
+
+ /* We never really get here, but oh well. */
+ UNLOCK();
+ return NSS_STATUS_UNAVAIL;
+}
+#endif
+
+#ifdef IMPLEMENT_MAIN
+int
+main(int argc, char **argv)
+{
+ struct passwd pwd;
+ char buffer[LINE_MAX];
+ int error;
+ if (getnum(500, &pwd, buffer, sizeof(buffer),
+ &error) == NSS_STATUS_SUCCESS) {
+ printf("%s:%ld\n", pwd.pw_name, (long) pwd.pw_uid);
+ }
+ while (getent(&pwd, buffer, sizeof(buffer),
+ &error) == NSS_STATUS_SUCCESS) {
+ printf("%s:%ld\n", pwd.pw_name, (long) pwd.pw_uid);
+ }
+ return 0;
+}
+#endif
diff --git a/src/group.c b/src/group.c
new file mode 100644
index 0000000..6aebecb
--- /dev/null
+++ b/src/group.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: group.c,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#include <sys/types.h>
+#include <grp.h>
+
+#define STRUCTURE group
+#define FILENAME "group"
+
+#define getnam _nss_directories_getgrnam_r
+#define getnam_field gr_name
+
+#define getnum _nss_directories_getgrgid_r
+#define getnum_type gid_t
+#define getnum_field gr_gid
+
+#define setent _nss_directories_setgrent
+#define getent _nss_directories_getgrent_r
+#define endent _nss_directories_endgrent
+
+#define parser _nss_files_parse_grent
+
+#include "generic.c"
diff --git a/src/parsers.h b/src/parsers.h
new file mode 100644
index 0000000..47e787d
--- /dev/null
+++ b/src/parsers.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: parsers.h,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#ifndef parsers_h
+#define parsers_h
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
+#include <netdb.h>
+
+struct parser_data;
+
+extern int _nss_files_parse_pwent(char *line, struct passwd *result,
+ struct parser_data *data, size_t datalen,
+ int *errnop);
+extern int _nss_files_parse_grent(char *line, struct group *result,
+ struct parser_data *data, size_t datalen,
+ int *errnop);
+extern int _nss_files_parse_spent(char *line, struct spwd *result,
+ struct parser_data *data, size_t datalen,
+ int *errnop);
+extern int _nss_files_parse_servent(char *line, struct servent *result,
+ struct parser_data *data, size_t datalen,
+ int *errnop);
+extern int _nss_files_parse_protoent(char *line, struct protoent *result,
+ struct parser_data *data, size_t datalen,
+ int *errnop);
+
+#endif
diff --git a/src/passwd.c b/src/passwd.c
new file mode 100644
index 0000000..53b3159
--- /dev/null
+++ b/src/passwd.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: passwd.c,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#include <sys/types.h>
+#include <pwd.h>
+
+#define STRUCTURE passwd
+#define FILENAME "passwd"
+
+#define getnam _nss_directories_getpwnam_r
+#define getnam_field pw_name
+
+#define getnum _nss_directories_getpwuid_r
+#define getnum_type uid_t
+#define getnum_field pw_uid
+
+#define setent _nss_directories_setpwent
+#define getent _nss_directories_getpwent_r
+#define endent _nss_directories_endpwent
+
+#define parser _nss_files_parse_pwent
+
+#include "generic.c"
diff --git a/src/protocols.c b/src/protocols.c
new file mode 100644
index 0000000..0a89a81
--- /dev/null
+++ b/src/protocols.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: protocols.c,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#include <sys/types.h>
+#include <netdb.h>
+
+#define STRUCTURE protoent
+#define FILENAME "protocols"
+
+#define getnam _nss_directories_getprotobyname_r
+#define getnam_field p_name
+#define getnam_fields p_aliases
+
+#define getnum _nss_directories_getprotobynumber_r
+#define getnum_type int
+#define getnum_field p_proto
+
+#define setent _nss_directories_setprotoent
+#define getent _nss_directories_getprotoent_r
+#define endent _nss_directories_endprotoent
+
+#define parser _nss_files_parse_protoent
+
+#include "generic.c"
diff --git a/src/services.c b/src/services.c
new file mode 100644
index 0000000..1ca091f
--- /dev/null
+++ b/src/services.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: services.c,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#include <sys/types.h>
+#include <netdb.h>
+
+#define STRUCTURE servent
+#define FILENAME "services"
+
+#define getnam _nss_directories_getservbyname_r
+#define getnam_field s_name
+#define getnam_fields s_aliases
+
+#define getnum _nss_directories_getservbyport_r
+#define getnum_type int
+#define getnum_field s_port
+
+#define setent _nss_directories_setservent
+#define getent _nss_directories_getservent_r
+#define endent _nss_directories_endservent
+
+#define parser _nss_files_parse_servent
+
+#define GET_EXTRA_CRITERIA const char *protocol
+#define EXTRA_CRITERIA_NAMES protocol
+#define CHECK_EXTRA_CRITERIA(__s) (((__s)->s_proto != NULL) && strcmp((__s)->s_proto, protocol) == 0)
+
+#include "generic.c"
diff --git a/src/shadow.c b/src/shadow.c
new file mode 100644
index 0000000..0622f63
--- /dev/null
+++ b/src/shadow.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This 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.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ident "$Id: shadow.c,v 1.1 2002/11/18 19:53:21 nalin Exp $"
+
+#include <sys/types.h>
+#include <shadow.h>
+
+#define STRUCTURE spwd
+#define FILENAME "shadow"
+
+#define getnam _nss_directories_getspnam_r
+#define getnam_field sp_namp
+
+#define setent _nss_directories_setspent
+#define getent _nss_directories_getspent_r
+#define endent _nss_directories_endspent
+
+#define parser _nss_files_parse_spent
+
+#include "generic.c"