diff options
Diffstat (limited to 'nis/nss_nisplus')
-rw-r--r-- | nis/nss_nisplus/nisplus-alias.c | 257 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-ethers.c | 251 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-grp.c | 380 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-hosts.c | 371 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-initgroups.c | 150 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-netgrp.c | 30 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-network.c | 318 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-parser.c | 252 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-proto.c | 323 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-publickey.c | 62 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-pwd.c | 388 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-rpc.c | 336 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-service.c | 341 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-spwd.c | 151 |
14 files changed, 1508 insertions, 2102 deletions
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c index 57858721a1..152e5fc3fc 100644 --- a/nis/nss_nisplus/nisplus-alias.c +++ b/nis/nss_nisplus/nisplus-alias.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,7 +17,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> #include <nss.h> #include <errno.h> #include <ctype.h> @@ -34,39 +32,32 @@ __libc_lock_define_initialized (static, lock) static nis_result *result; static u_long next_entry; static nis_name tablename_val; -static size_t tablename_len; +static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) static enum nss_status _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "mail_aliases.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "mail_aliases.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } @@ -79,87 +70,86 @@ _nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry, return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || __type_of (&NIS_RES_OBJECT (result)[entry]) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)[entry].EN_data.en_type, + || __type_of (&result->objects.objects_val[entry]) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val[entry].EN_data.en_type, "mail_aliases") != 0 - || NIS_RES_OBJECT (result)[entry].EN_data.en_cols.en_cols_len < 2) + || result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 2) return 0; - - if (NISENTRYLEN (entry, 1, result) >= buflen) - { - /* The line is too long for our buffer. */ - no_more_room: - *errnop = ERANGE; - return -1; - } - - char *cp = __stpncpy (buffer, NISENTRYVAL (entry, 1, result), - NISENTRYLEN (entry, 1, result)); - *cp = '\0'; - - char *first_unused = cp + 1; - size_t room_left = buflen - (first_unused - buffer); - - alias->alias_local = 0; - alias->alias_members_len = 0; - - if (NISENTRYLEN (entry, 0, result) >= room_left) - goto no_more_room; - - cp = __stpncpy (first_unused, NISENTRYVAL (entry, 0, result), - NISENTRYLEN (entry, 0, result)); - *cp = '\0'; - alias->alias_name = first_unused; - - /* Terminate the line for any case. */ - cp = strpbrk (alias->alias_name, "#\n"); - if (cp != NULL) - *cp = '\0'; - - size_t len = strlen (alias->alias_name) + 1; - first_unused += len; - room_left -= len; - - /* Adjust the pointer so it is aligned for - storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; - - alias->alias_members = (char **) first_unused; - - char *line = buffer; - while (*line != '\0') + else { - /* Skip leading blanks. */ - while (isspace (*line)) - ++line; - - if (*line == '\0') - break; + char *first_unused = buffer + NISENTRYLEN (0, 1, result) + 1; + size_t room_left = + buflen - (buflen % __alignof__ (char *)) - + NISENTRYLEN (0, 1, result) - 2; + char *line; + char *cp; + + if (NISENTRYLEN (entry, 1, result) >= buflen) + { + /* The line is too long for our buffer. */ + no_more_room: + *errnop = ERANGE; + return -1; + } + else + { + cp = __stpncpy (buffer, NISENTRYVAL (entry, 1, result), + NISENTRYLEN (entry, 1, result)); + *cp = '\0'; + } - if (room_left < sizeof (char *)) + if (NISENTRYLEN(entry, 0, result) >= room_left) goto no_more_room; - room_left -= sizeof (char *); - alias->alias_members[alias->alias_members_len] = line; - - while (*line != '\0' && *line != ',') - ++line; - if (line != alias->alias_members[alias->alias_members_len]) + alias->alias_local = 0; + alias->alias_members_len = 0; + *first_unused = '\0'; + ++first_unused; + cp = __stpncpy (first_unused, NISENTRYVAL (entry, 0, result), + NISENTRYLEN (entry, 0, result)); + *cp = '\0'; + alias->alias_name = first_unused; + + /* Terminate the line for any case. */ + cp = strpbrk (alias->alias_name, "#\n"); + if (cp != NULL) + *cp = '\0'; + + first_unused += strlen (alias->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 *)); + alias->alias_members = (char **) first_unused; + + line = buffer; + + while (*line != '\0') { - *line++ = '\0'; - ++alias->alias_members_len; + /* Skip leading blanks. */ + while (isspace (*line)) + ++line; + + if (*line == '\0') + break; + + if (room_left < sizeof (char *)) + goto no_more_room; + room_left -= sizeof (char *); + alias->alias_members[alias->alias_members_len] = line; + + while (*line != '\0' && *line != ',') + ++line; + + if (line != alias->alias_members[alias->alias_members_len]) + { + *line++ = '\0'; + alias->alias_members_len++; + } } - else if (*line == ',') - ++line; - } - return alias->alias_members_len == 0 ? 0 : 1; + return alias->alias_members_len == 0 ? 0 : 1; + } } static enum nss_status @@ -168,11 +158,9 @@ internal_setaliasent (void) enum nss_status status; int err; - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS) return NSS_STATUS_UNAVAIL; @@ -215,11 +203,9 @@ _nss_nisplus_endaliasent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; next_entry = 0; __libc_lock_unlock (lock); @@ -254,8 +240,7 @@ internal_nisplus_getaliasent_r (struct aliasent *alias, return NSS_STATUS_TRYAGAIN; ++next_entry; - } - while (!parse_res); + } while (!parse_res); return NSS_STATUS_SUCCESS; } @@ -283,12 +268,7 @@ _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias, if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } @@ -298,42 +278,35 @@ _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias, *errnop = EINVAL; return NSS_STATUS_UNAVAIL; } - - char buf[strlen (name) + 9 + tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - - if (result == NULL) + else { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + nis_result *result; + char buf[strlen (name) + 30 + tablename_len]; + int olderr = errno; - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); - nis_freeresult (result); - return status; - } + sprintf (buf, "[name=%s],%s", name, tablename_val); - parse_res = _nss_nisplus_parse_aliasent (result, 0, alias, - buffer, buflen, errnop); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - /* We do not need the lookup result anymore. */ - nis_freeresult (result); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + return niserr2nss (result->status); - if (__builtin_expect (parse_res < 1, 0)) - { - __set_errno (olderr); + parse_res = _nss_nisplus_parse_aliasent (result, 0, alias, + buffer, buflen, errnop); + if (parse_res < 1) + { + __set_errno (olderr); - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; - else - return NSS_STATUS_NOTFOUND; + if (parse_res == -1) + return NSS_STATUS_TRYAGAIN; + else + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c index 298869f931..028309c841 100644 --- a/nis/nss_nisplus/nisplus-ethers.c +++ b/nis/nss_nisplus/nisplus-ethers.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997,1998,2000-2003,2005,2006,2007 - Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -18,17 +17,15 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> -#include <ctype.h> -#include <errno.h> -#include <inttypes.h> -#include <netdb.h> #include <nss.h> +#include <errno.h> +#include <ctype.h> #include <string.h> +#include <bits/libc-lock.h> +#include <netdb.h> #include <netinet/ether.h> -#include <netinet/if_ether.h> #include <rpcsvc/nis.h> -#include <bits/libc-lock.h> +#include <netinet/if_ether.h> #include "nss-nisplus.h" @@ -39,11 +36,11 @@ static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].zo_data.objdata_u.en_data.en_cols.en_cols_val[col].ec_value.ec_value_val) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].zo_data.objdata_u.en_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) static int _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether, @@ -56,7 +53,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether, return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || NIS_RES_NUMOBJ (result) != 1 + || result->objects.objects_len != 1 || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "ethers_tbl") != 0 @@ -64,25 +61,16 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether, return 0; /* Generate the ether entry format and use the normal parser */ - if (NISENTRYLEN (0, 0, result) + 1 > room_left) + if (NISENTRYLEN (0, 0, result) +1 > room_left) { *errnop = ERANGE; return -1; } - char *cp = __stpncpy (p, NISENTRYVAL (0, 0, result), - NISENTRYLEN (0, 0, result)); - *cp = '\0'; - room_left -= NISENTRYLEN (0, 0, result) + 1; + strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result)); + room_left -= (NISENTRYLEN (0, 0, result) +1); ether->e_name = p; - struct ether_addr *ea = ether_aton (NISENTRYVAL (0, 1, result)); - if (ea == NULL) - { - *errnop = EINVAL; - return -2; - } - - ether->e_addr = *ea; + ether->e_addr = *ether_aton (NISENTRYVAL (0, 1, result)); return 1; } @@ -92,24 +80,18 @@ _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "ethers.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "ethers.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } return NSS_STATUS_SUCCESS; } @@ -125,11 +107,9 @@ _nss_nisplus_setetherent (int stayopen) __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS) status = NSS_STATUS_UNAVAIL; @@ -144,11 +124,9 @@ _nss_nisplus_endetherent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -159,6 +137,8 @@ static enum nss_status internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, size_t buflen, int *errnop) { + int parse_res; + if (tablename_val == NULL) { enum nss_status status = _nss_create_tablename (errnop); @@ -168,7 +148,6 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, } /* Get the next entry until we found a correct one. */ - int parse_res; do { nis_result *saved_result; @@ -177,23 +156,16 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, { saved_result = NULL; result = nis_first_entry (tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) return niserr2nss (result->status); } else { + nis_result *res2; + + res2 = nis_next_entry(tablename_val, &result->cookie); saved_result = result; - result = nis_next_entry (tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + result = res2; if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { nis_freeresult (saved_result); @@ -206,15 +178,17 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, if (parse_res == -1) { nis_freeresult (result); + *errnop = ERANGE; result = saved_result; return NSS_STATUS_TRYAGAIN; } + else + { + if (saved_result != NULL) + nis_freeresult (saved_result); + } - if (saved_result != NULL) - nis_freeresult (saved_result); - - } - while (!parse_res); + } while (!parse_res); return NSS_STATUS_SUCCESS; } @@ -238,6 +212,8 @@ enum nss_status _nss_nisplus_gethostton_r (const char *name, struct etherent *eth, char *buffer, size_t buflen, int *errnop) { + int parse_res; + if (tablename_val == NULL) { enum nss_status status = _nss_create_tablename (errnop); @@ -251,59 +227,56 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth, *errnop = EINVAL; return NSS_STATUS_UNAVAIL; } - - char buf[strlen (name) + 9 + tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); - - if (result == NULL) + else { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + nis_result *result; + char buf[strlen (name) + 40 + tablename_len]; + int olderr = errno; - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); - nis_freeresult (result); - return status; - } + sprintf (buf, "[name=%s],%s", name, tablename_val); - int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, - buflen, errnop); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - /* We do not need the lookup result anymore. */ - nis_freeresult (result); - - if (__builtin_expect (parse_res < 1, 0)) - { - __set_errno (olderr); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); + nis_freeresult (result); + return status; + } - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; + parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, + buflen, errnop); + if (parse_res < 1) + { + __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + if (parse_res == -1) + { + nis_freeresult (result); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } enum nss_status -_nss_nisplus_getntohost_r (const struct ether_addr *addr, struct etherent *eth, +_nss_nisplus_getntohost_r (const struct ether_addr *addr, + struct etherent *eth, char *buffer, size_t buflen, int *errnop) { if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } @@ -313,46 +286,44 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr, struct etherent *eth, *errnop = EINVAL; return NSS_STATUS_UNAVAIL; } - - char buf[26 + tablename_len]; - - snprintf (buf, sizeof (buf), - "[addr=%" PRIx8 ":%" PRIx8 ":%" PRIx8 ":%" PRIx8 ":%" PRIx8 - ":%" PRIx8 "],%s", - addr->ether_addr_octet[0], addr->ether_addr_octet[1], - addr->ether_addr_octet[2], addr->ether_addr_octet[3], - addr->ether_addr_octet[4], addr->ether_addr_octet[5], - tablename_val); - - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); - - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) + else { - enum nss_status status = niserr2nss (result->status); - nis_freeresult (result); - return status; - } + int parse_res; + nis_result *result; + char buf[255 + tablename_len]; - int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, - buflen, errnop); + sprintf (buf, "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir", + addr->ether_addr_octet[0], addr->ether_addr_octet[1], + addr->ether_addr_octet[2], addr->ether_addr_octet[3], + addr->ether_addr_octet[4], addr->ether_addr_octet[5]); - /* We do not need the lookup result anymore. */ - nis_freeresult (result); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) - return NSS_STATUS_TRYAGAIN; + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); + nis_freeresult (result); + return status; + } - return NSS_STATUS_NOTFOUND; + parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, + buflen, errnop); + if (parse_res < 1) + { + if (parse_res == -1) + { + nis_freeresult (result); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c index 7cc762fea9..daca94fc87 100644 --- a/nis/nss_nisplus/nisplus-grp.c +++ b/nis/nss_nisplus/nisplus-grp.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,7 +17,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> #include <nss.h> #include <grp.h> #include <ctype.h> @@ -29,110 +27,68 @@ #include "nss-nisplus.h" #include "nisplus-parser.h" -#include <libnsl.h> -#include <nis_intern.h> -#include <nis_xdr.h> - __libc_lock_define_initialized (static, lock); -/* Connection information. */ -static ib_request *ibreq; -static directory_obj *dir; -static dir_binding bptr; -static char *tablepath; -static char *tableptr; -/* Cursor. */ -static netobj cursor; - +static nis_result *result; +static unsigned long next_entry; +static nis_name tablename_val; +static u_long tablename_len; -nis_name grp_tablename_val attribute_hidden; -size_t grp_tablename_len attribute_hidden; - -enum nss_status -_nss_grp_create_tablename (int *errnop) +static enum nss_status +_nss_create_tablename (int *errnop) { - if (grp_tablename_val == NULL) + if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "group.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "group.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - grp_tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - if (atomic_compare_and_exchange_bool_acq (&grp_tablename_val, p, NULL)) - { - /* Another thread already installed the value. */ - free (p); - grp_tablename_len = strlen (grp_tablename_val); - } + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } - -static void -internal_endgrent (void) -{ - __nisbind_destroy (&bptr); - memset (&bptr, '\0', sizeof (bptr)); - - nis_free_directory (dir); - dir = NULL; - - nis_free_request (ibreq); - ibreq = NULL; - - xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor); - memset (&cursor, '\0', sizeof (cursor)); - - free (tablepath); - tableptr = tablepath = NULL; -} - - static enum nss_status -internal_setgrent (int *errnop) +internal_setgrent (void) { - enum nss_status status = NSS_STATUS_SUCCESS; + enum nss_status status; + int err; - if (grp_tablename_val == NULL) - status = _nss_grp_create_tablename (errnop); + if (result) + nis_freeresult (result); + result = NULL; + next_entry = 0; - if (status == NSS_STATUS_SUCCESS) - { - ibreq = __create_ib_request (grp_tablename_val, 0); - if (ibreq == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + if (tablename_val == NULL) + if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS) + return NSS_STATUS_UNAVAIL; - nis_error retcode = __prepare_niscall (grp_tablename_val, &dir, &bptr, 0); - if (retcode != NIS_SUCCESS) + result = nis_list (tablename_val, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); + if (result == NULL) + { + status = NSS_STATUS_TRYAGAIN; + __set_errno (ENOMEM); + } + else + { + status = niserr2nss (result->status); + if (status != NSS_STATUS_SUCCESS) { - nis_free_request (ibreq); - ibreq = NULL; - status = niserr2nss (retcode); + nis_freeresult (result); + result = NULL; } } - return status; } - enum nss_status _nss_nisplus_setgrent (int stayopen) { @@ -140,133 +96,58 @@ _nss_nisplus_setgrent (int stayopen) __libc_lock_lock (lock); - internal_endgrent (); - - // XXX We need to be able to set errno. Pass in new parameter. - int err; - status = internal_setgrent (&err); + status = internal_setgrent (); __libc_lock_unlock (lock); return status; } - enum nss_status _nss_nisplus_endgrent (void) { __libc_lock_lock (lock); - internal_endgrent (); + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); return NSS_STATUS_SUCCESS; } - static enum nss_status internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen, int *errnop) { - int parse_res = -1; - enum nss_status retval = NSS_STATUS_SUCCESS; + int parse_res; - /* Get the next entry until we found a correct one. */ - do + if (result == NULL) { - nis_error status; - nis_result result; - memset (&result, '\0', sizeof (result)); + enum nss_status status; - if (cursor.n_bytes == NULL) - { - if (ibreq == NULL) - { - retval = internal_setgrent (errnop); - if (retval != NSS_STATUS_SUCCESS) - return retval; - } - - status = __do_niscall3 (&bptr, NIS_IBFIRST, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, - (xdrproc_t) _xdr_nis_result, - (caddr_t) &result, - 0, NULL); - } - else - { - ibreq->ibr_cookie.n_bytes = cursor.n_bytes; - ibreq->ibr_cookie.n_len = cursor.n_len; - - status = __do_niscall3 (&bptr, NIS_IBNEXT, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, - (xdrproc_t) _xdr_nis_result, - (caddr_t) &result, - 0, NULL); - - ibreq->ibr_cookie.n_bytes = NULL; - ibreq->ibr_cookie.n_len = 0; - } - - if (status != NIS_SUCCESS) - return niserr2nss (status); + status = internal_setgrent (); + if (result == NULL || status != NSS_STATUS_SUCCESS) + return status; + } - if (NIS_RES_STATUS (&result) == NIS_NOTFOUND) - { - /* No more entries on this server. This means we have to go - to the next server on the path. */ - status = __follow_path (&tablepath, &tableptr, ibreq, &bptr); - if (status != NIS_SUCCESS) - return niserr2nss (status); - - directory_obj *newdir = NULL; - dir_binding newbptr; - status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0); - if (status != NIS_SUCCESS) - return niserr2nss (status); - - nis_free_directory (dir); - dir = newdir; - __nisbind_destroy (&bptr); - bptr = newbptr; - - xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie); - result.cookie.n_bytes = NULL; - result.cookie.n_len = 0; - parse_res = 0; - goto next; - } - else if (NIS_RES_STATUS (&result) != NIS_SUCCESS) - return niserr2nss (NIS_RES_STATUS (&result)); + /* Get the next entry until we found a correct one. */ + do + { + if (next_entry >= result->objects.objects_len) + return NSS_STATUS_NOTFOUND; - parse_res = _nss_nisplus_parse_grent (&result, gr, + parse_res = _nss_nisplus_parse_grent (result, next_entry, gr, buffer, buflen, errnop); - if (__builtin_expect (parse_res == -1, 0)) - { - *errnop = ERANGE; - retval = NSS_STATUS_TRYAGAIN; - goto freeres; - } + if (parse_res == -1) + return NSS_STATUS_TRYAGAIN; - next: - /* Free the old cursor. */ - xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor); - /* Remember the new one. */ - cursor.n_bytes = result.cookie.n_bytes; - cursor.n_len = result.cookie.n_len; - /* Free the result structure. NB: we do not remove the cookie. */ - result.cookie.n_bytes = NULL; - result.cookie.n_len = 0; - freeres: - xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result); - memset (&result, '\0', sizeof (result)); + ++next_entry; } while (!parse_res); - return retval; + return NSS_STATUS_SUCCESS; } enum nss_status @@ -290,9 +171,9 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr, { int parse_res; - if (grp_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_grp_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; @@ -303,101 +184,102 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr, *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } - - nis_result *result; - char buf[strlen (name) + 9 + grp_tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[name=%s],%s", name, grp_tablename_val); - - result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - - if (result == NULL) + else { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + nis_result *result; + char buf[strlen (name) + 24 + tablename_len]; + int olderr = errno; - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + sprintf (buf, "[name=%s],%s", name, tablename_val); - nis_freeresult (result); - return status; - } + result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop); - nis_freeresult (result); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) + if (result == NULL) { - *errnop = ERANGE; + *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } - else + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + enum nss_status status = niserr2nss (result->status); + + nis_freeresult (result); + return status; } - } - return NSS_STATUS_SUCCESS; + parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen, + errnop); + nis_freeresult (result); + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } enum nss_status _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop) { - if (grp_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_grp_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } - int parse_res; - nis_result *result; - char buf[8 + 3 * sizeof (unsigned long int) + grp_tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[gid=%lu],%s", - (unsigned long int) gid, grp_tablename_val); + { + int parse_res; + nis_result *result; + char buf[36 + tablename_len]; + int olderr = errno; - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + sprintf (buf, "[gid=%lu],%s", (unsigned long int) gid, tablename_val); - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - __set_errno (olderr); - - nis_freeresult (result); - return status; - } + __set_errno (olderr); - parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop); - - nis_freeresult (result); - if (__builtin_expect (parse_res < 1, 0)) - { - __set_errno (olderr); - - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else - return NSS_STATUS_NOTFOUND; - } - - return NSS_STATUS_SUCCESS; + nis_freeresult (result); + return status; + } + + parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen, + errnop); + + nis_freeresult (result); + if (parse_res < 1) + { + __set_errno (olderr); + + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; + } } diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c index f5f0ac96da..540469894e 100644 --- a/nis/nss_nisplus/nisplus-hosts.c +++ b/nis/nss_nisplus/nisplus-hosts.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2002, 2003, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -17,16 +17,15 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> -#include <ctype.h> -#include <errno.h> -#include <netdb.h> #include <nss.h> +#include <netdb.h> +#include <errno.h> +#include <ctype.h> #include <string.h> -#include <arpa/inet.h> #include <netinet/in.h> -#include <rpcsvc/nis.h> +#include <arpa/inet.h> #include <bits/libc-lock.h> +#include <rpcsvc/nis.h> #include "nss-nisplus.h" @@ -36,16 +35,15 @@ static nis_result *result; static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) /* Get implementation for some internal functions. */ #include <resolv/mapv4v6addr.h> - static int _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, char *buffer, size_t buflen, int *errnop, @@ -54,26 +52,27 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, unsigned int i; char *first_unused = buffer; size_t room_left = buflen; + char *data, *p, *line; if (result == NULL) return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || - __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ || - strcmp(NIS_RES_OBJECT (result)[0].EN_data.en_type, "hosts_tbl") != 0 || - NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4) + __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ || + strcmp(result->objects.objects_val[0].EN_data.en_type, + "hosts_tbl") != 0 || + result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 4) return 0; - char *data = first_unused; - - if (room_left < (af == AF_INET6 || (flags & AI_V4MAPPED) != 0 - ? IN6ADDRSZ : INADDRSZ)) + if (room_left < NISENTRYLEN (0, 2, result) + 1) { no_more_room: *errnop = ERANGE; return -1; } + data = first_unused; + /* Parse address. */ if (af == AF_INET && inet_pton (af, NISENTRYVAL (0, 2, result), data) > 0) { @@ -99,53 +98,51 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, /* Illegal address: ignore line. */ return 0; - first_unused += host->h_length; - room_left -= host->h_length; + first_unused+=host->h_length; + room_left-=host->h_length; if (NISENTRYLEN (0, 0, result) + 1 > room_left) goto no_more_room; + p = __stpncpy (first_unused, NISENTRYVAL (0, 0, result), + NISENTRYLEN (0, 0, result)); + *p = '\0'; + room_left -= (NISENTRYLEN (0, 0, result) + 1); host->h_name = first_unused; - first_unused = __stpncpy (first_unused, NISENTRYVAL (0, 0, result), - NISENTRYLEN (0, 0, result)); - *first_unused++ = '\0'; - room_left -= NISENTRYLEN (0, 0, result) + 1; - - /* XXX Rewrite at some point to allocate the array first and then - copy the strings. It wasteful to first concatenate the strings - to just split them again later. */ - char *line = first_unused; - for (i = 0; i < NIS_RES_NUMOBJ (result); ++i) + first_unused += NISENTRYLEN (0, 0, result) +1; + p = first_unused; + + line = p; + for (i = 0; i < result->objects.objects_len; ++i) { if (strcmp (NISENTRYVAL (i, 1, result), host->h_name) != 0) { if (NISENTRYLEN (i, 1, result) + 2 > room_left) goto no_more_room; - *first_unused++ = ' '; - first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result), - NISENTRYLEN (i, 1, result)); - *first_unused = '\0'; - room_left -= NISENTRYLEN (i, 1, result) + 1; + *p++ = ' '; + p = __stpncpy (p, NISENTRYVAL (i, 1, result), + NISENTRYLEN (i, 1, result)); + *p = '\0'; + room_left -= (NISENTRYLEN (i, 1, result) + 1); } } - *first_unused++ = '\0'; + *p++ = '\0'; + first_unused = p; /* Adjust the pointer so it is aligned for storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust + 3 * sizeof (char *)) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; + first_unused += __alignof__ (char *) - 1; + first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); host->h_addr_list = (char **) first_unused; + if (room_left < 2 * sizeof (char *)) + goto no_more_room; - room_left -= 3 * sizeof (char *); + room_left -= (2 * sizeof (char *)); host->h_addr_list[0] = data; host->h_addr_list[1] = NULL; host->h_aliases = &host->h_addr_list[2]; + host->h_aliases[0] = NULL; i = 0; while (*line != '\0') @@ -161,46 +158,41 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, goto no_more_room; room_left -= sizeof (char *); - host->h_aliases[i++] = line; + host->h_aliases[i] = line; while (*line != '\0' && *line != ' ') ++line; if (*line == ' ') - *line++ = '\0'; + { + *line = '\0'; + ++line; + ++i; + } + else + host->h_aliases[i+1] = NULL; } - - host->h_aliases[i] = NULL; - return 1; } - static enum nss_status _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "hosts.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "hosts.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } @@ -212,11 +204,9 @@ _nss_nisplus_sethostent (int stayopen) __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (tablename_val == NULL) status = _nss_create_tablename (&err); @@ -231,11 +221,9 @@ _nss_nisplus_endhostent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -265,11 +253,6 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer, } result = nis_first_entry (tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { enum nss_status retval = niserr2nss (result->status); @@ -284,13 +267,11 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer, } else { + nis_result *res2; + saved_res = result; - result = nis_next_entry (tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + res2 = nis_next_entry(tablename_val, &result->cookie); + result = res2; if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { enum nss_status retval= niserr2nss (result->status); @@ -354,12 +335,8 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host, if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) { *herrnop = NETDB_INTERNAL; @@ -373,81 +350,75 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host, *herrnop = NETDB_INTERNAL; return NSS_STATUS_NOTFOUND; } + else + { + nis_result *result; + char buf[strlen (name) + 255 + tablename_len]; + int olderr = errno; - nis_result *result; - char buf[strlen (name) + 10 + tablename_len]; - int olderr = errno; + /* Search at first in the alias list, and use the correct name + for the next search */ + sprintf (buf, "[name=%s],%s", name, tablename_val); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - /* Search at first in the alias list, and use the correct name - for the next search. */ - snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + if (result != NULL) + { + /* If we do not find it, try it as original name. But if the + database is correct, we should find it in the first case, too */ + if ((result->status != NIS_SUCCESS + && result->status != NIS_S_SUCCESS) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "hosts_tbl") != 0 + || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3) + sprintf (buf, "[cname=%s],%s", name, tablename_val); + else + sprintf (buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result), + tablename_val); - if (result != NULL) - { - char *bufptr = buf; - - /* If we did not find it, try it as original name. But if the - database is correct, we should find it in the first case, too. */ - if ((result->status != NIS_SUCCESS - && result->status != NIS_S_SUCCESS) - || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ - || strcmp (result->objects.objects_val->EN_data.en_type, - "hosts_tbl") != 0 - || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3) - snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val); - else + nis_freeresult (result); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + } + + if (result == NULL) { - /* We need to allocate a new buffer since there is no - guarantee the returned name has a length limit. */ - const char *entryval = NISENTRYVAL(0, 0, result); - size_t buflen = strlen (entryval) + 10 + tablename_len; - bufptr = alloca (buflen); - snprintf (bufptr, buflen, "[cname=%s],%s", - entryval, tablename_val); + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; } + retval = niserr2nss (result->status); + if (retval != NSS_STATUS_SUCCESS) + { + if (retval == NSS_STATUS_TRYAGAIN) + { + *errnop = errno; + *herrnop = NETDB_INTERNAL; + } + else + __set_errno (olderr); + nis_freeresult (result); + return retval; + } + + parse_res = _nss_nisplus_parse_hostent (result, af, host, buffer, + buflen, errnop, flags); nis_freeresult (result); - result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - } - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + if (parse_res > 0) + return NSS_STATUS_SUCCESS; - retval = niserr2nss (result->status); - if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0)) - { - if (retval == NSS_STATUS_TRYAGAIN) + *herrnop = NETDB_INTERNAL; + if (parse_res == -1) { - *errnop = errno; - *herrnop = NETDB_INTERNAL; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; } else - __set_errno (olderr); - nis_freeresult (result); - return retval; - } - - parse_res = _nss_nisplus_parse_hostent (result, af, host, buffer, - buflen, errnop, flags); - - nis_freeresult (result); - - if (parse_res > 0) - return NSS_STATUS_SUCCESS; - - *herrnop = NETDB_INTERNAL; - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } } - - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; } enum nss_status @@ -460,6 +431,17 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)); } +#if 0 +enum nss_status +_nss_nisplus_getipnodebyname_r (const char *name, int af, int flags, + struct hostent *result, char *buffer, + size_t buflen, int *errnop, int *herrnop) +{ + return internal_gethostbyname2_r (name, af, result, buffer, buflen, + errnop, herrnop, flags); +} +#endif + enum nss_status _nss_nisplus_gethostbyname_r (const char *name, struct hostent *host, char *buffer, size_t buflen, int *errnop, @@ -487,63 +469,62 @@ _nss_nisplus_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, { if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } if (addr == NULL) return NSS_STATUS_NOTFOUND; - - char buf[24 + tablename_len]; - int retval, parse_res; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[addr=%s],%s", - inet_ntoa (*(const struct in_addr *) addr), tablename_val); - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - - if (result == NULL) + else { - __set_errno (ENOMEM); - return NSS_STATUS_TRYAGAIN; - } + nis_result *result; + char buf[255 + tablename_len]; + int retval, parse_res; + int olderr = errno; - retval = niserr2nss (result->status); - if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0)) - { - if (retval == NSS_STATUS_TRYAGAIN) + sprintf (buf, "[addr=%s],%s", + inet_ntoa (*(const struct in_addr *) addr), tablename_val); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + + if (result == NULL) { - *errnop = errno; - *herrnop = NETDB_INTERNAL; + __set_errno (ENOMEM); + return NSS_STATUS_TRYAGAIN; } - else - __set_errno (olderr); - nis_freeresult (result); - return retval; - } + retval = niserr2nss (result->status); + if (retval != NSS_STATUS_SUCCESS) + { + if (retval == NSS_STATUS_TRYAGAIN) + { + *errnop = errno; + *herrnop = NETDB_INTERNAL; + } + else + __set_errno (olderr); + nis_freeresult (result); + return retval; + } - parse_res = _nss_nisplus_parse_hostent (result, af, host, - buffer, buflen, errnop, - ((_res.options & RES_USE_INET6) - ? AI_V4MAPPED : 0)); - nis_freeresult (result); + parse_res = _nss_nisplus_parse_hostent (result, af, host, + buffer, buflen, errnop, + ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)); + nis_freeresult (result); - if (parse_res > 0) - return NSS_STATUS_SUCCESS; + if (parse_res > 0) + return NSS_STATUS_SUCCESS; - *herrnop = NETDB_INTERNAL; - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; + *herrnop = NETDB_INTERNAL; + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } } - - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; } diff --git a/nis/nss_nisplus/nisplus-initgroups.c b/nis/nss_nisplus/nisplus-initgroups.c deleted file mode 100644 index 6588ec2533..0000000000 --- a/nis/nss_nisplus/nisplus-initgroups.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <atomic.h> -#include <nss.h> -#include <grp.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <bits/libc-lock.h> -#include <rpcsvc/nis.h> - -#include "nss-nisplus.h" -#include "nisplus-parser.h" -#include <libnsl.h> -#include <nis_intern.h> -#include <nis_xdr.h> - -#define NISOBJVAL(col, obj) \ - ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) - -#define NISOBJLEN(col, obj) \ - ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) - -extern nis_name grp_tablename_val attribute_hidden; -extern size_t grp_tablename_len attribute_hidden; -extern enum nss_status _nss_grp_create_tablename (int *errnop); - - -enum nss_status -_nss_nisplus_initgroups_dyn (const char *user, gid_t group, long int *start, - long int *size, gid_t **groupsp, long int limit, - int *errnop) -{ - if (grp_tablename_val == NULL) - { - enum nss_status status = _nss_grp_create_tablename (errnop); - - if (status != NSS_STATUS_SUCCESS) - return status; - } - - nis_result *result; - char buf[strlen (user) + 12 + grp_tablename_len]; - - snprintf (buf, sizeof (buf), "[members=%s],%s", user, grp_tablename_val); - - result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | ALL_RESULTS, NULL, NULL); - - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); - - nis_freeresult (result); - return status; - } - - if (NIS_RES_NUMOBJ (result) == 0) - { - errout: - nis_freeresult (result); - return NSS_STATUS_NOTFOUND; - } - - gid_t *groups = *groupsp; - nis_object *obj = NIS_RES_OBJECT (result); - for (unsigned int cnt = 0; cnt < NIS_RES_NUMOBJ (result); ++cnt, ++obj) - { - if (__type_of (obj) != NIS_ENTRY_OBJ - || strcmp (obj->EN_data.en_type, "group_tbl") != 0 - || obj->EN_data.en_cols.en_cols_len < 4) - continue; - - char *numstr = NISOBJVAL (2, obj); - size_t len = NISOBJLEN (2, obj); - if (len == 0 || numstr[0] == '\0') - continue; - - gid_t gid; - char *endp; - if (__builtin_expect (numstr[len - 1] != '\0', 0)) - { - char numstrbuf[len + 1]; - memcpy (numstrbuf, numstr, len); - numstrbuf[len] = '\0'; - gid = strtoul (numstrbuf, &endp, 10); - if (*endp) - continue; - } - else - { - gid = strtoul (numstr, &endp, 10); - if (*endp) - continue; - } - - if (gid == group) - 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; - } - - nis_freeresult (result); - return NSS_STATUS_SUCCESS; -} diff --git a/nis/nss_nisplus/nisplus-netgrp.c b/nis/nss_nisplus/nisplus-netgrp.c index 24303b1474..607bc2c1ca 100644 --- a/nis/nss_nisplus/nisplus-netgrp.c +++ b/nis/nss_nisplus/nisplus-netgrp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -27,11 +27,11 @@ #include "nss-nisplus.h" -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) enum nss_status _nss_nisplus_getnetgrent_r (struct __netgrent *result, char *buffer, @@ -141,23 +141,29 @@ _nss_nisplus_getnetgrent_r (struct __netgrent *result, char *buffer, static void internal_endnetgrent (struct __netgrent *netgrp) { - nis_freeresult ((nis_result *) netgrp->data); - netgrp->data = NULL; - netgrp->data_size = 0; - netgrp->position = 0; + if (netgrp->data != NULL) + { + nis_freeresult ((nis_result *) netgrp->data); + netgrp->data = NULL; + netgrp->data_size = 0; + netgrp->position = 0; + } } enum nss_status _nss_nisplus_setnetgrent (const char *group, struct __netgrent *netgrp) { - char buf[strlen (group) + 25]; + enum nss_status status; + char buf[strlen (group) + 30]; if (group == NULL || group[0] == '\0') return NSS_STATUS_UNAVAIL; - enum nss_status status = NSS_STATUS_SUCCESS; + status = NSS_STATUS_SUCCESS; + + internal_endnetgrent (netgrp); - snprintf (buf, sizeof (buf), "[name=%s],netgroup.org_dir", group); + sprintf (buf, "[name=%s],netgroup.org_dir", group); netgrp->data = (char *) nis_list (buf, EXPAND_NAME, NULL, NULL); diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c index 1cf652f071..422b02b82a 100644 --- a/nis/nss_nisplus/nisplus-network.c +++ b/nis/nss_nisplus/nisplus-network.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997,1998,2000-2003,2005,2006,2007 - Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,16 +17,15 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> -#include <ctype.h> -#include <errno.h> -#include <netdb.h> #include <nss.h> +#include <netdb.h> +#include <errno.h> +#include <ctype.h> #include <stdint.h> #include <string.h> #include <arpa/inet.h> -#include <rpcsvc/nis.h> #include <bits/libc-lock.h> +#include <rpcsvc/nis.h> #include "nss-nisplus.h" @@ -37,31 +35,33 @@ static nis_result *result; static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) static int _nss_nisplus_parse_netent (nis_result *result, struct netent *network, - char *buffer, size_t buflen, int *errnop) + char *buffer, size_t buflen, int *errnop) { char *first_unused = buffer; size_t room_left = buflen; + unsigned int i; + char *p, *line; if (result == NULL) return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val[0].EN_data.en_type, "networks_tbl") != 0 - || NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 3) + || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3) return 0; - if (NISENTRYLEN (0, 0, result) >= room_left) + if (NISENTRYLEN(0, 0, result) >= room_left) { /* The line is too long for our buffer. */ no_more_room: @@ -69,56 +69,50 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network, return -1; } - strncpy (first_unused, NISENTRYVAL (0, 0, result), + strncpy (first_unused, NISENTRYVAL(0, 0, result), NISENTRYLEN (0, 0, result)); first_unused[NISENTRYLEN (0, 0, result)] = '\0'; network->n_name = first_unused; - size_t len = strlen (first_unused) + 1; - room_left -= len; - first_unused += len; - + room_left -= (strlen (first_unused) +1); + first_unused += strlen (first_unused) +1; network->n_addrtype = 0; network->n_net = inet_network (NISENTRYVAL (0, 2, result)); + p = first_unused; - /* XXX Rewrite at some point to allocate the array first and then - copy the strings. It wasteful to first concatenate the strings - to just split them again later. */ - char *line = first_unused; - for (unsigned int i = 0; i < NIS_RES_NUMOBJ (result); ++i) + line = p; + for (i = 0; i < result->objects.objects_len; ++i) { if (strcmp (NISENTRYVAL (i, 1, result), network->n_name) != 0) { if (NISENTRYLEN (i, 1, result) + 2 > room_left) goto no_more_room; - *first_unused++ = ' '; - first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result), - NISENTRYLEN (i, 1, result)); + *p++ = ' '; + p = __stpncpy (p, NISENTRYVAL (i, 1, result), + NISENTRYLEN (i, 1, result)); + *p = '\0'; room_left -= (NISENTRYLEN (i, 1, result) + 1); } } - *first_unused++ = '\0'; + *p++ = '\0'; + first_unused = p; /* Adjust the pointer so it is aligned for storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust + sizeof (char *)) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; + first_unused += __alignof__ (char *) - 1; + first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); network->n_aliases = (char **) first_unused; + if (room_left < 2 * sizeof (char *)) + goto no_more_room; + room_left -= (2 * sizeof (char *)); + network->n_aliases[0] = NULL; - /* For the terminating NULL pointer. */ - room_left -= sizeof (char *); - - unsigned int i = 0; + i = 0; while (*line != '\0') { /* Skip leading blanks. */ while (isspace (*line)) - ++line; + line++; if (*line == '\0') break; @@ -127,45 +121,42 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network, goto no_more_room; room_left -= sizeof (char *); - network->n_aliases[i++] = line; + network->n_aliases[i] = line; while (*line != '\0' && *line != ' ') ++line; if (*line == ' ') - *line++ = '\0'; + { + *line = '\0'; + ++line; + ++i; + } + else + network->n_aliases[i+1] = NULL; } - network->n_aliases[i] = NULL; return 1; } - static enum nss_status _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "networks.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "networks.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } @@ -173,20 +164,16 @@ enum nss_status _nss_nisplus_setnetent (int stayopen) { enum nss_status status = NSS_STATUS_SUCCESS; + int err; __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (tablename_val == NULL) - { - int err; - status = _nss_create_tablename (&err); - } + status = _nss_create_tablename (&err); __libc_lock_unlock (lock); @@ -198,11 +185,9 @@ _nss_nisplus_endnetent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -233,14 +218,11 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer, } result = nis_first_entry (tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { - int retval = niserr2nss (result->status); + int retval; + + retval = niserr2nss (result->status); nis_freeresult (result); result = NULL; if (retval == NSS_STATUS_TRYAGAIN) @@ -255,16 +237,16 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer, } else { + nis_result *res; + + res = nis_next_entry (tablename_val, &result->cookie); saved_res = result; - result = nis_next_entry (tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + result = res; if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { - int retval = niserr2nss (result->status); + int retval; + + retval = niserr2nss (result->status); nis_freeresult (result); result = saved_res; if (retval == NSS_STATUS_TRYAGAIN) @@ -284,8 +266,7 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer, return NSS_STATUS_TRYAGAIN; } - } - while (!parse_res); + } while (!parse_res); return NSS_STATUS_SUCCESS; } @@ -315,12 +296,8 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network, if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } @@ -331,83 +308,76 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network, *herrnop = NETDB_INTERNAL; return NSS_STATUS_UNAVAIL; } + else + { + nis_result *result; + char buf[strlen (name) + 255 + tablename_len]; + int olderr = errno; - nis_result *result; - char buf[strlen (name) + 10 + tablename_len]; - int olderr = errno; + /* Search at first in the alias list, and use the correct name + for the next search */ + sprintf (buf, "[name=%s],%s", name, tablename_val); + result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - /* Search at first in the alias list, and use the correct name - for the next search */ - snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | USE_DGRAM, NULL, NULL); + if (result != NULL) + { + /* If we do not find it, try it as original name. But if the + database is correct, we should find it in the first case, too */ + if ((result->status != NIS_SUCCESS + && result->status != NIS_S_SUCCESS) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val[0].EN_data.en_type, + "networks_tbl") != 0 + || (result->objects.objects_val[0].EN_data.en_cols.en_cols_len + < 3)) + sprintf (buf, "[cname=%s],%s", name, tablename_val); + else + sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result), + tablename_val); + + nis_freeresult (result); + result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); + } - if (result != NULL) - { - char *bufptr = buf; - - /* If we do not find it, try it as original name. But if the - database is correct, we should find it in the first case, too */ - if ((result->status != NIS_SUCCESS - && result->status != NIS_S_SUCCESS) - || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ - || strcmp (result->objects.objects_val[0].EN_data.en_type, - "networks_tbl") != 0 - || (result->objects.objects_val[0].EN_data.en_cols.en_cols_len - < 3)) - snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val); - else + if (result == NULL) + { + __set_errno (ENOMEM); + return NSS_STATUS_TRYAGAIN; + } + retval = niserr2nss (result->status); + if (retval != NSS_STATUS_SUCCESS) { - /* We need to allocate a new buffer since there is no - guarantee the returned name has a length limit. */ - const char *entryval = NISENTRYVAL (0, 0, result); - size_t buflen = strlen (entryval) + 10 + tablename_len; - bufptr = alloca (buflen); - snprintf (bufptr, buflen, "[cname=%s],%s", - entryval, tablename_val); + if (retval == NSS_STATUS_TRYAGAIN) + { + *errnop = errno; + *herrnop = NETDB_INTERNAL; + } + else + __set_errno (olderr); + nis_freeresult (result); + return retval; } + parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen, + errnop); + nis_freeresult (result); - result = nis_list (bufptr, FOLLOW_LINKS | FOLLOW_PATH | USE_DGRAM, - NULL, NULL); - } - if (result == NULL) - { - __set_errno (ENOMEM); - return NSS_STATUS_TRYAGAIN; - } + if (parse_res > 0) + return NSS_STATUS_SUCCESS; - retval = niserr2nss (result->status); - if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0)) - { - if (retval == NSS_STATUS_TRYAGAIN) + *herrnop = NETDB_INTERNAL; + if (parse_res == -1) { - *errnop = errno; - *herrnop = NETDB_INTERNAL; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; } else - __set_errno (olderr); - nis_freeresult (result); - return retval; - } - - parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen, - errnop); - - nis_freeresult (result); - - if (parse_res > 0) - return NSS_STATUS_SUCCESS; - - *herrnop = NETDB_INTERNAL; - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } } - - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; } /* XXX type is ignored, SUN's NIS+ table doesn't support it */ @@ -418,48 +388,48 @@ _nss_nisplus_getnetbyaddr_r (uint32_t addr, const int type, { if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } { - char buf[27 + tablename_len]; - char buf2[18]; + int parse_res, retval; + nis_result *result; + char buf[1024 + tablename_len]; + struct in_addr in; + char buf2[256]; + int b2len; int olderr = errno; - struct in_addr in = inet_makeaddr (addr, 0); + in = inet_makeaddr (addr, 0); strcpy (buf2, inet_ntoa (in)); - size_t b2len = strlen (buf2); + b2len = strlen (buf2); while (1) { - snprintf (buf, sizeof (buf), "[addr=%s],%s", buf2, tablename_val); - nis_result *result = nis_list (buf, EXPAND_NAME | USE_DGRAM, - NULL, NULL); + sprintf (buf, "[addr=%s],%s", buf2, tablename_val); + result = nis_list (buf, EXPAND_NAME, NULL, NULL); if (result == NULL) { __set_errno (ENOMEM); return NSS_STATUS_TRYAGAIN; } - enum nss_status retval = niserr2nss (result->status); - if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0)) + retval = niserr2nss (result->status); + if (retval != NSS_STATUS_SUCCESS) { - if (b2len > 2 && buf2[b2len - 2] == '.' && buf2[b2len - 1] == '0') + if (buf2[b2len -2] == '.' && buf2[b2len -1] == '0') { /* Try again, but with trailing dot(s) removed (one by one) */ buf2[b2len - 2] = '\0'; b2len -= 2; - nis_freeresult (result); continue; } + else + return NSS_STATUS_NOTFOUND; if (retval == NSS_STATUS_TRYAGAIN) { @@ -472,8 +442,8 @@ _nss_nisplus_getnetbyaddr_r (uint32_t addr, const int type, return retval; } - int parse_res = _nss_nisplus_parse_netent (result, network, buffer, - buflen, errnop); + parse_res = _nss_nisplus_parse_netent (result, network, buffer, + buflen, errnop); nis_freeresult (result); diff --git a/nis/nss_nisplus/nisplus-parser.c b/nis/nss_nisplus/nisplus-parser.c index 1e1a343d52..b61733a628 100644 --- a/nis/nss_nisplus/nisplus-parser.c +++ b/nis/nss_nisplus/nisplus-parser.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -25,36 +25,33 @@ #include "nisplus-parser.h" -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) - -#define NISOBJVAL(col, obj) \ - ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) - -#define NISOBJLEN(col, obj) \ - ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) int _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw, char *buffer, size_t buflen, int *errnop) { - if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || NIS_RES_NUMOBJ (result) != 1 - || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0 - || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7) - return 0; - - nis_object *obj = NIS_RES_OBJECT (result); char *first_unused = buffer; size_t room_left = buflen; size_t len; - if (NISOBJLEN (0, obj) >= room_left) + if (result == NULL) + return 0; + + if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) + || result->objects.objects_len != 1 + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "passwd_tbl") != 0 + || result->objects.objects_val->EN_data.en_cols.en_cols_len < 7) + return 0; + + if (NISENTRYLEN (0, 0, result) >= room_left) { /* The line is too long for our buffer. */ no_more_room: @@ -62,109 +59,111 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw, return -1; } - strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj)); - first_unused[NISOBJLEN (0, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (0, 0, result), + NISENTRYLEN (0, 0, result)); + first_unused[NISENTRYLEN (0, 0, result)] = '\0'; len = strlen (first_unused); if (len == 0) /* No name ? Should never happen, database is corrupt */ return 0; pw->pw_name = first_unused; - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); - if (NISOBJLEN (1, obj) >= room_left) + if (NISENTRYLEN (0, 1, result) >= room_left) goto no_more_room; - strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj)); - first_unused[NISOBJLEN (1, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (0, 1, result), + NISENTRYLEN (0, 1, result)); + first_unused[NISENTRYLEN (0, 1, result)] = '\0'; pw->pw_passwd = first_unused; len = strlen (first_unused); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); - char *numstr = NISOBJVAL (2, obj); - len = NISOBJLEN (2, obj); - if (len == 0 && numstr[len - 1] != '\0') - { - if (len >= room_left) - goto no_more_room; + if (NISENTRYLEN(0, 2, result) >= room_left) + goto no_more_room; - strncpy (first_unused, numstr, len); - first_unused[len] = '\0'; - numstr = first_unused; - } - if (numstr[0] == '\0') - /* If we don't have a uid, it's an invalid shadow entry. */ + strncpy (first_unused, NISENTRYVAL (0, 2, result), + NISENTRYLEN (0, 2, result)); + first_unused[NISENTRYLEN (0, 2, result)] = '\0'; + len = strlen (first_unused); + if (len == 0) /* If we don't have a uid, it's an invalid shadow entry */ return 0; - pw->pw_uid = strtoul (numstr, NULL, 10); + pw->pw_uid = strtoul (first_unused, NULL, 10); + room_left -= (len + 1); + first_unused += (len + 1); - numstr = NISOBJVAL (3, obj); - len = NISOBJLEN (3, obj); - if (len == 0 && numstr[len - 1] != '\0') - { - if (len >= room_left) - goto no_more_room; + if (NISENTRYLEN (0, 3, result) >= room_left) + goto no_more_room; - strncpy (first_unused, numstr, len); - first_unused[len] = '\0'; - numstr = first_unused; - } - if (numstr[0] == '\0') - /* If we don't have a gid, it's an invalid shadow entry. */ + strncpy (first_unused, NISENTRYVAL (0, 3, result), + NISENTRYLEN (0, 3, result)); + first_unused[NISENTRYLEN (0, 3, result)] = '\0'; + len = strlen (first_unused); + if (len == 0) /* If we don't have a gid, it's an invalid shadow entry */ return 0; - pw->pw_gid = strtoul (numstr, NULL, 10); + pw->pw_gid = strtoul (first_unused, NULL, 10); + room_left -= (len + 1); + first_unused += (len + 1); - if (NISOBJLEN(4, obj) >= room_left) + if (NISENTRYLEN(0, 4, result) >= room_left) goto no_more_room; - strncpy (first_unused, NISOBJVAL (4, obj), NISOBJLEN (4, obj)); - first_unused[NISOBJLEN (4, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (0, 4, result), + NISENTRYLEN (0, 4, result)); + first_unused[NISENTRYLEN (0, 4, result)] = '\0'; pw->pw_gecos = first_unused; len = strlen (first_unused); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); - if (NISOBJLEN (5, obj) >= room_left) + if (NISENTRYLEN (0, 5, result) >= room_left) goto no_more_room; - strncpy (first_unused, NISOBJVAL (5, obj), NISOBJLEN (5, obj)); - first_unused[NISOBJLEN (5, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (0, 5, result), + NISENTRYLEN (0, 5, result)); + first_unused[NISENTRYLEN (0, 5, result)] = '\0'; pw->pw_dir = first_unused; len = strlen (first_unused); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); - if (NISOBJLEN (6, obj) >= room_left) + if (NISENTRYLEN (0, 6, result) >= room_left) goto no_more_room; - strncpy (first_unused, NISOBJVAL (6, obj), NISOBJLEN (6, obj)); - first_unused[NISOBJLEN (6, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (0, 6, result), + NISENTRYLEN (0, 6, result)); + first_unused[NISENTRYLEN (0, 6, result)] = '\0'; pw->pw_shell = first_unused; len = strlen (first_unused); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); return 1; } - +libnss_nisplus_hidden_def (_nss_nisplus_parse_pwent) int -_nss_nisplus_parse_grent (nis_result *result, struct group *gr, +_nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr, char *buffer, size_t buflen, int *errnop) { - if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "group_tbl") != 0 - || NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4) - return 0; - - nis_object *obj = NIS_RES_OBJECT (result); char *first_unused = buffer; size_t room_left = buflen; char *line; int count; size_t len; - if (NISOBJLEN (0, obj) >= room_left) + if (result == NULL) + return 0; + + if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) + || __type_of(result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val[entry].EN_data.en_type, + "group_tbl") != 0 + || result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 4) + return 0; + + if (NISENTRYLEN (entry, 0, result) >= room_left) { /* The line is too long for our buffer. */ no_more_room: @@ -172,59 +171,54 @@ _nss_nisplus_parse_grent (nis_result *result, struct group *gr, return -1; } - strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj)); - first_unused[NISOBJLEN (0, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (entry, 0, result), + NISENTRYLEN (entry, 0, result)); + first_unused[NISENTRYLEN (entry, 0, result)] = '\0'; len = strlen (first_unused); if (len == 0) /* group table is corrupt */ return 0; gr->gr_name = first_unused; - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); - if (NISOBJLEN (1, obj) >= room_left) + if (NISENTRYLEN (entry, 1, result) >= room_left) goto no_more_room; - strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj)); - first_unused[NISOBJLEN (1, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (entry, 1, result), + NISENTRYLEN (entry, 1, result)); + first_unused[NISENTRYLEN (entry, 1, result)] = '\0'; gr->gr_passwd = first_unused; len = strlen (first_unused); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); - char *numstr = NISOBJVAL (2, obj); - len = NISOBJLEN (2, obj); - if (len == 0 || numstr[len - 1] != '\0') - { - if (len >= room_left) - goto no_more_room; + if (NISENTRYLEN (entry, 2, result) >= room_left) + goto no_more_room; - strncpy (first_unused, numstr, len); - first_unused[len] = '\0'; - numstr = first_unused; - } - if (numstr[0] == '\0') - /* We should always have a gid. */ + strncpy (first_unused, NISENTRYVAL (entry, 2, result), + NISENTRYLEN (entry, 2, result)); + first_unused[NISENTRYLEN (entry, 2, result)] = '\0'; + len = strlen (first_unused); + if (len == 0) /* We should always have an gid */ return 0; - gr->gr_gid = strtoul (numstr, NULL, 10); + gr->gr_gid = strtoul (first_unused, NULL, 10); + room_left -= (strlen (first_unused) + 1); + first_unused += strlen (first_unused) + 1; - if (NISOBJLEN (3, obj) >= room_left) + if (NISENTRYLEN (entry, 3, result) >= room_left) goto no_more_room; - strncpy (first_unused, NISOBJVAL (3, obj), NISOBJLEN (3, obj)); - first_unused[NISOBJLEN (3, obj)] = '\0'; + strncpy (first_unused, NISENTRYVAL (entry, 3, result), + NISENTRYLEN (entry, 3, result)); + first_unused[NISENTRYLEN (entry, 3, result)] = '\0'; line = first_unused; len = strlen (line); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); /* Adjust the pointer so it is aligned for storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; + first_unused += __alignof__ (char *) - 1; + first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); gr->gr_mem = (char **) first_unused; count = 0; @@ -249,10 +243,12 @@ _nss_nisplus_parse_grent (nis_result *result, struct group *gr, { int is = isspace (*line); - *line++ = '\0'; + *line = '\0'; if (is) while (*line != '\0' && (*line == ',' || isspace (*line))) ++line; + else + ++line; } } if (room_left < sizeof (char *)) @@ -262,7 +258,7 @@ _nss_nisplus_parse_grent (nis_result *result, struct group *gr, return 1; } - +libnss_nisplus_hidden_def (_nss_nisplus_parse_grent) int _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, @@ -276,10 +272,11 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || NIS_RES_NUMOBJ (result) != 1 - || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0 - || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 8) + || result->objects.objects_len != 1 + || __type_of(result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "passwd_tbl") != 0 + || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 8) return 0; if (NISENTRYLEN (0, 0, result) >= room_left) @@ -297,8 +294,8 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, if (len == 0) return 0; sp->sp_namp = first_unused; - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); if (NISENTRYLEN (0, 1, result) >= room_left) goto no_more_room; @@ -308,8 +305,8 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, first_unused[NISENTRYLEN (0, 1, result)] = '\0'; sp->sp_pwdp = first_unused; len = strlen (first_unused); - room_left -= len + 1; - first_unused += len + 1; + room_left -= (len + 1); + first_unused += (len + 1); sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact = sp->sp_expire = -1; @@ -317,8 +314,10 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, if (NISENTRYLEN (0, 7, result) > 0) { - char *line = NISENTRYVAL (0, 7, result); - char *cp = strchr (line, ':'); + char *line, *cp; + + line = NISENTRYVAL (0, 7, result); + cp = strchr (line, ':'); if (cp == NULL) return 1; *cp++ = '\0'; @@ -374,3 +373,4 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, return 1; } +libnss_nisplus_hidden_def (_nss_nisplus_parse_spent) diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c index 42a2d088da..83456cae64 100644 --- a/nis/nss_nisplus/nisplus-proto.c +++ b/nis/nss_nisplus/nisplus-proto.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,14 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> -#include <ctype.h> +#include <nss.h> #include <errno.h> +#include <ctype.h> #include <netdb.h> -#include <nss.h> #include <string.h> -#include <rpcsvc/nis.h> #include <bits/libc-lock.h> +#include <rpcsvc/nis.h> #include "nss-nisplus.h" @@ -35,20 +33,20 @@ static nis_result *result; static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) - -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) static int -_nss_nisplus_parse_protoent (nis_result *result, struct protoent *proto, +_nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto, char *buffer, size_t buflen, int *errnop) { char *first_unused = buffer; size_t room_left = buflen; unsigned int i; + char *p, *line; if (result == NULL) return 0; @@ -71,44 +69,41 @@ _nss_nisplus_parse_protoent (nis_result *result, struct protoent *proto, NISENTRYLEN (0, 0, result)); first_unused[NISENTRYLEN (0, 0, result)] = '\0'; proto->p_name = first_unused; - size_t len = strlen (first_unused) + 1; - room_left -= len; - first_unused += len; + room_left -= (strlen (first_unused) +1); + first_unused += strlen (first_unused) +1; + if (NISENTRYLEN (0, 2, result) + 1 > room_left) + goto no_more_room; proto->p_proto = atoi (NISENTRYVAL (0, 2, result)); + p = first_unused; - /* XXX Rewrite at some point to allocate the array first and then - copy the strings. It wasteful to first concatenate the strings - to just split them again later. */ - char *line = first_unused; - for (i = 0; i < NIS_RES_NUMOBJ (result); ++i) + line = p; + for (i = 0; i < result->objects.objects_len; ++i) { if (strcmp (NISENTRYVAL (i, 1, result), proto->p_name) != 0) { if (NISENTRYLEN (i, 1, result) + 2 > room_left) goto no_more_room; - *first_unused++ = ' '; - first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result), - NISENTRYLEN (i, 1, result)); - room_left -= NISENTRYLEN (i, 1, result) + 1; + *p++ = ' '; + p = __stpncpy (p, NISENTRYVAL (i, 1, result), + NISENTRYLEN (i, 1, result)); + *p = '\0'; + room_left -= (NISENTRYLEN (i, 1, result) + 1); } } - *first_unused++ = '\0'; + *p++ = '\0'; + first_unused = p; /* Adjust the pointer so it is aligned for storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust + sizeof (char *)) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; + first_unused += __alignof__ (char *) - 1; + first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); proto->p_aliases = (char **) first_unused; - - /* For the terminating NULL pointer. */ + if (room_left < sizeof (char *)) + goto no_more_room; room_left -= sizeof (char *); + proto->p_aliases[0] = NULL; i = 0; while (*line != '\0') @@ -123,15 +118,20 @@ _nss_nisplus_parse_protoent (nis_result *result, struct protoent *proto, goto no_more_room; room_left -= sizeof (char *); - proto->p_aliases[i++] = line; + proto->p_aliases[i] = line; while (*line != '\0' && *line != ' ') ++line; if (*line == ' ') - *line++ = '\0'; + { + *line = '\0'; + ++line; + ++i; + } + else + proto->p_aliases[i+1] = NULL; } - proto->p_aliases[i] = NULL; return 1; } @@ -141,26 +141,19 @@ _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "protocols.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "protocols.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } @@ -171,11 +164,9 @@ _nss_nisplus_setprotoent (int stayopen) __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (tablename_val == NULL) { @@ -193,11 +184,9 @@ _nss_nisplus_endprotoent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -227,23 +216,17 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer, } result = nis_first_entry (tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) return niserr2nss (result->status); } else { + nis_result *res; + saved_res = result; - result = nis_next_entry (tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + res = nis_next_entry (tablename_val, &result->cookie); + result = res; + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { nis_freeresult (saved_res); @@ -294,91 +277,79 @@ _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto, if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } if (name == NULL) return NSS_STATUS_NOTFOUND; + else + { + nis_result *result; + char buf[strlen (name) + 255 + tablename_len]; + int olderr = errno; - char buf[strlen (name) + 10 + tablename_len]; - int olderr = errno; - - /* Search at first in the alias list, and use the correct name - for the next search */ - snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + /* Search at first in the alias list, and use the correct name + for the next search */ + sprintf (buf, "[name=%s],%s", name, tablename_val); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (result != NULL) - { - char *bufptr = buf; - - /* If we did not find it, try it as original name. But if the - database is correct, we should find it in the first case, too */ - if ((result->status != NIS_SUCCESS - && result->status != NIS_S_SUCCESS) - || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ - || strcmp (result->objects.objects_val->EN_data.en_type, - "protocols_tbl") != 0 - || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3) - snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val); - else + if (result != NULL) { - /* We need to allocate a new buffer since there is no - guarantee the returned name has a length limit. */ - const char *entryval = NISENTRYVAL (0, 0, result); - size_t buflen = strlen (entryval) + 10 + tablename_len; - bufptr = alloca (buflen); - snprintf (bufptr, buflen, "[cname=%s],%s", - entryval, tablename_val); + /* If we do not find it, try it as original name. But if the + database is correct, we should find it in the first case, too */ + if ((result->status != NIS_SUCCESS + && result->status != NIS_S_SUCCESS) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "protocols_tbl") != 0 + || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3) + sprintf (buf, "[cname=%s],%s", name, tablename_val); + else + sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result), + tablename_val); + + nis_freeresult (result); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); } - nis_freeresult (result); - result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - } + if (result == NULL) + { + __set_errno (ENOMEM); + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - if (result == NULL) - { - __set_errno (ENOMEM); - return NSS_STATUS_TRYAGAIN; - } + __set_errno (olderr); - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + nis_freeresult (result); + return status; + } - __set_errno (olderr); + parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen, + errnop); nis_freeresult (result); - return status; - } - parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen, - errnop); - - nis_freeresult (result); - - if (parse_res < 1) - { - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else + if (parse_res < 1) { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } enum nss_status @@ -387,57 +358,55 @@ _nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto, { if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } - char buf[12 + 3 * sizeof (number) + tablename_len]; - int olderr = errno; + { + int parse_res; + nis_result *result; + char buf[46 + tablename_len]; + int olderr = errno; - snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val); + sprintf (buf, "[number=%d],%s", number, tablename_val); - nis_result *result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); + result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - if (result == NULL) - { - __set_errno (ENOMEM); - return NSS_STATUS_TRYAGAIN; - } + if (result == NULL) + { + __set_errno (ENOMEM); + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + __set_errno (olderr); - __set_errno (olderr); - - nis_freeresult (result); - return status; - } - - int parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen, - errnop); - - nis_freeresult (result); - - if (parse_res < 1) - { - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else - { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; - } - } - - return NSS_STATUS_SUCCESS; + nis_freeresult (result); + return status; + } + + parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen, + errnop); + + nis_freeresult (result); + + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c index f6b32f8827..58ae7012af 100644 --- a/nis/nss_nisplus/nisplus-publickey.c +++ b/nis/nss_nisplus/nisplus-publickey.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997,1999,2001,2003,2005,2006 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1999, 2001, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -37,7 +37,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop) { nis_result *res; enum nss_status retval; - char buf[NIS_MAXNAMELEN + 2]; + char buf[NIS_MAXNAMELEN+2]; size_t slen; char *domain, *cptr; int len; @@ -91,20 +91,20 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop) return retval; } - if (NIS_RES_NUMOBJ (res) > 1) + if (res->objects.objects_len > 1) { /* * More than one principal with same uid? * something wrong with cred table. Should be unique * Warn user and continue. */ - syslog (LOG_ERR, _("DES entry for netname %s not unique\n"), netname); + printf (_("DES entry for netname %s not unique\n"), netname); nis_freeresult (res); return NSS_STATUS_SUCCESS; } - len = ENTRY_LEN (NIS_RES_OBJECT (res), 3); - memcpy (pkey, ENTRY_VAL (NIS_RES_OBJECT (res),3), len); + len = ENTRY_LEN (res->objects.objects_val, 3); + memcpy (pkey, ENTRY_VAL (res->objects.objects_val,3), len); pkey[len] = 0; cptr = strchr (pkey, ':'); if (cptr) @@ -114,14 +114,13 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop) return NSS_STATUS_SUCCESS; } - enum nss_status _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, int *errnop) { nis_result *res; enum nss_status retval; - char buf[NIS_MAXNAMELEN + 2]; + char buf[NIS_MAXNAMELEN+2]; size_t slen; char *domain, *cptr; int len; @@ -155,7 +154,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, buf[slen] = '\0'; } - res = nis_list (buf, USE_DGRAM | NO_AUTHINFO | FOLLOW_LINKS | FOLLOW_PATH, + res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, NULL, NULL); if (res == NULL) @@ -173,20 +172,20 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, return retval; } - if (NIS_RES_NUMOBJ (res) > 1) + if (res->objects.objects_len > 1) { /* * More than one principal with same uid? * something wrong with cred table. Should be unique * Warn user and continue. */ - syslog (LOG_ERR, _("DES entry for netname %s not unique\n"), netname); + printf (_("DES entry for netname %s not unique\n"), netname); nis_freeresult (res); return NSS_STATUS_SUCCESS; } - len = ENTRY_LEN (NIS_RES_OBJECT (res), 4); - memcpy (buf, ENTRY_VAL (NIS_RES_OBJECT (res), 4), len); + len = ENTRY_LEN (res->objects.objects_val, 4); + memcpy (buf, ENTRY_VAL (res->objects.objects_val,4), len); buf[len] = '\0'; cptr = strchr (buf, ':'); if (cptr) @@ -205,7 +204,6 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, return NSS_STATUS_SUCCESS; } - /* Parse information from the passed string. The format of the string passed is gid,grp,grp, ... */ static enum nss_status @@ -226,12 +224,8 @@ parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist, gidlen = 0; /* After strtoul() ep should point to the marker ',', which means - here starts a new value. - - The Sun man pages show that GIDLIST should contain at least NGRPS - elements. Limiting the number written by this value is the best - we can do. */ - while (ep != NULL && *ep == ',' && gidlen < NGRPS) + here starts a new value. */ + while (ep != NULL && *ep == ',') { ep++; s = ep; @@ -248,9 +242,9 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, { char *domain; nis_result *res; - char sname[NIS_MAXNAMELEN + 2]; /* search criteria + table name */ + char sname[NIS_MAXNAMELEN+2]; /* search criteria + table name */ size_t slen; - char principal[NIS_MAXNAMELEN + 1]; + char principal[NIS_MAXNAMELEN+1]; int len; /* 1. Get home domain of user. */ @@ -261,6 +255,10 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, ++domain; /* skip '@' */ /* 2. Get user's nisplus principal name. */ + if ((strlen (netname) + strlen (domain)+45) > + (size_t) NIS_MAXNAMELEN) + return NSS_STATUS_UNAVAIL; + slen = snprintf (sname, NIS_MAXNAMELEN, "[auth_name=%s,auth_type=DES],cred.org_dir.%s", netname, domain); @@ -311,7 +309,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, return NSS_STATUS_UNAVAIL; } - if (NIS_RES_NUMOBJ (res) > 1) + if (res->objects.objects_len > 1) /* * A netname belonging to more than one principal? * Something wrong with cred table. should be unique. @@ -321,8 +319,8 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, _("netname2user: DES entry for %s in directory %s not unique"), netname, domain); - len = ENTRY_LEN (NIS_RES_OBJECT (res), 0); - strncpy (principal, ENTRY_VAL (NIS_RES_OBJECT (res), 0), len); + len = ENTRY_LEN (res->objects.objects_val, 0); + strncpy (principal, ENTRY_VAL (res->objects.objects_val, 0), len); principal[len] = '\0'; nis_freeresult (res); @@ -334,16 +332,15 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, * LOCAL entry in **local** cred table. */ domain = nis_local_directory (); - if (strlen (principal) + strlen (domain) + 45 > (size_t) NIS_MAXNAMELEN) + if ((strlen (principal) + strlen (domain) + 45) > (size_t) NIS_MAXNAMELEN) { syslog (LOG_ERR, _("netname2user: principal name `%s' too long"), principal); return NSS_STATUS_UNAVAIL; } - slen = snprintf (sname, sizeof (sname), - "[cname=%s,auth_type=LOCAL],cred.org_dir.%s", - principal, domain); + slen = sprintf (sname, "[cname=%s,auth_type=LOCAL],cred.org_dir.%s", + principal, domain); if (sname[slen - 1] != '.') { @@ -385,7 +382,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, return NSS_STATUS_UNAVAIL; } - if (NIS_RES_NUMOBJ (res) > 1) + if (res->objects.objects_len > 1) /* * A principal can have more than one LOCAL entry? * Something wrong with cred table. @@ -395,16 +392,15 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, _("netname2user: LOCAL entry for %s in directory %s not unique"), netname, domain); /* Fetch the uid */ - *uidp = strtoul (ENTRY_VAL (NIS_RES_OBJECT (res), 2), NULL, 10); + *uidp = strtoul (ENTRY_VAL (res->objects.objects_val, 2), NULL, 10); if (*uidp == 0) { syslog (LOG_ERR, _("netname2user: should not have uid 0")); - nis_freeresult (res); return NSS_STATUS_NOTFOUND; } - parse_grp_str (ENTRY_VAL (NIS_RES_OBJECT (res), 3), + parse_grp_str (ENTRY_VAL (res->objects.objects_val, 3), gidp, gidlenp, gidlist, errnop); nis_freeresult (res); diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c index cd33aebbcc..8f3bc997b3 100644 --- a/nis/nss_nisplus/nisplus-pwd.c +++ b/nis/nss_nisplus/nisplus-pwd.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1999, 2001, 2002, 2003, 2005, 2006, 2007 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,7 +17,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> #include <nss.h> #include <errno.h> #include <pwd.h> @@ -28,246 +26,126 @@ #include "nss-nisplus.h" #include "nisplus-parser.h" -#include <libnsl.h> -#include <nis_intern.h> -#include <nis_xdr.h> - __libc_lock_define_initialized (static, lock) -/* Connection information. */ -static ib_request *ibreq; -static directory_obj *dir; -static dir_binding bptr; -static char *tablepath; -static char *tableptr; -/* Cursor. */ -static netobj cursor; - +static nis_result *result; +static nis_name tablename_val; +static u_long tablename_len; -nis_name pwd_tablename_val attribute_hidden; -size_t pwd_tablename_len attribute_hidden; - -enum nss_status -_nss_pwd_create_tablename (int *errnop) +static enum nss_status +_nss_create_tablename (int *errnop) { - if (pwd_tablename_val == NULL) + if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "passwd.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "passwd.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - pwd_tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - if (atomic_compare_and_exchange_bool_acq (&pwd_tablename_val, p, NULL)) - { - /* Another thread already installed the value. */ - free (p); - pwd_tablename_len = strlen (pwd_tablename_val); - } + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } -static void -internal_nisplus_endpwent (void) -{ - __nisbind_destroy (&bptr); - memset (&bptr, '\0', sizeof (bptr)); - - nis_free_directory (dir); - dir = NULL; - - nis_free_request (ibreq); - ibreq = NULL; - - xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor); - memset (&cursor, '\0', sizeof (cursor)); - - free (tablepath); - tableptr = tablepath = NULL; -} - - -static enum nss_status -internal_nisplus_setpwent (int *errnop) -{ - enum nss_status status = NSS_STATUS_SUCCESS; - - if (pwd_tablename_val == NULL) - status = _nss_pwd_create_tablename (errnop); - - if (status == NSS_STATUS_SUCCESS) - { - ibreq = __create_ib_request (pwd_tablename_val, 0); - if (ibreq == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } - - nis_error retcode = __prepare_niscall (pwd_tablename_val, &dir, - &bptr, 0); - if (retcode != NIS_SUCCESS) - { - nis_free_request (ibreq); - ibreq = NULL; - status = niserr2nss (retcode); - } - } - - return status; -} - - enum nss_status _nss_nisplus_setpwent (int stayopen) { - enum nss_status status; + enum nss_status status = NSS_STATUS_SUCCESS; + int err; __libc_lock_lock (lock); - internal_nisplus_endpwent (); + if (result) + nis_freeresult (result); + result = NULL; - // XXX We need to be able to set errno. Pass in new parameter. - int err; - status = internal_nisplus_setpwent (&err); + if (tablename_val == NULL) + status = _nss_create_tablename (&err); __libc_lock_unlock (lock); return status; } - enum nss_status _nss_nisplus_endpwent (void) { __libc_lock_lock (lock); - internal_nisplus_endpwent (); + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); return NSS_STATUS_SUCCESS; } - static enum nss_status internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen, int *errnop) { - int parse_res = -1; - enum nss_status retval = NSS_STATUS_SUCCESS; + int parse_res; /* Get the next entry until we found a correct one. */ do { - nis_error status; - nis_result result; - memset (&result, '\0', sizeof (result)); + nis_result *saved_res; - if (cursor.n_bytes == NULL) + if (result == NULL) { - if (ibreq == NULL) + saved_res = NULL; + if (tablename_val == NULL) { - retval = internal_nisplus_setpwent (errnop); - if (retval != NSS_STATUS_SUCCESS) - return retval; + enum nss_status status = _nss_create_tablename (errnop); + + if (status != NSS_STATUS_SUCCESS) + return status; } - status = __do_niscall3 (&bptr, NIS_IBFIRST, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, - (xdrproc_t) _xdr_nis_result, - (caddr_t) &result, - 0, NULL); + result = nis_first_entry (tablename_val); + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + return niserr2nss (result->status); } else { - ibreq->ibr_cookie.n_bytes = cursor.n_bytes; - ibreq->ibr_cookie.n_len = cursor.n_len; - - status = __do_niscall3 (&bptr, NIS_IBNEXT, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, - (xdrproc_t) _xdr_nis_result, - (caddr_t) &result, - 0, NULL); - - ibreq->ibr_cookie.n_bytes = NULL; - ibreq->ibr_cookie.n_len = 0; - } - - if (status != NIS_SUCCESS) - return niserr2nss (status); + nis_result *res; - if (NIS_RES_STATUS (&result) == NIS_NOTFOUND) - { - /* No more entries on this server. This means we have to go - to the next server on the path. */ - status = __follow_path (&tablepath, &tableptr, ibreq, &bptr); - if (status != NIS_SUCCESS) - return niserr2nss (status); - - directory_obj *newdir = NULL; - dir_binding newbptr; - status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0); - if (status != NIS_SUCCESS) - return niserr2nss (status); - - nis_free_directory (dir); - dir = newdir; - __nisbind_destroy (&bptr); - bptr = newbptr; - - xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie); - result.cookie.n_bytes = NULL; - result.cookie.n_len = 0; - parse_res = 0; - goto next; + saved_res = result; + res = nis_next_entry (tablename_val, &result->cookie); + result = res; + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + nis_freeresult (saved_res); + return niserr2nss (result->status); + } } - else if (NIS_RES_STATUS (&result) != NIS_SUCCESS) - return niserr2nss (NIS_RES_STATUS (&result)); - parse_res = _nss_nisplus_parse_pwent (&result, pw, buffer, + parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop); - - if (__builtin_expect (parse_res == -1, 0)) + if (parse_res == -1) { + nis_freeresult (result); + result = saved_res; *errnop = ERANGE; - retval = NSS_STATUS_TRYAGAIN; - goto freeres; + return NSS_STATUS_TRYAGAIN; } + else + { + if (saved_res) + nis_freeresult (saved_res); + } + } while (!parse_res); - next: - /* Free the old cursor. */ - xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor); - /* Remember the new one. */ - cursor.n_bytes = result.cookie.n_bytes; - cursor.n_len = result.cookie.n_len; - /* Free the result structure. NB: we do not remove the cookie. */ - result.cookie.n_bytes = NULL; - result.cookie.n_len = 0; - freeres: - xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result); - memset (&result, '\0', sizeof (result)); - } - while (!parse_res); - - return retval; + return NSS_STATUS_SUCCESS; } enum nss_status @@ -291,9 +169,9 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw, { int parse_res; - if (pwd_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_pwd_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; @@ -304,107 +182,107 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw, *errnop = EINVAL; return NSS_STATUS_UNAVAIL; } + else + { + nis_result *result; + char buf[strlen (name) + 24 + tablename_len]; + int olderr = errno; - nis_result *result; - char buf[strlen (name) + 9 + pwd_tablename_len]; - int olderr = errno; + sprintf (buf, "[name=%s],%s", name, tablename_val); - snprintf (buf, sizeof (buf), "[name=%s],%s", name, pwd_tablename_val); + result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + __set_errno (olderr); - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + nis_freeresult (result); + return status; + } - __set_errno (olderr); + parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, + errnop); nis_freeresult (result); - return status; - } - - parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop); - nis_freeresult (result); - - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else + if (parse_res < 1) { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } enum nss_status _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw, char *buffer, size_t buflen, int *errnop) { - if (pwd_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_pwd_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } - int parse_res; - nis_result *result; - char buf[8 + 3 * sizeof (unsigned long int) + pwd_tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[uid=%lu],%s", - (unsigned long int) uid, pwd_tablename_val); - - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL); - - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + { + int parse_res; + nis_result *result; + char buf[100 + tablename_len]; + int olderr = errno; - __set_errno (olderr); + sprintf (buf, "[uid=%lu],%s", (unsigned long int) uid, tablename_val); - nis_freeresult (result); - return status; - } + result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - nis_freeresult (result); + __set_errno (olderr); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else - { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; - } - } - - return NSS_STATUS_SUCCESS; + nis_freeresult (result); + return status; + } + + parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop); + + nis_freeresult (result); + + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c index 711c6bc273..31d48d17a3 100644 --- a/nis/nss_nisplus/nisplus-rpc.c +++ b/nis/nss_nisplus/nisplus-rpc.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -18,14 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> -#include <ctype.h> -#include <errno.h> #include <nss.h> +#include <errno.h> +#include <ctype.h> #include <string.h> +#include <bits/libc-lock.h> #include <rpc/netdb.h> #include <rpcsvc/nis.h> -#include <bits/libc-lock.h> #include "nss-nisplus.h" @@ -35,12 +33,11 @@ static nis_result *result; static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) - -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) static int _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc, @@ -49,16 +46,17 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc, char *first_unused = buffer; size_t room_left = buflen; unsigned int i; - char *line; + char *p, *line; if (result == NULL) return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "rpc_tbl") != 0 - || NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 3) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val[0].EN_data.en_type, + "rpc_tbl") != 0 + || result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3) return 0; if (NISENTRYLEN (0, 0, result) >= room_left) @@ -71,43 +69,37 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc, NISENTRYLEN (0, 0, result)); first_unused[NISENTRYLEN (0, 0, result)] = '\0'; rpc->r_name = first_unused; - size_t len = strlen (first_unused) + 1; - room_left -= len; - first_unused += len; - + room_left -= (strlen (first_unused) + 1); + first_unused += strlen (first_unused) + 1; rpc->r_number = atoi (NISENTRYVAL (0, 2, result)); + p = first_unused; - /* XXX Rewrite at some point to allocate the array first and then - copy the strings. It wasteful to first concatenate the strings - to just split them again later. */ - line = first_unused; - for (i = 0; i < NIS_RES_NUMOBJ (result); ++i) + line = p; + for (i = 0; i < result->objects.objects_len; ++i) { if (strcmp (NISENTRYVAL (i, 1, result), rpc->r_name) != 0) { if (NISENTRYLEN (i, 1, result) + 2 > room_left) goto no_more_room; - *first_unused++ = ' '; - first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result), - NISENTRYLEN (i, 1, result)); - room_left -= NISENTRYLEN (i, 1, result) + 1; + *p++ = ' '; + p = __stpncpy (p, NISENTRYVAL (i, 1, result), + NISENTRYLEN (i, 1, result)); + *p = '\0'; + room_left -= (NISENTRYLEN (i, 1, result) + 1); } } - *first_unused++ = '\0'; + ++p; + first_unused = p; /* Adjust the pointer so it is aligned for storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust + sizeof (char *)) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; + first_unused += __alignof__ (char *) - 1; + first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); rpc->r_aliases = (char **) first_unused; - - /* For the terminating NULL pointer. */ + if (room_left < sizeof (char *)) + goto no_more_room; room_left -= sizeof (char *); + rpc->r_aliases[0] = NULL; i = 0; while (*line != '\0') @@ -123,45 +115,42 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc, goto no_more_room; room_left -= sizeof (char *); - rpc->r_aliases[i++] = line; + rpc->r_aliases[i] = line; while (*line != '\0' && *line != ' ') ++line; if (*line == ' ') - *line++ = '\0'; + { + *line = '\0'; + ++line; + ++i; + } + else + rpc->r_aliases[i+1] = NULL; } - rpc->r_aliases[i] = NULL; return 1; } - static enum nss_status _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "rpc.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "rpc.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } @@ -170,20 +159,16 @@ enum nss_status _nss_nisplus_setrpcent (int stayopen) { enum nss_status status = NSS_STATUS_SUCCESS; + int err; __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (tablename_val == NULL) - { - int err; - status = _nss_create_tablename (&err); - } + status = _nss_create_tablename (&err); __libc_lock_unlock (lock); @@ -195,11 +180,9 @@ _nss_nisplus_endrpcent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -229,23 +212,16 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer, } result = nis_first_entry (tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) return niserr2nss (result->status); } else { + nis_result *res; + saved_res = result; - result = nis_next_entry (tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + res = nis_next_entry (tablename_val, &result->cookie); + result = res; if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { nis_freeresult (saved_res); @@ -267,8 +243,7 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer, if (saved_res) nis_freeresult (saved_res); } - } - while (!parse_res); + } while (!parse_res); return NSS_STATUS_SUCCESS; } @@ -296,91 +271,77 @@ _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc, if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } if (name == NULL) return NSS_STATUS_NOTFOUND; + else + { + nis_result *result; + char buf[strlen (name) + 255 + tablename_len]; + int olderr = errno; - char buf[strlen (name) + 10 + tablename_len]; - int olderr = errno; - - /* Search at first in the alias list, and use the correct name - for the next search */ - snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); + /* Search at first in the alias list, and use the correct name + for the next search */ + sprintf (buf, "[name=%s],%s", name, tablename_val); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (result != NULL) - { - char *bufptr = buf; - - /* If we did not find it, try it as original name. But if the - database is correct, we should find it in the first case, too */ - if ((result->status != NIS_SUCCESS - && result->status != NIS_S_SUCCESS) - || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ - || strcmp (result->objects.objects_val->EN_data.en_type, - "rpc_tbl") != 0 - || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3) - snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val); - else + if (result != NULL) { - /* We need to allocate a new buffer since there is no - guarantee the returned name has a length limit. */ - const char *entryval = NISENTRYVAL (0, 0, result); - size_t buflen = strlen (entryval) + 10 + tablename_len; - bufptr = alloca (buflen); - snprintf (bufptr, buflen, "[cname=%s],%s", - entryval, tablename_val); - } - - nis_freeresult (result); - result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); - } + /* If we do not find it, try it as original name. But if the + database is correct, we should find it in the first case, too */ + if ((result->status != NIS_SUCCESS + && result->status != NIS_S_SUCCESS) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "rpc_tbl") != 0 + || result->objects.objects_val->EN_data.en_cols.en_cols_len < 3) + sprintf (buf, "[cname=%s],%s", name, tablename_val); + else + sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result), + tablename_val); - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + nis_freeresult (result); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS , NULL, NULL); + } - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - __set_errno (olderr); + __set_errno (olderr); - nis_freeresult (result); - return status; - } + nis_freeresult (result); + return status; + } - parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen, + parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen, errnop); - nis_freeresult (result); + nis_freeresult (result); - if (parse_res < 1) - { - if (parse_res == -1) + if (parse_res < 1) { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } enum nss_status @@ -389,58 +350,55 @@ _nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc, { if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } - char buf[12 + 3 * sizeof (number) + tablename_len]; - int olderr = errno; + { + int parse_res; + nis_result *result; + char buf[100 + tablename_len]; + int olderr = errno; - snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val); + sprintf (buf, "[number=%d],%s", number, tablename_val); - nis_result *result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | USE_DGRAM, - NULL, NULL); + result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); - - __set_errno (olderr); - - nis_freeresult (result); - return status; - } - - int parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen, - errnop); - - nis_freeresult (result); - - if (parse_res < 1) - { - if (parse_res == -1) - { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else - { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; - } - } + __set_errno (olderr); - return NSS_STATUS_SUCCESS; + nis_freeresult (result); + return status; + } + + parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen, + errnop); + + nis_freeresult (result); + + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c index 607ce80b01..fbb6987e9e 100644 --- a/nis/nss_nisplus/nisplus-service.c +++ b/nis/nss_nisplus/nisplus-service.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2005, 2006, 2007 - Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,1999,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -18,14 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <atomic.h> -#include <ctype.h> +#include <nss.h> #include <errno.h> +#include <ctype.h> #include <netdb.h> -#include <nss.h> #include <string.h> -#include <rpcsvc/nis.h> #include <bits/libc-lock.h> +#include <rpcsvc/nis.h> #include "nss-nisplus.h" @@ -35,12 +33,11 @@ static nis_result *result; static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) - -#define NISENTRYLEN(idx, col, res) \ - (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) +#define NISENTRYVAL(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) +#define NISENTRYLEN(idx,col,res) \ + ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) static int _nss_nisplus_parse_servent (nis_result *result, struct servent *serv, @@ -48,14 +45,17 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv, { char *first_unused = buffer; size_t room_left = buflen; + unsigned int i; + char *p, *line; if (result == NULL) return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) - || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "services_tbl") != 0 - || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 4) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "services_tbl") != 0 + || result->objects.objects_val->EN_data.en_cols.en_cols_len < 4) return 0; if (NISENTRYLEN (0, 0, result) >= room_left) @@ -68,9 +68,8 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv, NISENTRYLEN (0, 0, result)); first_unused[NISENTRYLEN (0, 0, result)] = '\0'; serv->s_name = first_unused; - size_t len = strlen (first_unused) + 1; - room_left -= len; - first_unused += len; + room_left -= (strlen (first_unused) +1); + first_unused += strlen (first_unused) +1; if (NISENTRYLEN (0, 2, result) >= room_left) goto no_more_room; @@ -78,45 +77,40 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv, NISENTRYLEN (0, 2, result)); first_unused[NISENTRYLEN (0, 2, result)] = '\0'; serv->s_proto = first_unused; - len = strlen (first_unused) + 1; - room_left -= len; - first_unused += len; + room_left -= strlen (first_unused) + 1; + first_unused += strlen (first_unused) + 1; serv->s_port = htons (atoi (NISENTRYVAL (0, 3, result))); + p = first_unused; - /* XXX Rewrite at some point to allocate the array first and then - copy the strings. It wasteful to first concatenate the strings - to just split them again later. */ - char *line = first_unused; - for (unsigned int i = 0; i < NIS_RES_NUMOBJ (result); ++i) + line = p; + for (i = 0; i < result->objects.objects_len; ++i) { if (strcmp (NISENTRYVAL (i, 1, result), serv->s_name) != 0) { if (NISENTRYLEN (i, 1, result) + 2 > room_left) goto no_more_room; - *first_unused++ = ' '; - first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result), - NISENTRYLEN (i, 1, result)); - room_left -= NISENTRYLEN (i, 1, result) + 1; + *p++ = ' '; + p = __stpncpy (p, NISENTRYVAL (i, 1, result), + NISENTRYLEN (i, 1, result)); + *p = '\0'; + room_left -= (NISENTRYLEN (i, 1, result) + 1); } } - *first_unused++ = '\0'; + *p++ = '\0'; + first_unused = p; /* Adjust the pointer so it is aligned for storing pointers. */ - size_t adjust = ((__alignof__ (char *) - - (first_unused - (char *) 0) % __alignof__ (char *)) - % __alignof__ (char *)); - if (room_left < adjust + sizeof (char *)) - goto no_more_room; - first_unused += adjust; - room_left -= adjust; + first_unused += __alignof__ (char *) - 1; + first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); serv->s_aliases = (char **) first_unused; - - /* For the terminating NULL pointer. */ + if (room_left < sizeof (char *)) + goto no_more_room; room_left -= (sizeof (char *)); + serv->s_aliases[0] = NULL; - unsigned int i = 0; + i = 0; while (*line != '\0') { /* Skip leading blanks. */ @@ -130,45 +124,42 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv, goto no_more_room; room_left -= sizeof (char *); - serv->s_aliases[i++] = line; + serv->s_aliases[i] = line; while (*line != '\0' && *line != ' ') ++line; if (*line == ' ') - *line++ = '\0'; + { + *line = '\0'; + ++line; + ++i; + } + else + serv->s_aliases[i+1] = NULL; } - serv->s_aliases[i] = NULL; return 1; } - static enum nss_status _nss_create_tablename (int *errnop) { if (tablename_val == NULL) { - const char *local_dir = nis_local_directory (); - size_t local_dir_len = strlen (local_dir); - static const char prefix[] = "services.org_dir."; + char buf [40 + strlen (nis_local_directory ())]; + char *p; - char *p = malloc (sizeof (prefix) + local_dir_len); - if (p == NULL) + p = __stpcpy (buf, "services.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; } - - memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1); - - tablename_len = sizeof (prefix) - 1 + local_dir_len; - - atomic_write_barrier (); - - tablename_val = p; + tablename_len = strlen (tablename_val); } - return NSS_STATUS_SUCCESS; } @@ -181,11 +172,9 @@ _nss_nisplus_setservent (int stayopen) __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; if (tablename_val == NULL) status = _nss_create_tablename (&err); @@ -200,11 +189,9 @@ _nss_nisplus_endservent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -234,23 +221,16 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer, } result = nis_first_entry (tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) return niserr2nss (result->status); } else { + nis_result *res; + saved_res = result; - result = nis_next_entry (tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + res = nis_next_entry (tablename_val, &result->cookie); + result = res; if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { nis_freeresult (saved_res); @@ -260,7 +240,7 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer, parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen, errnop); - if (__builtin_expect (parse_res == -1, 0)) + if (parse_res == -1) { nis_freeresult (result); result = saved_res; @@ -282,9 +262,11 @@ enum nss_status _nss_nisplus_getservent_r (struct servent *result, char *buffer, size_t buflen, int *errnop) { + int status; + __libc_lock_lock (lock); - int status = internal_nisplus_getservent_r (result, buffer, buflen, errnop); + status = internal_nisplus_getservent_r (result, buffer, buflen, errnop); __libc_lock_unlock (lock); @@ -296,14 +278,12 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol, struct servent *serv, char *buffer, size_t buflen, int *errnop) { + int parse_res; + if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } @@ -313,84 +293,72 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol, *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } + else + { + nis_result *result; + char buf[strlen (name) + 255 + tablename_len]; + int olderr = errno; - size_t protocol_len = strlen (protocol); - char buf[strlen (name) + protocol_len + 17 + tablename_len]; - int olderr = errno; - - /* Search at first in the alias list, and use the correct name - for the next search */ - snprintf (buf, sizeof (buf), "[name=%s,proto=%s],%s", name, protocol, - tablename_val); - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); + /* Search at first in the alias list, and use the correct name + for the next search */ + sprintf (buf, "[name=%s,proto=%s],%s", name, protocol, + tablename_val); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (result != NULL) - { - char *bufptr = buf; - - /* If we did not find it, try it as original name. But if the - database is correct, we should find it in the first case, too */ - if ((result->status != NIS_SUCCESS - && result->status != NIS_S_SUCCESS) - || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ - || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, - "services_tbl") != 0 - || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 4) - snprintf (buf, sizeof (buf), "[cname=%s,proto=%s],%s", name, protocol, - tablename_val); - else + if (result != NULL) { - /* We need to allocate a new buffer since there is no - guarantee the returned name has a length limit. */ - const char *entryval = NISENTRYVAL(0, 0, result); - size_t buflen = (strlen (entryval) + protocol_len + 17 - + tablename_len); - bufptr = alloca (buflen); - snprintf (bufptr, buflen, "[cname=%s,proto=%s],%s", - entryval, protocol, tablename_val); - } + /* If we do not find it, try it as original name. But if the + database is correct, we should find it in the first case, too */ + if ((result->status != NIS_SUCCESS + && result->status != NIS_S_SUCCESS) + || __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ + || strcmp (result->objects.objects_val->EN_data.en_type, + "services_tbl") != 0 + || result->objects.objects_val->EN_data.en_cols.en_cols_len < 4) + sprintf (buf, "[cname=%s,proto=%s],%s", name, protocol, + tablename_val); + else + sprintf (buf, "[cname=%s,proto=%s],%s", + NISENTRYVAL (0, 0, result), protocol, tablename_val); - nis_freeresult (result); - result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); - } - - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } + nis_freeresult (result); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + } - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) - { - enum nss_status status = niserr2nss (result->status); + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) + { + enum nss_status status = niserr2nss (result->status); - __set_errno (olderr); + __set_errno (olderr); - nis_freeresult (result); - return status; - } + nis_freeresult (result); + return status; + } - int parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen, + parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen, errnop); - nis_freeresult (result); + nis_freeresult (result); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) + if (parse_res < 1) { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - else - { - __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } } + return NSS_STATUS_SUCCESS; } - - return NSS_STATUS_SUCCESS; } enum nss_status @@ -400,12 +368,8 @@ _nss_nisplus_getservbyport_r (const int number, const char *protocol, { if (tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } @@ -415,49 +379,50 @@ _nss_nisplus_getservbyport_r (const int number, const char *protocol, *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } - - char buf[17 + 3 * sizeof (int) + strlen (protocol) + tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[port=%d,proto=%s],%s", - number, protocol, tablename_val); - - nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, - NULL, NULL); - - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) + else { - enum nss_status status = niserr2nss (result->status); + int parse_res; + nis_result *result; + char buf[60 + strlen (protocol) + tablename_len]; + int olderr = errno; - __set_errno (olderr); + sprintf (buf, "[port=%d,proto=%s],%s", + number, protocol, tablename_val); - nis_freeresult (result); - return status; - } - - int parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen, - errnop); - nis_freeresult (result); + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) + if (result == NULL) { - *errnop = ERANGE; + *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } - else + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { + enum nss_status status = niserr2nss (result->status); + __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + + nis_freeresult (result); + return status; } - } - return NSS_STATUS_SUCCESS; + parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen, + errnop); + nis_freeresult (result); + + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } diff --git a/nis/nss_nisplus/nisplus-spwd.c b/nis/nss_nisplus/nisplus-spwd.c index f256f3eb90..c317469137 100644 --- a/nis/nss_nisplus/nisplus-spwd.c +++ b/nis/nss_nisplus/nisplus-spwd.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2007 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -31,12 +30,29 @@ __libc_lock_define_initialized (static, lock) static nis_result *result; +static nis_name tablename_val; +static u_long tablename_len; -/* Defined in nisplus-pwd.c. */ -extern nis_name pwd_tablename_val attribute_hidden; -extern size_t pwd_tablename_len attribute_hidden; -extern enum nss_status _nss_pwd_create_tablename (int *errnop); +static enum nss_status +_nss_create_tablename (int *errnop) +{ + if (tablename_val == NULL) + { + char buf [40 + strlen (nis_local_directory ())]; + char *p; + p = __stpcpy (buf, "passwd.org_dir."); + p = __stpcpy (p, nis_local_directory ()); + tablename_val = __strdup (buf); + if (tablename_val == NULL) + { + *errnop = errno; + return NSS_STATUS_TRYAGAIN; + } + tablename_len = strlen (tablename_val); + } + return NSS_STATUS_SUCCESS; +} enum nss_status _nss_nisplus_setspent (int stayopen) @@ -46,14 +62,12 @@ _nss_nisplus_setspent (int stayopen) __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; - if (pwd_tablename_val == NULL) - status = _nss_pwd_create_tablename (&err); + if (tablename_val == NULL) + status = _nss_create_tablename (&err); __libc_lock_unlock (lock); @@ -65,11 +79,9 @@ _nss_nisplus_endspent (void) { __libc_lock_lock (lock); - if (result != NULL) - { - nis_freeresult (result); - result = NULL; - } + if (result) + nis_freeresult (result); + result = NULL; __libc_lock_unlock (lock); @@ -91,32 +103,25 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen, { saved_res = NULL; - if (pwd_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_pwd_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; } - result = nis_first_entry (pwd_tablename_val); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + result = nis_first_entry (tablename_val); if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) return niserr2nss (result->status); } else { + nis_result *res; + saved_res = result; - result = nis_next_entry (pwd_tablename_val, &result->cookie); - if (result == NULL) - { - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - } + res = nis_next_entry (tablename_val, &result->cookie); + result = res; if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { nis_freeresult (saved_res); @@ -126,18 +131,19 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen, parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen, errnop); - if (__builtin_expect (parse_res == -1, 0)) + if (parse_res == -1) { nis_freeresult (result); result = saved_res; *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - - if (saved_res != NULL) - nis_freeresult (saved_res); - } - while (!parse_res); + else + { + if (saved_res) + nis_freeresult (saved_res); + } + } while (!parse_res); return NSS_STATUS_SUCCESS; } @@ -163,9 +169,9 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp, { int parse_res; - if (pwd_tablename_val == NULL) + if (tablename_val == NULL) { - enum nss_status status = _nss_pwd_create_tablename (errnop); + enum nss_status status = _nss_create_tablename (errnop); if (status != NSS_STATUS_SUCCESS) return status; @@ -176,47 +182,48 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp, *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } - - nis_result *result; - char buf[strlen (name) + 9 + pwd_tablename_len]; - int olderr = errno; - - snprintf (buf, sizeof (buf), "[name=%s],%s", name, pwd_tablename_val); - - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL); - - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - - if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) + else { - enum nss_status status = niserr2nss (result->status); + nis_result *result; + char buf[strlen (name) + 24 + tablename_len]; + int olderr = errno; - __set_errno (olderr); + sprintf (buf, "[name=%s],%s", name, tablename_val); - nis_freeresult (result); - return status; - } + result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen, errnop); - nis_freeresult (result); - - if (__builtin_expect (parse_res < 1, 0)) - { - if (parse_res == -1) + if (result == NULL) { - *errnop = ERANGE; + *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; } - else + if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { + enum nss_status status = niserr2nss (result->status); + __set_errno (olderr); - return NSS_STATUS_NOTFOUND; + + nis_freeresult (result); + return status; } - } - return NSS_STATUS_SUCCESS; + parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen, + errnop); + nis_freeresult (result); + + if (parse_res < 1) + { + if (parse_res == -1) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + else + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + } + return NSS_STATUS_SUCCESS; + } } |