diff options
Diffstat (limited to 'nss')
-rw-r--r-- | nss/Makefile | 2 | ||||
-rw-r--r-- | nss/databases.def | 1 | ||||
-rw-r--r-- | nss/db-Makefile | 10 | ||||
-rw-r--r-- | nss/getXXent_r.c | 6 | ||||
-rw-r--r-- | nss/netgrp-lookup.c | 22 | ||||
-rw-r--r-- | nss/nss.h | 1 | ||||
-rw-r--r-- | nss/nss_db/db-XXX.c | 10 | ||||
-rw-r--r-- | nss/nss_db/db-netgrp.c | 108 | ||||
-rw-r--r-- | nss/nss_dns/dns-network.c | 7 | ||||
-rw-r--r-- | nss/nss_files/files-netgrp.c | 262 | ||||
-rw-r--r-- | nss/nsswitch.c | 3 | ||||
-rw-r--r-- | nss/nsswitch.conf | 2 | ||||
-rw-r--r-- | nss/nsswitch.h | 2 |
13 files changed, 420 insertions, 16 deletions
diff --git a/nss/Makefile b/nss/Makefile index b900e96cc3..319bad5b29 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -33,7 +33,7 @@ routines = nsswitch $(addsuffix -lookup,$(databases)) # 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 + spwd netgrp # Specify rules for the nss_* modules. We have some services. services := files dns db diff --git a/nss/databases.def b/nss/databases.def index 98772bac76..8a5ede2a58 100644 --- a/nss/databases.def +++ b/nss/databases.def @@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ DEFINE_DATABASE (ethers) DEFINE_DATABASE (group) DEFINE_DATABASE (hosts) +DEFINE_DATABASE (netgroup) DEFINE_DATABASE (networks) DEFINE_DATABASE (passwd) DEFINE_DATABASE (protocols) diff --git a/nss/db-Makefile b/nss/db-Makefile index 55edd66c01..756f4c6ce6 100644 --- a/nss/db-Makefile +++ b/nss/db-Makefile @@ -1,5 +1,5 @@ DATABASES = $(wildcard /etc/passwd /etc/group /etc/ethers /etc/protocols \ - /etc/rpc /etc/services /etc/shadow) + /etc/rpc /etc/services /etc/shadow /etc/netgroup) VAR_DB = /var/db @@ -67,3 +67,11 @@ $(VAR_DB)/shadow.db: /etc/shadow /^[^#]/ { printf ".%s ", $$1; print }' $^ | \ $(MAKEDB) -o $@ - @echo "done." + +$(VAR_DB)/netgroup.db: /etc/netgroup + @echo -n "$(patsubst %.db,%,$(@F))... " + @$(AWK) '/^[^#]/ { end=sub(/\\/, " "); \ + gsub(/[ \t]+/, " "); \ + if(end == 1) printf "%s", $$0; else print }' $^ | \ + $(MAKEDB) -o $@ - + @echo "done." diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c index ea391fe094..6bff863e07 100644 --- a/nss/getXXent_r.c +++ b/nss/getXXent_r.c @@ -136,7 +136,7 @@ SETFUNC_NAME (STAYOPEN) #ifdef NEED__RES if ((_res.options & RES_INIT) == 0 && res_init () == -1) { - h_errno = NETDB_INTERNAL; + __set_h_errno (NETDB_INTERNAL); return NULL; } #endif /* need _res */ @@ -166,7 +166,7 @@ ENDFUNC_NAME (void) #ifdef NEED__RES if ((_res.options & RES_INIT) == 0 && res_init () == -1) { - h_errno = NETDB_INTERNAL; + __set_h_errno (NETDB_INTERNAL); return NULL; } #endif /* need _res */ @@ -198,7 +198,7 @@ INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *result, char *buffer, int buflen #ifdef NEED__RES if ((_res.options & RES_INIT) == 0 && res_init () == -1) { - h_errno = NETDB_INTERNAL; + __set_h_errno (NETDB_INTERNAL); return NULL; } #endif /* need _res */ diff --git a/nss/netgrp-lookup.c b/nss/netgrp-lookup.c new file mode 100644 index 0000000000..b7ea374f1b --- /dev/null +++ b/nss/netgrp-lookup.c @@ -0,0 +1,22 @@ +/* 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. */ + +#define DATABASE_NAME netgroup + +#include "XXX-lookup.c" diff --git a/nss/nss.h b/nss/nss.h index e9acb93bcc..8246719054 100644 --- a/nss/nss.h +++ b/nss/nss.h @@ -37,6 +37,7 @@ enum nss_status NSS_STATUS_UNAVAIL, NSS_STATUS_NOTFOUND, NSS_STATUS_SUCCESS, + NSS_STATUS_RETURN }; diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c index e2bab51f5d..0c41761d67 100644 --- a/nss/nss_db/db-XXX.c +++ b/nss/nss_db/db-XXX.c @@ -56,10 +56,10 @@ static int keep_db; static unsigned int entidx; /* Index for `getENTNAME'. */ /* Open database file if not already opened. */ -static int +static enum nss_status internal_setent (int stayopen) { - int status = NSS_STATUS_SUCCESS; + enum nss_status status = NSS_STATUS_SUCCESS; if (db == NULL) { @@ -78,10 +78,10 @@ internal_setent (int stayopen) /* Thread-safe, exported version of that. */ -int +enum nss_status CONCAT(_nss_db_set,ENTNAME) (int stayopen) { - int status; + enum nss_status status; __libc_lock_lock (lock); @@ -109,7 +109,7 @@ internal_endent (void) /* Thread-safe, exported version of that. */ -int +enum nss_status CONCAT(_nss_db_end,ENTNAME) (void) { __libc_lock_lock (lock); diff --git a/nss/nss_db/db-netgrp.c b/nss/nss_db/db-netgrp.c new file mode 100644 index 0000000000..441a0bdf55 --- /dev/null +++ b/nss/nss_db/db-netgrp.c @@ -0,0 +1,108 @@ +/* Netgroup file parser in nss_db 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 <db.h> +#include <errno.h> +#include <fcntl.h> +#include <libc-lock.h> +#include <paths.h> +#include "nsswitch.h" +#include "netgroup.h" + + +#define DBFILE _PATH_VARDB "netgroup.db" + + +/* Locks the static variables in this file. */ +__libc_lock_define_initialized (static, lock) + +/* Maintenance of the shared handle open on the database. */ +static DB *db; +static char *entry; +static char *cursor; + +enum nss_status +_nss_db_setnetgrent (const char *group) +{ + enum nss_status status = NSS_STATUS_SUCCESS; + + __libc_lock_lock (lock); + + /* Make sure the data base file is open. */ + if (db == NULL) + { + db = dbopen (DBFILE, O_RDONLY, 0, DB_BTREE, NULL); + + if (db == NULL) + status = errno = EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; + } + + if (status == NSS_STATUS_SUCCESS) + { + DBT key = { data: (void *) group, size: strlen (group) }; + DBT value; + + if ((*db->get) (db, &key, &value, 0) != 0) + status = NSS_STATUS_NOTFOUND; + else + cursor = entry = value.data; + } + + __libc_lock_unlock (lock); + + return status; + +} + + +enum nss_status +_nss_db_endnetgrent (void) +{ + __libc_lock_lock (lock); + + if (db != NULL) + { + (*db->close) (db); + db = NULL; + } + + __libc_lock_unlock (lock); + + return NSS_STATUS_SUCCESS; +} + + +extern enum nss_status _nss_netgroup_parseline (char **cursor, + struct __netgrent *result, + char *buffer, int buflen); + +enum nss_status +_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen) +{ + int status; + + __libc_lock_lock (lock); + + status = _nss_netgroup_parseline (&cursor, result, buffer, buflen); + + __libc_lock_unlock (lock); + + return status; +} diff --git a/nss/nss_dns/dns-network.c b/nss/nss_dns/dns-network.c index 1b5d0ce71b..a2d9d280a5 100644 --- a/nss/nss_dns/dns-network.c +++ b/nss/nss_dns/dns-network.c @@ -236,12 +236,12 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, OSF/1 has a per-thread h_errno variable. */ if (header_pointer->aa != 0) { - h_errno = HOST_NOT_FOUND; + __set_h_errno (HOST_NOT_FOUND); return NSS_STATUS_NOTFOUND; } else { - h_errno = TRY_AGAIN; + __set_h_errno (TRY_AGAIN); return NSS_STATUS_TRYAGAIN; } @@ -338,7 +338,6 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, return NSS_STATUS_SUCCESS; } - /* XXX Really use global variable??? */ - h_errno = TRY_AGAIN; + __set_h_errno (TRY_AGAIN); return NSS_STATUS_TRYAGAIN; } diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c new file mode 100644 index 0000000000..8af55f209f --- /dev/null +++ b/nss/nss_files/files-netgrp.c @@ -0,0 +1,262 @@ +/* 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 <libc-lock.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "nsswitch.h" +#include "netgroup.h" + +#define DATAFILE "/etc/netgroup" + + +/* Locks the static variables in this file. */ +__libc_lock_define_initialized (static, lock) + +/* We share a single place where we store the data for the current + netgroup. This buffer is allocated by `setnetgrent' and freed on + the next call of this function or when calling `endnetgrent'. */ +static char *data; +static size_t data_size; +static char *cursor; +static int first; + + +#define EXPAND(needed) \ + do \ + { \ + size_t old_cursor = cursor - data; \ + \ + data_size += 512 > 2 * needed ? 512 : 2 * needed; \ + data = realloc (data, data_size); \ + \ + if (data == NULL) \ + { \ + status = NSS_STATUS_UNAVAIL; \ + goto the_end; \ + } \ + \ + cursor = data + old_cursor; \ + } \ + while (0) + + +enum nss_status +_nss_files_setnetgrent (const char *group) +{ + FILE *fp; + enum nss_status status; + + if (group[0] == '\0') + return NSS_STATUS_UNAVAIL; + + __libc_lock_lock (lock); + + /* 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; + cursor = 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 (cursor, &line[group_len + 1], curlen - group_len); + 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. */ + 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. */ + *cursor++ = ' '; + + /* Copy new line. */ + memcpy (cursor, line, curlen + 1); + cursor += curlen; + } + } + + if (found) + { + /* Now we have read the line. */ + status = NSS_STATUS_SUCCESS; + cursor = data; + first = 1; + break; + } + } + + the_end: + /* We don't need the file and the line buffer anymore. */ + free (line); + fclose (fp); + } + + __libc_lock_unlock (lock); + + return status; +} + + +int +_nss_files_endnetgrent (void) +{ + __libc_lock_lock (lock); + + /* Free allocated memory for data if some is present. */ + if (data != NULL) + { + free (data); + data = NULL; + data_size = 0; + cursor = NULL; + } + + __libc_lock_unlock (lock); + + return NSS_STATUS_SUCCESS; +} + + +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; + + /* First skip leading spaces. */ + while (isspace (*cp)) + ++cp; + + if (*cp != '(') + return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; + + /* Match host name. */ + host = ++cp; + while (*cp != ',') + if (*cp++ == '\0') + return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; + + /* Match user name. */ + user = ++cp; + while (*cp != ',') + if (*cp++ == '\0') + return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; + + /* Match domain name. */ + domain = ++cp; + while (*cp != ')') + if (*cp++ == '\0') + return 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); + + buffer[(user - host) - 1] = '\0'; + result->host = *host == ',' ? NULL : buffer; + + buffer[(domain - host) - 1] = '\0'; + result->user = *user == ',' ? NULL : buffer + (user - host); + + buffer[(cp - host) - 1] = '\0'; + result->domain = *domain == ')' ? NULL : buffer + (domain - host); + + status = NSS_STATUS_SUCCESS; + + /* Rememember where we stopped reading. */ + *cursor = cp; + + first = 0; + } + + return status; +} + + +enum nss_status +_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen) +{ + enum nss_status status; + + __libc_lock_lock (lock); + + status = _nss_netgroup_parseline (&cursor, result, buffer, buflen); + + __libc_lock_unlock (lock); + + return status; +} diff --git a/nss/nsswitch.c b/nss/nsswitch.c index f49ddb95a6..9f27ef80ff 100644 --- a/nss/nsswitch.c +++ b/nss/nsswitch.c @@ -158,7 +158,7 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, else { /* This is really only for debugging. */ - if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_SUCCESS) + if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) __libc_fatal ("illegal status in " __FUNCTION__); if (nss_next_action (*ni, status) == NSS_ACTION_RETURN) @@ -503,6 +503,7 @@ nss_parse_service_list (const char *line) new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE; new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE; new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN; + new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN; new_service->library = NULL; new_service->known = NULL; new_service->next = NULL; diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf index 08bd96ea10..63a78758d6 100644 --- a/nss/nsswitch.conf +++ b/nss/nsswitch.conf @@ -14,3 +14,5 @@ protocols: db files services: db files ethers: db files rpc: db files + +netgroup: db files diff --git a/nss/nsswitch.h b/nss/nsswitch.h index 0c99f147fd..df4e0f77f6 100644 --- a/nss/nsswitch.h +++ b/nss/nsswitch.h @@ -62,7 +62,7 @@ typedef struct service_user /* Name of the service (`files', `dns', `nis', ...). */ const char *name; /* Action according to result. */ - lookup_actions actions[4]; + lookup_actions actions[5]; /* Link to the underlying library object. */ service_library *library; /* Collection of known functions. */ |