diff options
Diffstat (limited to 'nis/nss_nis')
-rw-r--r-- | nis/nss_nis/nis-alias.c | 281 | ||||
-rw-r--r-- | nis/nss_nis/nis-ethers.c | 292 | ||||
-rw-r--r-- | nis/nss_nis/nis-grp.c | 359 | ||||
-rw-r--r-- | nis/nss_nis/nis-hosts.c | 567 | ||||
-rw-r--r-- | nis/nss_nis/nis-initgroups.c | 336 | ||||
-rw-r--r-- | nis/nss_nis/nis-netgrp.c | 98 | ||||
-rw-r--r-- | nis/nss_nis/nis-network.c | 315 | ||||
-rw-r--r-- | nis/nss_nis/nis-proto.c | 278 | ||||
-rw-r--r-- | nis/nss_nis/nis-publickey.c | 234 | ||||
-rw-r--r-- | nis/nss_nis/nis-pwd.c | 581 | ||||
-rw-r--r-- | nis/nss_nis/nis-rpc.c | 279 | ||||
-rw-r--r-- | nis/nss_nis/nis-service.c | 438 | ||||
-rw-r--r-- | nis/nss_nis/nis-spwd.c | 235 |
13 files changed, 0 insertions, 4293 deletions
diff --git a/nis/nss_nis/nis-alias.c b/nis/nss_nis/nis-alias.c deleted file mode 100644 index c9c89db6ce..0000000000 --- a/nis/nss_nis/nis-alias.c +++ /dev/null @@ -1,281 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <aliases.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" - -__libc_lock_define_initialized (static, lock) - -static bool_t new_start = 1; -static char *oldkey; -static int oldkeylen; - -static int -_nss_nis_parse_aliasent (const char *key, char *alias, struct aliasent *result, - char *buffer, size_t buflen, int *errnop) -{ - char *first_unused = buffer + strlen (alias) + 1; - size_t room_left = - buflen - (buflen % __alignof__ (char *)) - strlen (alias) - 2; - char *line; - char *cp; - - result->alias_members_len = 0; - *first_unused = '\0'; - first_unused++; - strcpy (first_unused, key); - - if (first_unused[room_left - 1] != '\0') - { - /* The line is too long for our buffer. */ - no_more_room: - *errnop = ERANGE; - return -1; - } - - result->alias_name = first_unused; - - /* Terminate the line for any case. */ - cp = strpbrk (alias, "#\n"); - if (cp != NULL) - *cp = '\0'; - - first_unused += strlen (result->alias_name) + 1; - /* Adjust the pointer so it is aligned for - storing pointers. */ - first_unused += __alignof__ (char *) - 1; - first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); - result->alias_members = (char **) first_unused; - - line = alias; - - while (*line != '\0') - { - /* Skip leading blanks. */ - while (isspace (*line)) - line++; - - if (*line == '\0') - break; - - if (room_left < sizeof (char *)) - goto no_more_room; - room_left -= sizeof (char *); - result->alias_members[result->alias_members_len] = line; - - while (*line != '\0' && *line != ',') - line++; - - if (line != result->alias_members[result->alias_members_len]) - { - *line = '\0'; - line++; - result->alias_members_len++; - } - } - return result->alias_members_len == 0 ? 0 : 1; -} - -enum nss_status -_nss_nis_setaliasent (void) -{ - __libc_lock_lock (lock); - - new_start = 1; - if (oldkey != NULL) - { - free (oldkey); - oldkey = NULL; - oldkeylen = 0; - } - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} -/* The 'endaliasent' function is identical. */ -strong_alias (_nss_nis_setaliasent, _nss_nis_endaliasent) - -static enum nss_status -internal_nis_getaliasent_r (struct aliasent *alias, char *buffer, - size_t buflen, int *errnop) -{ - char *domain; - - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - alias->alias_local = 0; - - /* Get the next entry until we found a correct one. */ - int parse_res; - do - { - char *result; - int len; - char *outkey; - int keylen; - int yperr; - - if (new_start) - yperr = yp_first (domain, "mail.aliases", &outkey, &keylen, &result, - &len); - else - yperr = yp_next (domain, "mail.aliases", oldkey, oldkeylen, &outkey, - &keylen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer, - buflen, errnop); - if (__glibc_unlikely (parse_res == -1)) - { - free (outkey); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = 0; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen, - int *errnop) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_getaliasent_r (alias, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - size_t namlen = strlen (name); - char *name2; - int use_alloca = __libc_use_alloca (namlen + 1); - if (use_alloca) - name2 = __alloca (namlen + 1); - else - { - name2 = malloc (namlen + 1); - if (name2 == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - } - - /* Convert name to lowercase. */ - size_t i; - for (i = 0; i < namlen; ++i) - name2[i] = _tolower (name[i]); - name2[i] = '\0'; - - char *result; - int len; - int yperr = yp_match (domain, "mail.aliases", name2, namlen, &result, &len); - - if (!use_alloca) - free (name2); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - alias->alias_local = 0; - int parse_res = _nss_nis_parse_aliasent (name, p, alias, buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-ethers.c b/nis/nss_nis/nis-ethers.c deleted file mode 100644 index 2a466626e8..0000000000 --- a/nis/nss_nis/nis-ethers.c +++ /dev/null @@ -1,292 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> -#include <netinet/ether.h> -#include <netinet/if_ether.h> - -#include "nss-nis.h" - -/* Protect global state against multiple changers */ -__libc_lock_define_initialized (static, lock) - -/* Get the declaration of the parser function. */ -#define ENTNAME etherent -#define STRUCTURE etherent -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -struct response -{ - struct response *next; - char val[0]; -}; - -static struct response *start; -static struct response *next; - -static int -saveit (int instatus, char *inkey, int inkeylen, char *inval, - int invallen, char *indata) -{ - if (instatus != YP_TRUE) - return 1; - - if (inkey && inkeylen > 0 && inval && invallen > 0) - { - struct response *newp = malloc (sizeof (struct response) + invallen + 1); - if (newp == NULL) - return 1; /* We have no error code for out of memory */ - - if (start == NULL) - start = newp; - else - next->next = newp; - next = newp; - - newp->next = NULL; - *((char *) mempcpy (newp->val, inval, invallen)) = '\0'; - } - - return 0; -} - -static void -internal_nis_endetherent (void) -{ - while (start != NULL) - { - next = start; - start = start->next; - free (next); - } -} - -enum nss_status -_nss_nis_endetherent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endetherent (); - next = NULL; - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -internal_nis_setetherent (void) -{ - char *domainname; - struct ypall_callback ypcb; - enum nss_status status; - - yp_get_default_domain (&domainname); - - internal_nis_endetherent (); - - ypcb.foreach = saveit; - ypcb.data = NULL; - status = yperr2nss (yp_all (domainname, "ethers.byname", &ypcb)); - next = start; - - return status; -} - -enum nss_status -_nss_nis_setetherent (int stayopen) -{ - enum nss_status result; - - __libc_lock_lock (lock); - - result = internal_nis_setetherent (); - - __libc_lock_unlock (lock); - - return result; -} - -static enum nss_status -internal_nis_getetherent_r (struct etherent *eth, char *buffer, size_t buflen, - int *errnop) -{ - struct parser_data *data = (void *) buffer; - int parse_res; - - if (start == NULL) - internal_nis_setetherent (); - - /* Get the next entry until we found a correct one. */ - do - { - char *p; - - if (next == NULL) - return NSS_STATUS_NOTFOUND; - - p = strncpy (buffer, next->val, buflen); - - while (isspace (*p)) - ++p; - - parse_res = _nss_files_parse_etherent (p, eth, data, buflen, errnop); - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - next = next->next; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getetherent_r (struct etherent *result, char *buffer, size_t buflen, - int *errnop) -{ - int status; - - __libc_lock_lock (lock); - - status = internal_nis_getetherent_r (result, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_gethostton_r (const char *name, struct etherent *eth, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char *result; - int len; - int yperr = yp_match (domain, "ethers.byname", name, strlen (name), &result, - &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_etherent (p, eth, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getntohost_r (const struct ether_addr *addr, struct etherent *eth, - char *buffer, size_t buflen, int *errnop) -{ - if (addr == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char buf[33]; - int nlen = snprintf (buf, sizeof (buf), "%x:%x:%x:%x:%x:%x", - (int) addr->ether_addr_octet[0], - (int) addr->ether_addr_octet[1], - (int) addr->ether_addr_octet[2], - (int) addr->ether_addr_octet[3], - (int) addr->ether_addr_octet[4], - (int) addr->ether_addr_octet[5]); - - char *result; - int len; - int yperr = yp_match (domain, "ethers.byaddr", buf, nlen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_etherent (p, eth, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-grp.c b/nis/nss_nis/nis-grp.c deleted file mode 100644 index 05b33920fc..0000000000 --- a/nis/nss_nis/nis-grp.c +++ /dev/null @@ -1,359 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <ctype.h> -#include <errno.h> -#include <grp.h> -#include <nss.h> -#include <string.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" -#include <libnsl.h> - -/* Get the declaration of the parser function. */ -#define ENTNAME grent -#define STRUCTURE group -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -/* Protect global state against multiple changers */ -__libc_lock_define_initialized (static, lock) - -static bool_t new_start = 1; -static char *oldkey; -static int oldkeylen; -static intern_t intern; - - -static void -internal_nis_endgrent (void) -{ - new_start = 1; - if (oldkey != NULL) - { - free (oldkey); - oldkey = NULL; - oldkeylen = 0; - } - - struct response_t *curr = intern.start; - - while (curr != NULL) - { - struct response_t *last = curr; - curr = curr->next; - free (last); - } - - intern.next = intern.start = NULL; -} - - -enum nss_status -_nss_nis_endgrent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endgrent (); - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -internal_nis_setgrent (void) -{ - /* We have to read all the data now. */ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - struct ypall_callback ypcb; - - ypcb.foreach = _nis_saveit; - ypcb.data = (char *) &intern; - enum nss_status status = yperr2nss (yp_all (domain, "group.byname", &ypcb)); - - - /* Mark the last buffer as full. */ - if (intern.next != NULL) - intern.next->size = intern.offset; - - intern.next = intern.start; - intern.offset = 0; - - return status; -} - - -enum nss_status -_nss_nis_setgrent (int stayopen) -{ - enum nss_status result = NSS_STATUS_SUCCESS; - - __libc_lock_lock (lock); - - internal_nis_endgrent (); - - if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) - result = internal_nis_setgrent (); - - __libc_lock_unlock (lock); - - return result; -} - - -static enum nss_status -internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen, - int *errnop) -{ - /* If we read the entire database at setpwent time we just iterate - over the data we have in memory. */ - bool batch_read = intern.start != NULL; - - char *domain = NULL; - if (!batch_read && __builtin_expect (yp_get_default_domain (&domain), 0)) - return NSS_STATUS_UNAVAIL; - - /* Get the next entry until we found a correct one. */ - int parse_res; - do - { - char *result; - char *outkey; - int len; - int keylen; - - if (batch_read) - { - struct response_t *bucket; - - handle_batch_read: - bucket = intern.next; - - if (__glibc_unlikely (intern.offset >= bucket->size)) - { - if (bucket->next == NULL) - return NSS_STATUS_NOTFOUND; - - /* We look at all the content in the current bucket. Go on - to the next. */ - bucket = intern.next = bucket->next; - intern.offset = 0; - } - - for (result = &bucket->mem[intern.offset]; isspace (*result); - ++result) - ++intern.offset; - - len = strlen (result); - } - else - { - int yperr; - - if (new_start) - { - /* Maybe we should read the database in one piece. */ - if ((_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) - && internal_nis_setgrent () == NSS_STATUS_SUCCESS - && intern.start != NULL) - { - batch_read = true; - goto handle_batch_read; - } - - yperr = yp_first (domain, "group.byname", &outkey, &keylen, - &result, &len); - } - else - yperr = yp_next (domain, "group.byname", oldkey, oldkeylen, - &outkey, &keylen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - if (!batch_read) - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - if (!batch_read) - free (result); - - parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res == -1)) - { - if (!batch_read) - free (outkey); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - if (batch_read) - intern.offset += len + 1; - else - { - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = 0; - } - } - while (parse_res < 1); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen, - int *errnop) -{ - int status; - - __libc_lock_lock (lock); - - status = internal_nis_getgrent_r (result, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getgrnam_r (const char *name, struct group *grp, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char *result; - int len; - int yperr = yp_match (domain, "group.byname", name, strlen (name), &result, - &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen, - errnop); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getgrgid_r (gid_t gid, struct group *grp, - char *buffer, size_t buflen, int *errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char buf[32]; - int nlen = sprintf (buf, "%lu", (unsigned long int) gid); - - char *result; - int len; - int yperr = yp_match (domain, "group.bygid", buf, nlen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c deleted file mode 100644 index f64dbdaecb..0000000000 --- a/nis/nss_nis/nis-hosts.c +++ /dev/null @@ -1,567 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <nss.h> -#include <ctype.h> -/* The following is an ugly trick to avoid a prototype declaration for - _nss_nis_endgrent. */ -#define _nss_nis_endhostent _nss_nis_endhostent_XXX -#include <netdb.h> -#undef _nss_nis_endhostent -#include <string.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <resolv/resolv-internal.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" - -/* Get implementation for some internal functions. */ -#include <resolv/mapv4v6addr.h> - -#define ENTNAME hostent -#define DATABASE "hosts" -#define NEED_H_ERRNO - -#define EXTRA_ARGS , af, flags -#define EXTRA_ARGS_DECL , int af, int flags - -#define ENTDATA hostent_data -struct hostent_data - { - unsigned char host_addr[16]; /* IPv4 or IPv6 address. */ - char *h_addr_ptrs[2]; /* Points to that and null terminator. */ - }; - -#define TRAILING_LIST_MEMBER h_aliases -#define TRAILING_LIST_SEPARATOR_P isspace -#include <nss/nss_files/files-parse.c> -LINE_PARSER -("#", - { - char *addr; - - STRING_FIELD (addr, isspace, 1); - - assert (af == AF_INET || af == AF_INET6 || af == AF_UNSPEC); - - /* Parse address. */ - if (af != AF_INET6 && inet_pton (AF_INET, addr, entdata->host_addr) > 0) - { - assert ((flags & AI_V4MAPPED) == 0 || af != AF_UNSPEC); - if (flags & AI_V4MAPPED) - { - map_v4v6_address ((char *) entdata->host_addr, - (char *) entdata->host_addr); - result->h_addrtype = AF_INET6; - result->h_length = IN6ADDRSZ; - } - else - { - result->h_addrtype = AF_INET; - result->h_length = INADDRSZ; - } - } - else if (af != AF_INET - && inet_pton (AF_INET6, addr, entdata->host_addr) > 0) - { - result->h_addrtype = AF_INET6; - result->h_length = IN6ADDRSZ; - } - else - /* Illegal address: ignore line. */ - return 0; - - /* Store a pointer to the address in the expected form. */ - entdata->h_addr_ptrs[0] = (char *) entdata->host_addr; - entdata->h_addr_ptrs[1] = NULL; - result->h_addr_list = entdata->h_addr_ptrs; - - STRING_FIELD (result->h_name, isspace, 1); - }) - - -__libc_lock_define_initialized (static, lock) - -static bool_t new_start = 1; -static char *oldkey = NULL; -static int oldkeylen = 0; - - -enum nss_status -_nss_nis_sethostent (int stayopen) -{ - __libc_lock_lock (lock); - - new_start = 1; - if (oldkey != NULL) - { - free (oldkey); - oldkey = NULL; - oldkeylen = 0; - } - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} -/* Make _nss_nis_endhostent an alias of _nss_nis_sethostent. We do this - even though the prototypes don't match. The argument of sethostent - is used so this makes no difference. */ -strong_alias (_nss_nis_sethostent, _nss_nis_endhostent) - - -/* The calling function always need to get a lock first. */ -static enum nss_status -internal_nis_gethostent_r (struct hostent *host, char *buffer, - size_t buflen, int *errnop, int *h_errnop, - int af, int flags) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); - buffer += pad; - - struct parser_data *data = (void *) buffer; - if (__glibc_unlikely (buflen < sizeof *data + 1 + pad)) - { - *errnop = ERANGE; - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - buflen -= pad; - - /* Get the next entry until we found a correct one. */ - const size_t linebuflen = buffer + buflen - data->linebuffer; - int parse_res; - do - { - char *result; - int len; - char *outkey; - int keylen; - int yperr; - if (new_start) - yperr = yp_first (domain, "hosts.byname", &outkey, &keylen, &result, - &len); - else - yperr = yp_next (domain, "hosts.byname", oldkey, oldkeylen, &outkey, - &keylen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - switch (retval) - { - case NSS_STATUS_TRYAGAIN: - *errnop = errno; - *h_errnop = TRY_AGAIN; - break; - case NSS_STATUS_NOTFOUND: - *h_errnop = HOST_NOT_FOUND; - break; - default: - *h_errnop = NO_RECOVERY; - break; - } - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > linebuflen)) - { - free (result); - *h_errnop = NETDB_INTERNAL; - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (data->linebuffer, result, len); - data->linebuffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - parse_res = parse_line (p, host, data, buflen, errnop, af, flags); - if (__glibc_unlikely (parse_res == -1)) - { - free (outkey); - *h_errnop = NETDB_INTERNAL; - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = 0; - } - while (!parse_res); - - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen, - int *errnop, int *h_errnop) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_gethostent_r (host, buffer, buflen, errnop, h_errnop, - (res_use_inet6 () ? AF_INET6 : AF_INET), - (res_use_inet6 () ? AI_V4MAPPED : 0 )); - - __libc_lock_unlock (lock); - - return status; -} - - -static enum nss_status -internal_gethostbyname2_r (const char *name, int af, struct hostent *host, - char *buffer, size_t buflen, int *errnop, - int *h_errnop, int flags) -{ - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); - buffer += pad; - - struct parser_data *data = (void *) buffer; - - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (yp_get_default_domain (&domain)) - return NSS_STATUS_UNAVAIL; - - if (buflen < sizeof *data + 1 + pad) - { - *h_errnop = NETDB_INTERNAL; - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - buflen -= pad; - - /* Convert name to lowercase. */ - size_t namlen = strlen (name); - /* Limit name length to the maximum size of an RPC packet. */ - if (namlen > UDPMSGSIZE) - { - *errnop = ERANGE; - return NSS_STATUS_UNAVAIL; - } - - char name2[namlen + 1]; - size_t i; - - for (i = 0; i < namlen; ++i) - name2[i] = tolower (name[i]); - name2[i] = '\0'; - - char *result; - int len; - int yperr = yp_match (domain, "hosts.byname", name2, namlen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - { - *h_errnop = TRY_AGAIN; - *errnop = errno; - } - if (retval == NSS_STATUS_NOTFOUND) - *h_errnop = HOST_NOT_FOUND; - return retval; - } - - const size_t linebuflen = buffer + buflen - data->linebuffer; - if (__glibc_unlikely ((size_t) (len + 1) > linebuflen)) - { - free (result); - *h_errnop = NETDB_INTERNAL; - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (data->linebuffer, result, len); - data->linebuffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = parse_line (p, host, data, buflen, errnop, af, flags); - - if (__glibc_unlikely (parse_res < 1 || host->h_addrtype != af)) - { - if (parse_res == -1) - { - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - else - { - *h_errnop = HOST_NOT_FOUND; - return NSS_STATUS_NOTFOUND; - } - } - - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host, - char *buffer, size_t buflen, int *errnop, - int *h_errnop) -{ - if (af != AF_INET && af != AF_INET6) - { - *h_errnop = HOST_NOT_FOUND; - return NSS_STATUS_NOTFOUND; - } - - return internal_gethostbyname2_r (name, af, host, buffer, buflen, errnop, - h_errnop, - (res_use_inet6 () ? AI_V4MAPPED : 0)); -} - - -enum nss_status -_nss_nis_gethostbyname_r (const char *name, struct hostent *host, char *buffer, - size_t buflen, int *errnop, int *h_errnop) -{ - if (res_use_inet6 ()) - { - enum nss_status status; - - status = internal_gethostbyname2_r (name, AF_INET6, host, buffer, buflen, - errnop, h_errnop, AI_V4MAPPED); - if (status == NSS_STATUS_SUCCESS) - return status; - } - - return internal_gethostbyname2_r (name, AF_INET, host, buffer, buflen, - errnop, h_errnop, 0); -} - - -enum nss_status -_nss_nis_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, - struct hostent *host, char *buffer, size_t buflen, - int *errnop, int *h_errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); - buffer += pad; - - struct parser_data *data = (void *) buffer; - if (__glibc_unlikely (buflen < sizeof *data + 1 + pad)) - { - *errnop = ERANGE; - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - buflen -= pad; - - char *buf = inet_ntoa (*(const struct in_addr *) addr); - - char *result; - int len; - int yperr = yp_match (domain, "hosts.byaddr", buf, strlen (buf), &result, - &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - { - *h_errnop = TRY_AGAIN; - *errnop = errno; - } - else if (retval == NSS_STATUS_NOTFOUND) - *h_errnop = HOST_NOT_FOUND; - - return retval; - } - - const size_t linebuflen = buffer + buflen - data->linebuffer; - if (__glibc_unlikely ((size_t) (len + 1) > linebuflen)) - { - free (result); - *errnop = ERANGE; - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (data->linebuffer, result, len); - data->linebuffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = parse_line (p, host, data, buflen, errnop, af, - (res_use_inet6 () ? AI_V4MAPPED : 0)); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - { - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - else - { - *h_errnop = HOST_NOT_FOUND; - return NSS_STATUS_NOTFOUND; - } - } - - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, - char *buffer, size_t buflen, int *errnop, - int *herrnop, int32_t *ttlp) -{ - char *domain; - if (yp_get_default_domain (&domain)) - { - *herrnop = NO_DATA; - return NSS_STATUS_UNAVAIL; - } - - /* Convert name to lowercase. */ - size_t namlen = strlen (name); - /* Limit name length to the maximum size of an RPC packet. */ - if (namlen > UDPMSGSIZE) - { - *errnop = ERANGE; - return NSS_STATUS_UNAVAIL; - } - - char name2[namlen + 1]; - size_t i; - - for (i = 0; i < namlen; ++i) - name2[i] = tolower (name[i]); - name2[i] = '\0'; - - char *result; - int len; - int yperr = yp_match (domain, "hosts.byname", name2, namlen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - { - *herrnop = TRY_AGAIN; - *errnop = errno; - } - if (retval == NSS_STATUS_NOTFOUND) - *herrnop = HOST_NOT_FOUND; - return retval; - } - - if (*pat == NULL) - { - uintptr_t pad = (-(uintptr_t) buffer - % __alignof__ (struct gaih_addrtuple)); - buffer += pad; - buflen = buflen > pad ? buflen - pad : 0; - - if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple))) - { - erange: - free (result); - *errnop = ERANGE; - *herrnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - - *pat = (struct gaih_addrtuple *) buffer; - buffer += sizeof (struct gaih_addrtuple); - buflen -= sizeof (struct gaih_addrtuple); - } - - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); - buffer += pad; - - struct parser_data *data = (void *) buffer; - - if (__glibc_unlikely (buflen < sizeof *data + 1 + pad)) - goto erange; - buflen -= pad; - - struct hostent host; - int parse_res = parse_line (result, &host, data, buflen, errnop, AF_UNSPEC, - 0); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - { - *herrnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - else - { - *herrnop = HOST_NOT_FOUND; - return NSS_STATUS_NOTFOUND; - } - } - - (*pat)->next = NULL; - (*pat)->family = host.h_addrtype; - memcpy ((*pat)->addr, host.h_addr_list[0], host.h_length); - (*pat)->scopeid = 0; - assert (host.h_addr_list[1] == NULL); - - /* Undo the alignment for parser_data. */ - buffer -= pad; - buflen += pad; - - size_t h_name_len = strlen (host.h_name) + 1; - if (h_name_len >= buflen) - goto erange; - (*pat)->name = memcpy (buffer, host.h_name, h_name_len); - - free (result); - - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c deleted file mode 100644 index 3784c101f7..0000000000 --- a/nis/nss_nis/nis-initgroups.c +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright (C) 1998-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <alloca.h> -#include <ctype.h> -#include <errno.h> -#include <grp.h> -#include <nss.h> -#include <pwd.h> -#include <string.h> -#include <unistd.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> -#include <sys/param.h> - -#include "nss-nis.h" -#include <libnsl.h> - -/* Get the declaration of the parser function. */ -#define ENTNAME grent -#define STRUCTURE group -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - - -static enum nss_status -internal_setgrent (char *domainname, intern_t *intern) -{ - struct ypall_callback ypcb; - enum nss_status status; - - ypcb.foreach = _nis_saveit; - ypcb.data = (char *) intern; - status = yperr2nss (yp_all (domainname, "group.byname", &ypcb)); - - /* Mark the last buffer as full. */ - if (intern->next != NULL) - intern->next->size = intern->offset; - - intern->next = intern->start; - intern->offset = 0; - - return status; -} - - -static enum nss_status -internal_getgrent_r (struct group *grp, char *buffer, size_t buflen, - int *errnop, intern_t *intern) -{ - if (intern->start == NULL) - return NSS_STATUS_NOTFOUND; - - /* Get the next entry until we found a correct one. */ - int parse_res; - do - { - struct response_t *bucket = intern->next; - - if (__glibc_unlikely (intern->offset >= bucket->size)) - { - if (bucket->next == NULL) - return NSS_STATUS_NOTFOUND; - - /* We look at all the content in the current bucket. Go on - to the next. */ - bucket = intern->next = bucket->next; - intern->offset = 0; - } - - char *p; - for (p = &bucket->mem[intern->offset]; isspace (*p); ++p) - ++intern->offset; - - size_t len = strlen (p) + 1; - if (__glibc_unlikely (len > buflen)) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - /* We unfortunately have to copy the data in the user-provided - buffer because that buffer might be around for a very long - time and the servent structure must remain valid. If we would - rely on the BUCKET memory the next 'setservent' or 'endservent' - call would destroy it. - - The important thing is that it is a single NUL-terminated - string. This is what the parsing routine expects. */ - p = memcpy (buffer, &bucket->mem[intern->offset], len); - - parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res == -1)) - return NSS_STATUS_TRYAGAIN; - - intern->offset += len; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - - -static int -get_uid (const char *user, uid_t *uidp) -{ - size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); - char *buf = (char *) alloca (buflen); - - while (1) - { - struct passwd result; - struct passwd *resp; - - int r = getpwnam_r (user, &result, buf, buflen, &resp); - if (r == 0 && resp != NULL) - { - *uidp = resp->pw_uid; - return 0; - } - - if (r != ERANGE) - break; - - buf = extend_alloca (buf, buflen, 2 * buflen); - } - - return 1; -} - - -static enum nss_status -initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size, - gid_t **groupsp, long int limit, int *errnop, - const char *domainname) -{ - /* Limit domainname length to the maximum size of an RPC packet. */ - if (strlen (domainname) > UDPMSGSIZE) - { - *errnop = ERANGE; - return NSS_STATUS_UNAVAIL; - } - - /* Prepare the key. The form is "unix.UID@DOMAIN" with the UID and - DOMAIN field filled in appropriately. */ - char key[sizeof ("unix.@") + sizeof (uid_t) * 3 + strlen (domainname)]; - ssize_t keylen = snprintf (key, sizeof (key), "unix.%lu@%s", - (unsigned long int) uid, domainname); - - char *result; - int reslen; - int yperr = yp_match (domainname, "netid.byname", key, keylen, &result, - &reslen); - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - return yperr2nss (yperr); - - /* Parse the result: following the colon is a comma separated list of - group IDs. */ - char *cp = strchr (result, ':'); - if (cp == NULL) - { - errout: - free (result); - return NSS_STATUS_NOTFOUND; - } - /* Skip the colon. */ - ++cp; - - gid_t *groups = *groupsp; - while (*cp != '\0') - { - char *endp; - unsigned long int gid = strtoul (cp, &endp, 0); - if (cp == endp) - goto errout; - if (*endp == ',') - ++endp; - else if (*endp != '\0') - goto errout; - cp = endp; - - if (gid == group) - /* We do not need this group again. */ - continue; - - /* Insert this group. */ - if (*start == *size) - { - /* Need a bigger buffer. */ - long int newsize; - - if (limit > 0 && *size == limit) - /* We reached the maximum. */ - break; - - if (limit <= 0) - newsize = 2 * *size; - else - newsize = MIN (limit, 2 * *size); - - gid_t *newgroups = realloc (groups, newsize * sizeof (*groups)); - if (newgroups == NULL) - goto errout; - *groupsp = groups = newgroups; - *size = newsize; - } - - groups[*start] = gid; - *start += 1; - } - - free (result); - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start, - long int *size, gid_t **groupsp, long int limit, - int *errnop) -{ - /* We always need the domain name. */ - char *domainname; - if (yp_get_default_domain (&domainname)) - return NSS_STATUS_UNAVAIL; - - /* Check whether we are supposed to use the netid.byname map. */ - if (_nsl_default_nss () & NSS_FLAG_NETID_AUTHORITATIVE) - { - /* We need the user ID. */ - uid_t uid; - - if (get_uid (user, &uid) == 0 - && initgroups_netid (uid, group, start, size, groupsp, limit, - errnop, domainname) == NSS_STATUS_SUCCESS) - return NSS_STATUS_SUCCESS; - } - - struct group grpbuf, *g; - size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); - char *tmpbuf; - enum nss_status status; - intern_t intern = { NULL, NULL, 0 }; - gid_t *groups = *groupsp; - - status = internal_setgrent (domainname, &intern); - if (status != NSS_STATUS_SUCCESS) - return status; - - tmpbuf = __alloca (buflen); - - while (1) - { - while ((status = - internal_getgrent_r (&grpbuf, tmpbuf, buflen, errnop, - &intern)) == NSS_STATUS_TRYAGAIN - && *errnop == ERANGE) - tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen); - - if (status != NSS_STATUS_SUCCESS) - { - if (status == NSS_STATUS_NOTFOUND) - status = NSS_STATUS_SUCCESS; - goto done; - } - - g = &grpbuf; - if (g->gr_gid != group) - { - char **m; - - for (m = g->gr_mem; *m != NULL; ++m) - if (strcmp (*m, user) == 0) - { - /* Matches user. Insert this group. */ - if (*start == *size) - { - /* Need a bigger buffer. */ - gid_t *newgroups; - long int newsize; - - if (limit > 0 && *size == limit) - /* We reached the maximum. */ - goto done; - - if (limit <= 0) - newsize = 2 * *size; - else - newsize = MIN (limit, 2 * *size); - - newgroups = realloc (groups, newsize * sizeof (*groups)); - if (newgroups == NULL) - { - status = NSS_STATUS_TRYAGAIN; - *errnop = errno; - goto done; - } - *groupsp = groups = newgroups; - *size = newsize; - } - - groups[*start] = g->gr_gid; - *start += 1; - - break; - } - } - } - -done: - while (intern.start != NULL) - { - intern.next = intern.start; - intern.start = intern.start->next; - free (intern.next); - } - - return status; -} diff --git a/nis/nss_nis/nis-netgrp.c b/nis/nss_nis/nis-netgrp.c deleted file mode 100644 index ab3835fffa..0000000000 --- a/nis/nss_nis/nis-netgrp.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <malloc.h> -#include <netdb.h> -#include <nss.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netgroup.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" - -extern enum nss_status -_nss_netgroup_parseline (char **cursor, struct __netgrent *netgrp, - char *buffer, size_t buflen, int *errnop); - - -static void -internal_nis_endnetgrent (struct __netgrent *netgrp) -{ - free (netgrp->data); - netgrp->data = NULL; - netgrp->data_size = 0; - netgrp->cursor = NULL; -} - - -enum nss_status -_nss_nis_setnetgrent (const char *group, struct __netgrent *netgrp) -{ - int len; - enum nss_status status; - - status = NSS_STATUS_SUCCESS; - - if (__glibc_unlikely (group == NULL || group[0] == '\0')) - return NSS_STATUS_UNAVAIL; - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - status = yperr2nss (yp_match (domain, "netgroup", group, strlen (group), - &netgrp->data, &len)); - if (__glibc_likely (status == NSS_STATUS_SUCCESS)) - { - /* Our implementation of yp_match already allocates a buffer - which is one byte larger than the value in LEN specifies - and the last byte is filled with NUL. So we can simply - use that buffer. */ - assert (len >= 0); - assert (netgrp->data[len] == '\0'); - - netgrp->data_size = len; - netgrp->cursor = netgrp->data; - } - - return status; -} - - -enum nss_status -_nss_nis_endnetgrent (struct __netgrent *netgrp) -{ - internal_nis_endnetgrent (netgrp); - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen, - int *errnop) -{ - return _nss_netgroup_parseline (&result->cursor, result, buffer, buflen, - errnop); -} diff --git a/nis/nss_nis/nis-network.c b/nis/nss_nis/nis-network.c deleted file mode 100644 index baf0ce4b8a..0000000000 --- a/nis/nss_nis/nis-network.c +++ /dev/null @@ -1,315 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -/* The following is an ugly trick to avoid a prototype declaration for - _nss_nis_endgrent. */ -#define _nss_nis_endnetent _nss_nis_endnetent_XXX -#include <netdb.h> -#undef _nss_nis_endnetent -#include <ctype.h> -#include <errno.h> -#include <stdint.h> -#include <string.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" - -/* Get the declaration of the parser function. */ -#define ENTNAME netent -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -__libc_lock_define_initialized (static, lock) - -static bool_t new_start = 1; -static char *oldkey; -static int oldkeylen; - -enum nss_status -_nss_nis_setnetent (int stayopen) -{ - __libc_lock_lock (lock); - - new_start = 1; - if (oldkey != NULL) - { - free (oldkey); - oldkey = NULL; - oldkeylen = 0; - } - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} -/* Make _nss_nis_endnetent an alias of _nss_nis_setnetent. We do this - even though the prototypes don't match. The argument of setnetent - is not used so this makes no difference. */ -strong_alias (_nss_nis_setnetent, _nss_nis_endnetent) - -static enum nss_status -internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen, - int *errnop, int *herrnop) -{ - struct parser_data *data = (void *) buffer; - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - /* Get the next entry until we found a correct one. */ - int parse_res; - do - { - char *result; - char *outkey; - int len; - int keylen; - int yperr; - - if (new_start) - yperr = yp_first (domain, "networks.byname", &outkey, &keylen, &result, - &len); - else - yperr = yp_next (domain, "networks.byname", oldkey, oldkeylen, &outkey, - &keylen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - { - *herrnop = NETDB_INTERNAL; - *errnop = errno; - } - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - *herrnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop); - if (__glibc_unlikely (parse_res == -1)) - { - free (outkey); - *herrnop = NETDB_INTERNAL; - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = 0; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen, - int *errnop, int *herrnop) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_getnetent_r (net, buffer, buflen, errnop, herrnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer, - size_t buflen, int *errnop, int *herrnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - *herrnop = NETDB_INTERNAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - struct parser_data *data = (void *) buffer; - if (buflen < sizeof *data + 1) - { - *herrnop = NETDB_INTERNAL; - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - /* Convert name to lowercase. */ - size_t namlen = strlen (name); - /* Limit name length to the maximum size of an RPC packet. */ - if (namlen > UDPMSGSIZE) - { - *errnop = ERANGE; - return NSS_STATUS_UNAVAIL; - } - - char name2[namlen + 1]; - size_t i; - - for (i = 0; i < namlen; ++i) - name2[i] = _tolower (name[i]); - name2[i] = '\0'; - - char *result; - int len; - int yperr = yp_match (domain, "networks.byname", name2, namlen, &result, - &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - { - *errnop = errno; - *herrnop = NETDB_INTERNAL; - } - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - *herrnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop); - - if (__glibc_unlikely (parse_res < 1)) - { - *herrnop = NETDB_INTERNAL; - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - else - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getnetbyaddr_r (uint32_t addr, int type, struct netent *net, - char *buffer, size_t buflen, int *errnop, - int *herrnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - struct in_addr in = { .s_addr = htonl (addr) }; - char *buf = inet_ntoa (in); - size_t blen = strlen (buf); - - while (1) - { - char *result; - int len; - - int yperr = yp_match (domain, "networks.byaddr", buf, blen, &result, - &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_NOTFOUND) - { - if (buf[blen - 2] == '.' && buf[blen - 1] == '0') - { - /* Try again, but with trailing dot(s) - removed (one by one) */ - buf[blen - 2] = '\0'; - blen -= 2; - continue; - } - else - return NSS_STATUS_NOTFOUND; - } - else - { - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - *herrnop = NETDB_INTERNAL; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_netent (p, net, (void *) buffer, - buflen, errnop); - - if (__glibc_unlikely (parse_res < 1)) - { - *herrnop = NETDB_INTERNAL; - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - else - return NSS_STATUS_SUCCESS; - } -} diff --git a/nis/nss_nis/nis-proto.c b/nis/nss_nis/nis-proto.c deleted file mode 100644 index df0739aaad..0000000000 --- a/nis/nss_nis/nis-proto.c +++ /dev/null @@ -1,278 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <netdb.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" - -/* Get the declaration of the parser function. */ -#define ENTNAME protoent -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -__libc_lock_define_initialized (static, lock) - -struct response -{ - struct response *next; - char val[0]; -}; - -static struct response *start; -static struct response *next; - -static int -saveit (int instatus, char *inkey, int inkeylen, char *inval, - int invallen, char *indata) -{ - if (instatus != YP_TRUE) - return 1; - - if (inkey && inkeylen > 0 && inval && invallen > 0) - { - struct response *newp = malloc (sizeof (struct response) + invallen + 1); - if (newp == NULL) - return 1; /* We have no error code for out of memory */ - - if (start == NULL) - start = newp; - else - next->next = newp; - next = newp; - - newp->next = NULL; - *((char *) mempcpy (newp->val, inval, invallen)) = '\0'; - } - - return 0; -} - -static void -internal_nis_endprotoent (void) -{ - while (start != NULL) - { - next = start; - start = start->next; - free (next); - } -} - -static enum nss_status -internal_nis_setprotoent (void) -{ - char *domainname; - struct ypall_callback ypcb; - enum nss_status status; - - yp_get_default_domain (&domainname); - - internal_nis_endprotoent (); - - ypcb.foreach = saveit; - ypcb.data = NULL; - status = yperr2nss (yp_all (domainname, "protocols.bynumber", &ypcb)); - next = start; - - return status; -} - -enum nss_status -_nss_nis_setprotoent (int stayopen) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_setprotoent (); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_endprotoent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endprotoent (); - next = NULL; - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -internal_nis_getprotoent_r (struct protoent *proto, - char *buffer, size_t buflen, int *errnop) -{ - struct parser_data *data = (void *) buffer; - int parse_res; - - if (start == NULL) - internal_nis_setprotoent (); - - /* Get the next entry until we found a correct one. */ - do - { - char *p; - - if (next == NULL) - return NSS_STATUS_NOTFOUND; - - p = strncpy (buffer, next->val, buflen); - - while (isspace (*p)) - ++p; - - parse_res = _nss_files_parse_protoent (p, proto, data, buflen, errnop); - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - next = next->next; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen, - int *errnop) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_getprotoent_r (proto, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getprotobyname_r (const char *name, struct protoent *proto, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char *result; - int len; - int yperr = yp_match (domain, "protocols.byname", name, strlen (name), - &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_protoent (p, proto, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getprotobynumber_r (int number, struct protoent *proto, - char *buffer, size_t buflen, int *errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char buf[32]; - int nlen = snprintf (buf, sizeof (buf), "%d", number); - - char *result; - int len; - int yperr = yp_match (domain, "protocols.bynumber", buf, nlen, &result, - &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_protoent (p, proto, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c deleted file mode 100644 index 188e80cd5d..0000000000 --- a/nis/nss_nis/nis-publickey.c +++ /dev/null @@ -1,234 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <syslog.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> -#include <rpc/key_prot.h> -#include <rpc/des_crypt.h> - -#include "nss-nis.h" - -/* If we haven't found the entry, we give a SUCCESS and an empty key back. - Solaris docu says: sizeof (pkey) == HEXKEYBYTES + 1. -*/ -enum nss_status -_nss_nis_getpublickey (const char *netname, char *pkey, int *errnop) -{ - pkey[0] = 0; - - if (netname == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain = strchr (netname, '@'); - if (domain == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - ++domain; - - char *result; - int len; - int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname), - &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (result != NULL) - { - char *p = strchr (result, ':'); - if (p != NULL) - *p = 0; - strncpy (pkey, result, HEXKEYBYTES + 1); - pkey[HEXKEYBYTES] = '\0'; - free (result); - } - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd, - int *errnop) -{ - skey[0] = 0; - - if (netname == NULL || passwd == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain = strchr (netname, '@'); - if (domain == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - ++domain; - - char *result; - int len; - int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname), - &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (result != NULL) - { - char *p = strchr (result, ':'); - if (p != NULL) - { - char buf[2 * (HEXKEYBYTES + 1)]; - - ++p; - strncpy (buf, p, 2 * (HEXKEYBYTES + 1)); - buf[2 * HEXKEYBYTES + 1] = '\0'; - if (xdecrypt (buf, passwd) - && memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) == 0) - { - buf[HEXKEYBYTES] = '\0'; - strcpy (skey, buf); - } - } - - free (result); - } - return NSS_STATUS_SUCCESS; -} - -/* Parse uid and group information from the passed string. - The format of the string passed is uid:gid,grp,grp, ... */ -static enum nss_status -parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp, - gid_t *gidlist) -{ - char *p, *ep; - int gidlen; - - if (!s || !isdigit (*s)) - { - syslog (LOG_ERR, "netname2user: expecting uid '%s'", s); - return NSS_STATUS_NOTFOUND; /* XXX need a better error */ - } - - /* Fetch the uid */ - *uidp = strtoul (s, NULL, 10); - - if (*uidp == 0) - { - syslog (LOG_ERR, "netname2user: should not have uid 0"); - return NSS_STATUS_NOTFOUND; - } - - /* Now get the group list */ - p = strchr (s, ':'); - if (!p) - { - syslog (LOG_ERR, "netname2user: missing group id list in '%s'", s); - return NSS_STATUS_NOTFOUND; - } - ++p; /* skip ':' */ - if (!p || (!isdigit (*p))) - { - syslog (LOG_ERR, "netname2user: missing group id list in '%s'.", p); - return NSS_STATUS_NOTFOUND; - } - - *gidp = strtoul (p, &ep, 10); - - gidlen = 0; - - /* After strtoul() ep should point to the first invalid character. - This is the marker "," we search for the next value. */ - while (ep != NULL && *ep == ',') - { - ep++; - p = ep; - gidlist[gidlen++] = strtoul (p, &ep, 10); - } - - *gidlenp = gidlen; - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, - gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop) -{ - char *domain = strchr (netname, '@'); - if (domain == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - /* Point past the '@' character */ - ++domain; - char *lookup = NULL; - int len; - int yperr = yp_match (domain, "netid.byname", netname, strlen (netname), - &lookup, &len); - switch (yperr) - { - case YPERR_SUCCESS: - break; /* the successful case */ - case YPERR_DOMAIN: - case YPERR_KEY: - return NSS_STATUS_NOTFOUND; - case YPERR_MAP: - default: - return NSS_STATUS_UNAVAIL; - } - - if (lookup == NULL) - return NSS_STATUS_NOTFOUND; - - - lookup[len] = '\0'; - - enum nss_status err = parse_netid_str (lookup, uidp, gidp, gidlenp, gidlist); - - free (lookup); - - return err; -} diff --git a/nis/nss_nis/nis-pwd.c b/nis/nss_nis/nis-pwd.c deleted file mode 100644 index 6a759eeaec..0000000000 --- a/nis/nss_nis/nis-pwd.c +++ /dev/null @@ -1,581 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <nss.h> -#include <pwd.h> -#include <string.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" -#include <libnsl.h> - -/* Get the declaration of the parser function. */ -#define ENTNAME pwent -#define STRUCTURE passwd -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -/* Protect global state against multiple changers */ -__libc_lock_define_initialized (static, lock) - -static bool new_start = true; -static char *oldkey; -static int oldkeylen; -static intern_t intern; - - -int -_nis_saveit (int instatus, char *inkey, int inkeylen, char *inval, - int invallen, char *indata) -{ - intern_t *intern = (intern_t *) indata; - - if (instatus != YP_TRUE) - return 1; - - if (inkey && inkeylen > 0 && inval && invallen > 0) - { - struct response_t *bucket = intern->next; - - if (__glibc_unlikely (bucket == NULL)) - { -#define MINSIZE 4096 - 4 * sizeof (void *) - const size_t minsize = MAX (MINSIZE, 2 * (invallen + 1)); - bucket = malloc (sizeof (struct response_t) + minsize); - if (bucket == NULL) - /* We have no error code for out of memory. */ - return 1; - - bucket->next = NULL; - bucket->size = minsize; - intern->start = intern->next = bucket; - intern->offset = 0; - } - else if (__builtin_expect (invallen + 1 > bucket->size - intern->offset, - 0)) - { - /* We need a new (larger) buffer. */ - const size_t newsize = 2 * MAX (bucket->size, invallen + 1); - struct response_t *newp = malloc (sizeof (struct response_t) - + newsize); - if (newp == NULL) - /* We have no error code for out of memory. */ - return 1; - - /* Mark the old bucket as full. */ - bucket->size = intern->offset; - - newp->next = NULL; - newp->size = newsize; - bucket = intern->next = bucket->next = newp; - intern->offset = 0; - } - - char *p = mempcpy (&bucket->mem[intern->offset], inval, invallen); - if (__glibc_unlikely (p[-1] != '\0')) - { - *p = '\0'; - ++invallen; - } - intern->offset += invallen; - } - - return 0; -} - - -static void -internal_nis_endpwent (void) -{ - new_start = true; - free (oldkey); - oldkey = NULL; - oldkeylen = 0; - - struct response_t *curr = intern.start; - - while (curr != NULL) - { - struct response_t *last = curr; - curr = curr->next; - free (last); - } - - intern.next = intern.start = NULL; -} - - -enum nss_status -_nss_nis_endpwent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endpwent (); - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -internal_nis_setpwent (void) -{ - /* We have to read all the data now. */ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - struct ypall_callback ypcb; - - ypcb.foreach = _nis_saveit; - ypcb.data = (char *) &intern; - enum nss_status status = yperr2nss (yp_all (domain, "passwd.byname", &ypcb)); - - - /* Mark the last buffer as full. */ - if (intern.next != NULL) - intern.next->size = intern.offset; - - intern.next = intern.start; - intern.offset = 0; - - return status; -} - - -enum nss_status -_nss_nis_setpwent (int stayopen) -{ - enum nss_status result = NSS_STATUS_SUCCESS; - - __libc_lock_lock (lock); - - internal_nis_endpwent (); - - if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) - result = internal_nis_setpwent (); - - __libc_lock_unlock (lock); - - return result; -} - - -static enum nss_status -internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen, - int *errnop) -{ - /* If we read the entire database at setpwent time we just iterate - over the data we have in memory. */ - bool batch_read = intern.start != NULL; - - char *domain = NULL; - if (!batch_read && __builtin_expect (yp_get_default_domain (&domain), 0)) - return NSS_STATUS_UNAVAIL; - - /* Get the next entry until we found a correct one. */ - int parse_res; - do - { - char *result; - char *outkey; - int len; - int keylen; - - if (batch_read) - { - struct response_t *bucket; - - handle_batch_read: - bucket = intern.next; - - if (__glibc_unlikely (intern.offset >= bucket->size)) - { - if (bucket->next == NULL) - return NSS_STATUS_NOTFOUND; - - /* We look at all the content in the current bucket. Go on - to the next. */ - bucket = intern.next = bucket->next; - intern.offset = 0; - } - - for (result = &bucket->mem[intern.offset]; isspace (*result); - ++result) - ++intern.offset; - - len = strlen (result); - } - else - { - int yperr; - - if (new_start) - { - /* Maybe we should read the database in one piece. */ - if ((_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) - && internal_nis_setpwent () == NSS_STATUS_SUCCESS - && intern.start != NULL) - { - batch_read = true; - goto handle_batch_read; - } - - yperr = yp_first (domain, "passwd.byname", &outkey, &keylen, - &result, &len); - } - else - yperr = yp_next (domain, "passwd.byname", oldkey, oldkeylen, - &outkey, &keylen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - } - - /* Check for adjunct style secret passwords. They can be - recognized by a password starting with "##". We do not use - it if the passwd.adjunct.byname table is supposed to be used - as a shadow.byname replacement. */ - char *p = strchr (result, ':'); - size_t namelen; - char *result2; - int len2; - if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0 - && p != NULL /* This better should be true in all cases. */ - && p[1] == '#' && p[2] == '#' - && (namelen = p - result, - yp_match (domain, "passwd.adjunct.byname", result, namelen, - &result2, &len2)) == YPERR_SUCCESS) - { - /* We found a passwd.adjunct.byname entry. Merge encrypted - password therein into original result. */ - char *encrypted = strchr (result2, ':'); - char *endp; - size_t restlen; - - if (encrypted == NULL - || (endp = strchr (++encrypted, ':')) == NULL - || (p = strchr (p + 1, ':')) == NULL) - { - /* Invalid format of the entry. This never should happen - unless the data from which the NIS table is generated is - wrong. We simply ignore it. */ - free (result2); - goto non_adjunct; - } - - restlen = len - (p - result); - if (__builtin_expect ((size_t) (namelen + (endp - encrypted) - + restlen + 2) > buflen, 0)) - { - free (result2); - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - mempcpy (mempcpy (mempcpy (mempcpy (buffer, result, namelen), - ":", 1), - encrypted, endp - encrypted), - p, restlen + 1); - p = buffer; - - free (result2); - } - else - { - non_adjunct: - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - p = buffer; - *((char *) mempcpy (buffer, result, len)) = '\0'; - } - - while (isspace (*p)) - ++p; - if (!batch_read) - free (result); - - parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res == -1)) - { - if (!batch_read) - free (outkey); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - if (batch_read) - intern.offset += len + 1; - else - { - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = false; - } - } - while (parse_res < 1); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen, - int *errnop) -{ - int status; - - __libc_lock_lock (lock); - - status = internal_nis_getpwent_r (result, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getpwnam_r (const char *name, struct passwd *pwd, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - size_t namelen = strlen (name); - - char *result; - int len; - int yperr = yp_match (domain, "passwd.byname", name, namelen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - /* Check for adjunct style secret passwords. They can be recognized - by a password starting with "##". We do not use it if the - passwd.adjunct.byname table is supposed to be used as a shadow.byname - replacement. */ - char *result2; - int len2; - char *p = strchr (result, ':'); - if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0 - && p != NULL /* This better should be true in all cases. */ - && p[1] == '#' && p[2] == '#' - && yp_match (domain, "passwd.adjunct.byname", name, namelen, - &result2, &len2) == YPERR_SUCCESS) - { - /* We found a passwd.adjunct.byname entry. Merge encrypted password - therein into original result. */ - char *encrypted = strchr (result2, ':'); - char *endp; - - if (encrypted == NULL - || (endp = strchr (++encrypted, ':')) == NULL - || (p = strchr (p + 1, ':')) == NULL) - { - /* Invalid format of the entry. This never should happen - unless the data from which the NIS table is generated is - wrong. We simply ignore it. */ - free (result2); - goto non_adjunct; - } - - size_t restlen = len - (p - result); - if (__builtin_expect ((size_t) (namelen + (endp - encrypted) - + restlen + 2) > buflen, 0)) - { - free (result2); - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen), - ":", 1), - encrypted, endp - encrypted), - p, restlen + 1); - p = buffer; - - free (result2); - } - else - { - non_adjunct: - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - p = strncpy (buffer, result, len); - buffer[len] = '\0'; - } - - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - else - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd, - char *buffer, size_t buflen, int *errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char buf[32]; - int nlen = snprintf (buf, sizeof (buf), "%lu", (unsigned long int) uid); - - char *result; - int len; - int yperr = yp_match (domain, "passwd.byuid", buf, nlen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - /* Check for adjunct style secret passwords. They can be recognized - by a password starting with "##". We do not use it if the - passwd.adjunct.byname table is supposed to be used as a shadow.byname - replacement. */ - char *result2; - int len2; - size_t namelen; - char *p = strchr (result, ':'); - if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0 - && p != NULL /* This better should be true in all cases. */ - && p[1] == '#' && p[2] == '#' - && (namelen = p - result, - yp_match (domain, "passwd.adjunct.byname", result, namelen, - &result2, &len2)) == YPERR_SUCCESS) - { - /* We found a passwd.adjunct.byname entry. Merge encrypted password - therein into original result. */ - char *encrypted = strchr (result2, ':'); - char *endp; - size_t restlen; - - if (encrypted == NULL - || (endp = strchr (++encrypted, ':')) == NULL - || (p = strchr (p + 1, ':')) == NULL) - { - /* Invalid format of the entry. This never should happen - unless the data from which the NIS table is generated is - wrong. We simply ignore it. */ - free (result2); - goto non_adjunct; - } - - restlen = len - (p - result); - if (__builtin_expect ((size_t) (namelen + (endp - encrypted) - + restlen + 2) > buflen, 0)) - { - free (result2); - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen), - ":", 1), - encrypted, endp - encrypted), - p, restlen + 1); - p = buffer; - - free (result2); - } - else - { - non_adjunct: - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - p = strncpy (buffer, result, len); - buffer[len] = '\0'; - } - - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - else - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-rpc.c b/nis/nss_nis/nis-rpc.c deleted file mode 100644 index 24e47e9884..0000000000 --- a/nis/nss_nis/nis-rpc.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <netdb.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" - -/* Get the declaration of the parser function. */ -#define ENTNAME rpcent -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -__libc_lock_define_initialized (static, lock) - -static intern_t intern; - - -static void -internal_nis_endrpcent (intern_t *intern) -{ - struct response_t *curr = intern->next; - - while (curr != NULL) - { - struct response_t *last = curr; - curr = curr->next; - free (last); - } - - intern->next = intern->start = NULL; -} - -static enum nss_status -internal_nis_setrpcent (intern_t *intern) -{ - char *domainname; - struct ypall_callback ypcb; - enum nss_status status; - - if (yp_get_default_domain (&domainname)) - return NSS_STATUS_UNAVAIL; - - internal_nis_endrpcent (intern); - - ypcb.foreach = _nis_saveit; - ypcb.data = (char *) intern; - status = yperr2nss (yp_all (domainname, "rpc.bynumber", &ypcb)); - - /* Mark the last buffer as full. */ - if (intern->next != NULL) - intern->next->size = intern->offset; - - intern->next = intern->start; - intern->offset = 0; - - return status; -} - -enum nss_status -_nss_nis_setrpcent (int stayopen) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_setrpcent (&intern); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_endrpcent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endrpcent (&intern); - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen, - int *errnop, intern_t *intern) -{ - struct parser_data *pdata = (void *) buffer; - int parse_res; - char *p; - - if (intern->start == NULL) - internal_nis_setrpcent (intern); - - if (intern->next == NULL) - /* Not one entry in the map. */ - return NSS_STATUS_NOTFOUND; - - /* Get the next entry until we found a correct one. */ - do - { - struct response_t *bucket = intern->next; - - if (__glibc_unlikely (intern->offset >= bucket->size)) - { - if (bucket->next == NULL) - return NSS_STATUS_NOTFOUND; - - /* We look at all the content in the current bucket. Go on - to the next. */ - bucket = intern->next = bucket->next; - intern->offset = 0; - } - - for (p = &bucket->mem[intern->offset]; isspace (*p); ++p) - ++intern->offset; - - size_t len = strlen (p) + 1; - if (__glibc_unlikely (len > buflen)) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - /* We unfortunately have to copy the data in the user-provided - buffer because that buffer might be around for a very long - time and the servent structure must remain valid. If we would - rely on the BUCKET memory the next 'setservent' or 'endservent' - call would destroy it. - - The important thing is that it is a single NUL-terminated - string. This is what the parsing routine expects. */ - p = memcpy (buffer, &bucket->mem[intern->offset], len); - - parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop); - if (__glibc_unlikely (parse_res == -1)) - return NSS_STATUS_TRYAGAIN; - - intern->offset += len; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen, - int *errnop) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - intern_t data = { NULL, NULL, 0 }; - enum nss_status status = internal_nis_setrpcent (&data); - if (__glibc_unlikely (status != NSS_STATUS_SUCCESS)) - return status; - - int found = 0; - while (!found && - ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, - &data)) == NSS_STATUS_SUCCESS)) - { - if (strcmp (rpc->r_name, name) == 0) - found = 1; - else - { - int i = 0; - - while (rpc->r_aliases[i] != NULL) - { - if (strcmp (rpc->r_aliases[i], name) == 0) - { - found = 1; - break; - } - else - ++i; - } - } - } - - internal_nis_endrpcent (&data); - - if (__glibc_unlikely (!found && status == NSS_STATUS_SUCCESS)) - return NSS_STATUS_NOTFOUND; - - return status; -} - -enum nss_status -_nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc, - char *buffer, size_t buflen, int *errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - char buf[32]; - int nlen = snprintf (buf, sizeof (buf), "%d", number); - - char *result; - int len; - int yperr = yp_match (domain, "rpc.bynumber", buf, nlen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_rpcent (p, rpc, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - else - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c deleted file mode 100644 index fe628aa139..0000000000 --- a/nis/nss_nis/nis-service.c +++ /dev/null @@ -1,438 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <netdb.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" -#include <libnsl.h> - - -/* Get the declaration of the parser function. */ -#define ENTNAME servent -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -__libc_lock_define_initialized (static, lock) - -static intern_t intern; - -struct search_t -{ - const char *name; - const char *proto; - int port; - enum nss_status status; - struct servent *serv; - char *buffer; - size_t buflen; - int *errnop; -}; - -static int -dosearch (int instatus, char *inkey, int inkeylen, char *inval, - int invallen, char *indata) -{ - struct search_t *req = (struct search_t *) indata; - - if (__glibc_unlikely (instatus != YP_TRUE)) - return 1; - - if (inkey && inkeylen > 0 && inval && invallen > 0) - { - if (__glibc_unlikely ((size_t) (invallen + 1) > req->buflen)) - { - *req->errnop = ERANGE; - req->status = NSS_STATUS_TRYAGAIN; - return 1; - } - - char *p = strncpy (req->buffer, inval, invallen); - req->buffer[invallen] = '\0'; - while (isspace (*p)) - ++p; - - int parse_res = _nss_files_parse_servent (p, req->serv, - (void *) req->buffer, - req->buflen, req->errnop); - if (parse_res == -1) - { - req->status = NSS_STATUS_TRYAGAIN; - return 1; - } - - if (!parse_res) - return 0; - - if (req->proto != NULL && strcmp (req->serv->s_proto, req->proto) != 0) - return 0; - - if (req->port != -1 && req->serv->s_port != req->port) - return 0; - - if (req->name != NULL && strcmp (req->serv->s_name, req->name) != 0) - { - char **cp; - for (cp = req->serv->s_aliases; *cp; cp++) - if (strcmp (req->name, *cp) == 0) - break; - - if (*cp == NULL) - return 0; - } - - req->status = NSS_STATUS_SUCCESS; - return 1; - } - - return 0; -} - -static void -internal_nis_endservent (void) -{ - struct response_t *curr = intern.next; - - while (curr != NULL) - { - struct response_t *last = curr; - curr = curr->next; - free (last); - } - - intern.next = intern.start = NULL; -} - -enum nss_status -_nss_nis_endservent (void) -{ - __libc_lock_lock (lock); - - internal_nis_endservent (); - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -internal_nis_setservent (void) -{ - char *domainname; - struct ypall_callback ypcb; - enum nss_status status; - - if (yp_get_default_domain (&domainname)) - return NSS_STATUS_UNAVAIL; - - internal_nis_endservent (); - - ypcb.foreach = _nis_saveit; - ypcb.data = (char *) &intern; - status = yperr2nss (yp_all (domainname, "services.byname", &ypcb)); - - /* Mark the last buffer as full. */ - if (intern.next != NULL) - intern.next->size = intern.offset; - - intern.next = intern.start; - intern.offset = 0; - - return status; -} - -enum nss_status -_nss_nis_setservent (int stayopen) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_setservent (); - - __libc_lock_unlock (lock); - - return status; -} - -static enum nss_status -internal_nis_getservent_r (struct servent *serv, char *buffer, - size_t buflen, int *errnop) -{ - struct parser_data *pdata = (void *) buffer; - int parse_res; - char *p; - - if (intern.start == NULL) - internal_nis_setservent (); - - if (intern.next == NULL) - /* Not one entry in the map. */ - return NSS_STATUS_NOTFOUND; - - /* Get the next entry until we found a correct one. */ - do - { - struct response_t *bucket = intern.next; - - if (__glibc_unlikely (intern.offset >= bucket->size)) - { - if (bucket->next == NULL) - return NSS_STATUS_NOTFOUND; - - /* We look at all the content in the current bucket. Go on - to the next. */ - bucket = intern.next = bucket->next; - intern.offset = 0; - } - - for (p = &bucket->mem[intern.offset]; isspace (*p); ++p) - ++intern.offset; - - size_t len = strlen (p) + 1; - if (__glibc_unlikely (len > buflen)) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - /* We unfortunately have to copy the data in the user-provided - buffer because that buffer might be around for a very long - time and the servent structure must remain valid. If we would - rely on the BUCKET memory the next 'setservent' or 'endservent' - call would destroy it. - - The important thing is that it is a single NUL-terminated - string. This is what the parsing routine expects. */ - p = memcpy (buffer, &bucket->mem[intern.offset], len); - - parse_res = _nss_files_parse_servent (p, serv, pdata, buflen, errnop); - if (__glibc_unlikely (parse_res == -1)) - return NSS_STATUS_TRYAGAIN; - - intern.offset += len; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen, - int *errnop) -{ - enum nss_status status; - - __libc_lock_lock (lock); - - status = internal_nis_getservent_r (serv, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getservbyname_r (const char *name, const char *protocol, - struct servent *serv, char *buffer, size_t buflen, - int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - /* If the protocol is given, we could try if our NIS server knows - about services.byservicename map. If yes, we only need one query. */ - size_t keylen = strlen (name) + (protocol ? 1 + strlen (protocol) : 0); - /* Limit key length to the maximum size of an RPC packet. */ - if (keylen > UDPMSGSIZE) - { - *errnop = ERANGE; - return NSS_STATUS_UNAVAIL; - } - - char key[keylen + 1]; - - /* key is: "name/proto" */ - char *cp = stpcpy (key, name); - if (protocol != NULL) - { - *cp++ = '/'; - strcpy (cp, protocol); - } - - char *result; - int int_len; - int status = yp_match (domain, "services.byservicename", key, - keylen, &result, &int_len); - size_t len = int_len; - - /* If we found the key, it's ok and parse the result. If not, - fall through and parse the complete table. */ - if (__glibc_likely (status == YPERR_SUCCESS)) - { - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_servent (p, serv, (void *) buffer, - buflen, errnop); - if (__glibc_unlikely (parse_res < 0)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - else - return NSS_STATUS_SUCCESS; - } - - /* Check if it is safe to rely on services.byservicename. */ - if (_nsl_default_nss () & NSS_FLAG_SERVICES_AUTHORITATIVE) - return yperr2nss (status); - - struct ypall_callback ypcb; - struct search_t req; - - ypcb.foreach = dosearch; - ypcb.data = (char *) &req; - req.name = name; - req.proto = protocol; - req.port = -1; - req.serv = serv; - req.buffer = buffer; - req.buflen = buflen; - req.errnop = errnop; - req.status = NSS_STATUS_NOTFOUND; - status = yp_all (domain, "services.byname", &ypcb); - - if (__glibc_unlikely (status != YPERR_SUCCESS)) - return yperr2nss (status); - - return req.status; -} - -enum nss_status -_nss_nis_getservbyport_r (int port, const char *protocol, - struct servent *serv, char *buffer, - size_t buflen, int *errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - /* If the protocol is given, we only need one query. - Otherwise try first port/tcp, then port/udp and then fallback - to sequential scanning of services.byname. */ - const char *proto = protocol != NULL ? protocol : "tcp"; - /* Limit protocol name length to the maximum size of an RPC packet. */ - if (strlen (proto) > UDPMSGSIZE) - { - *errnop = ERANGE; - return NSS_STATUS_UNAVAIL; - } - - do - { - /* key is: "port/proto" */ - char key[sizeof (int) * 3 + strlen (proto) + 2]; - size_t keylen = snprintf (key, sizeof (key), "%d/%s", ntohs (port), - proto); - - char *result; - int int_len; - int status = yp_match (domain, "services.byname", key, keylen, &result, - &int_len); - size_t len = int_len; - - /* If we found the key, it's ok and parse the result. If not, - fall through and parse the complete table. */ - if (__glibc_likely (status == YPERR_SUCCESS)) - { - if (__glibc_unlikely ((size_t) (len + 1) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - int parse_res = _nss_files_parse_servent (p, serv, (void *) buffer, - buflen, errnop); - if (__glibc_unlikely (parse_res < 0)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - - return NSS_STATUS_SUCCESS; - } - } - while (protocol == NULL && (proto[0] == 't' ? (proto = "udp") : NULL)); - - if (port == -1) - return NSS_STATUS_NOTFOUND; - - struct ypall_callback ypcb; - struct search_t req; - - ypcb.foreach = dosearch; - ypcb.data = (char *) &req; - req.name = NULL; - req.proto = protocol; - req.port = port; - req.serv = serv; - req.buffer = buffer; - req.buflen = buflen; - req.errnop = errnop; - req.status = NSS_STATUS_NOTFOUND; - int status = yp_all (domain, "services.byname", &ypcb); - - if (__glibc_unlikely (status != YPERR_SUCCESS)) - return yperr2nss (status); - - return req.status; -} diff --git a/nis/nss_nis/nis-spwd.c b/nis/nss_nis/nis-spwd.c deleted file mode 100644 index 45e9d964d2..0000000000 --- a/nis/nss_nis/nis-spwd.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. - - 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, see - <http://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -/* The following is an ugly trick to avoid a prototype declaration for - _nss_nis_endspent. */ -#define _nss_nis_endspent _nss_nis_endspent_XXX -#include <shadow.h> -#undef _nss_nis_endspent -#include <libc-lock.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> - -#include "nss-nis.h" -#include <libnsl.h> - -/* Get the declaration of the parser function. */ -#define ENTNAME spent -#define STRUCTURE spwd -#define EXTERN_PARSER -#include <nss/nss_files/files-parse.c> - -/* Protect global state against multiple changers */ -__libc_lock_define_initialized (static, lock) - -static bool new_start = true; -static bool ent_adjunct_used; -static char *oldkey; -static int oldkeylen; - -enum nss_status -_nss_nis_setspent (int stayopen) -{ - __libc_lock_lock (lock); - - new_start = true; - ent_adjunct_used = false; - free (oldkey); - oldkey = NULL; - oldkeylen = 0; - - __libc_lock_unlock (lock); - - return NSS_STATUS_SUCCESS; -} -/* Make _nss_nis_endspent an alias of _nss_nis_setspent. We do this - even though the prototypes don't match. The argument of setspent - is not used so this makes no difference. */ -strong_alias (_nss_nis_setspent, _nss_nis_endspent) - -static enum nss_status -internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen, - int *errnop) -{ - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - /* Get the next entry until we found a correct one. */ - int parse_res; - do - { - char *result; - char *outkey; - int len; - int keylen; - int yperr; - - if (new_start) - { - yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result, - &len); - if (__builtin_expect (yperr == YPERR_MAP, 0) - && (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW)) - { - free (result); - yperr = yp_first (domain, "passwd.adjunct.byname", &outkey, - &keylen, &result, &len); - ent_adjunct_used = true; - } - } - else - yperr = yp_next (domain, (ent_adjunct_used - ? "passwd.adjunct.byname" : "shadow.byname"), - oldkey, oldkeylen, &outkey, &keylen, &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__builtin_expect ((size_t) (len + (ent_adjunct_used ? 3 : 1)) - > buflen, 0)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - if (ent_adjunct_used) - /* This is an ugly trick. The format of passwd.adjunct.byname almost - matches the shadow.byname format except that the last two fields - are missing. Synthesize them by marking them empty. */ - strcpy (&buffer[len], "::"); - else - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen, - errnop); - if (__builtin_expect (parse_res == -1, 0)) - { - free (outkey); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - free (oldkey); - oldkey = outkey; - oldkeylen = keylen; - new_start = false; - } - while (!parse_res); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen, - int *errnop) -{ - int status; - - __libc_lock_lock (lock); - - status = internal_nis_getspent_r (result, buffer, buflen, errnop); - - __libc_lock_unlock (lock); - - return status; -} - -enum nss_status -_nss_nis_getspnam_r (const char *name, struct spwd *sp, - char *buffer, size_t buflen, int *errnop) -{ - if (name == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - const size_t name_len = strlen (name); - - char *domain; - if (__glibc_unlikely (yp_get_default_domain (&domain))) - return NSS_STATUS_UNAVAIL; - - bool adjunct_used = false; - char *result; - int len; - int yperr = yp_match (domain, "shadow.byname", name, name_len, &result, - &len); - if (__builtin_expect (yperr == YPERR_MAP, 0) - && (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW)) - { - free (result); - yperr = yp_match (domain, "passwd.adjunct.byname", name, name_len, - &result, &len); - adjunct_used = true; - } - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (__glibc_unlikely ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen)) - { - free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - char *p = strncpy (buffer, result, len); - if (__builtin_expect (adjunct_used, false)) - /* This is an ugly trick. The format of passwd.adjunct.byname almost - matches the shadow.byname format except that the last two fields - are missing. Synthesize them by marking them empty. */ - strcpy (&buffer[len], "::"); - else - buffer[len] = '\0'; - while (isspace (*p)) - ++p; - free (result); - - int parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen, - errnop); - if (__glibc_unlikely (parse_res < 1)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; - } - return NSS_STATUS_SUCCESS; -} |