* nis/nss_nisplus/nisplus-service.c: Fix locking to use

_nss_create_tablename.  Avoid unnecessary copying, remove
	unnecessary variables, general cleanup.
	* nis/nss_nisplus/nisplus-rpc.c: Likewise.
	* nis/nss_nisplus/nisplus-proto.c: Likewise..
	* nis/nss_nisplus/nisplus-network.c: Fix locking to use
	_nss_create_tablename.  Avoid unnecessary copying, general cleanup.
	* nis/nss_nisplus/nisplus-hosts.c (_nss_nisplus_getipnodebyname_r):
	Removed.
	Fix locking to use _nss_create_tablename.  Avoid unnecessary copying,
	general cleanup.
	* nis/nss_nisplus/nisplus-ethers.c (_nss_nisplus_getntohost_r):
	Correctly construct request.
	Fix locking to use _nss_create_tablename.  Avoid unnecessary copying,
	general cleanup.
	* nis/nss_nisplus/nisplus-alias.c: Fix locking to use
	_nss_create_tablename.  Avoid unnecessary copying, general cleanup.
This commit is contained in:
Ulrich Drepper 2005-12-03 20:12:27 +00:00
parent 48b293913b
commit 636e689e6f
8 changed files with 913 additions and 761 deletions

View File

@ -1,3 +1,23 @@
2005-12-03 Ulrich Drepper <drepper@redhat.com>
* nis/nss_nisplus/nisplus-service.c: Fix locking to use
_nss_create_tablename. Avoid unnecessary copying, remove
unnecessary variables, general cleanup.
* nis/nss_nisplus/nisplus-rpc.c: Likewise.
* nis/nss_nisplus/nisplus-proto.c: Likewise..
* nis/nss_nisplus/nisplus-network.c: Fix locking to use
_nss_create_tablename. Avoid unnecessary copying, general cleanup.
* nis/nss_nisplus/nisplus-hosts.c (_nss_nisplus_getipnodebyname_r):
Removed.
Fix locking to use _nss_create_tablename. Avoid unnecessary copying,
general cleanup.
* nis/nss_nisplus/nisplus-ethers.c (_nss_nisplus_getntohost_r):
Correctly construct request.
Fix locking to use _nss_create_tablename. Avoid unnecessary copying,
general cleanup.
* nis/nss_nisplus/nisplus-alias.c: Fix locking to use
_nss_create_tablename. Avoid unnecessary copying, general cleanup.
2005-12-02 Ulrich Drepper <drepper@redhat.com>
* nis/nss_nisplus/nisplus-pwd.c (_nss_pwd_create_tablename):

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@ -17,6 +17,7 @@
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>
@ -32,7 +33,7 @@ __libc_lock_define_initialized (static, lock)
static nis_result *result;
static u_long next_entry;
static nis_name tablename_val;
static u_long tablename_len;
static size_t tablename_len;
#define NISENTRYVAL(idx,col,res) \
((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
@ -45,19 +46,26 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "mail_aliases.org_dir.";
p = __stpcpy (buf, "mail_aliases.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -75,81 +83,73 @@ _nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry,
"mail_aliases") != 0
|| result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 2)
return 0;
else
char *first_unused = buffer + NISENTRYLEN (0, 1, result) + 1;
size_t room_left = (buflen - (buflen % __alignof__ (char *))
- NISENTRYLEN (0, 1, result) - 2);
if (NISENTRYLEN (entry, 1, result) >= buflen)
{
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 (NISENTRYLEN(entry, 0, result) >= room_left)
goto no_more_room;
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')
{
/* 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++;
}
}
return alias->alias_members_len == 0 ? 0 : 1;
/* 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';
if (NISENTRYLEN(entry, 0, result) >= room_left)
goto no_more_room;
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;
char *line = buffer;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
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++;
}
}
return alias->alias_members_len == 0 ? 0 : 1;
}
static enum nss_status
@ -158,9 +158,11 @@ internal_setaliasent (void)
enum nss_status status;
int err;
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
@ -203,9 +205,11 @@ _nss_nisplus_endaliasent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
next_entry = 0;
__libc_lock_unlock (lock);
@ -240,7 +244,8 @@ internal_nisplus_getaliasent_r (struct aliasent *alias,
return NSS_STATUS_TRYAGAIN;
++next_entry;
} while (!parse_res);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
@ -268,7 +273,12 @@ _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;
}
@ -278,35 +288,34 @@ _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
else
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)
{
nis_result *result;
char buf[strlen (name) + 30 + tablename_len];
int olderr = errno;
sprintf (buf, "[name=%s],%s", name, tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
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;
}
return NSS_STATUS_SUCCESS;
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
return niserr2nss (result->status);
parse_res = _nss_nisplus_parse_aliasent (result, 0, alias,
buffer, buflen, errnop);
if (__builtin_expect (parse_res < 1, 0))
{
__set_errno (olderr);
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997,1998,2000,2001,2002,2003 Free Software Foundation, Inc.
/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@ -17,15 +17,17 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <nss.h>
#include <errno.h>
#include <atomic.h>
#include <ctype.h>
#include <string.h>
#include <bits/libc-lock.h>
#include <errno.h>
#include <inttypes.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <netinet/ether.h>
#include <rpcsvc/nis.h>
#include <netinet/if_ether.h>
#include <rpcsvc/nis.h>
#include <bits/libc-lock.h>
#include "nss-nisplus.h"
@ -70,7 +72,14 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
room_left -= (NISENTRYLEN (0, 0, result) +1);
ether->e_name = p;
ether->e_addr = *ether_aton (NISENTRYVAL (0, 1, result));
struct ether_addr *ea = ether_aton (NISENTRYVAL (0, 1, result));
if (ea == NULL)
{
*errnop = EINVAL;
return -2;
}
ether->e_addr = *ea;
return 1;
}
@ -80,18 +89,24 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "ethers.org_dir.";
p = __stpcpy (buf, "ethers.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -107,9 +122,11 @@ _nss_nisplus_setetherent (int stayopen)
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
status = NSS_STATUS_UNAVAIL;
@ -124,9 +141,11 @@ _nss_nisplus_endetherent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
@ -178,7 +197,6 @@ 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;
}
@ -258,7 +276,6 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
if (parse_res == -1)
{
nis_freeresult (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
@ -275,8 +292,12 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
{
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;
}
@ -286,44 +307,45 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
else
int parse_res;
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, NULL, NULL);
if (result == NULL)
{
int parse_res;
nis_result *result;
char buf[255 + tablename_len];
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
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]);
if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result == NULL)
parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
buflen, errnop);
if (__builtin_expect (parse_res < 1, 0))
{
if (parse_res == -1)
{
*errnop = ENOMEM;
nis_freeresult (result);
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
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_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1997-2002, 2003, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@ -17,15 +17,16 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <nss.h>
#include <netdb.h>
#include <errno.h>
#include <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <bits/libc-lock.h>
#include <netinet/in.h>
#include <rpcsvc/nis.h>
#include <bits/libc-lock.h>
#include "nss-nisplus.h"
@ -180,19 +181,26 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "hosts.org_dir.";
p = __stpcpy (buf, "hosts.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -204,9 +212,11 @@ _nss_nisplus_sethostent (int stayopen)
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename (&err);
@ -221,9 +231,11 @@ _nss_nisplus_endhostent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
@ -335,8 +347,12 @@ 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;
@ -350,75 +366,81 @@ 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) + 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);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result != NULL)
{
nis_result *result;
char buf[strlen (name) + 255 + tablename_len];
int olderr = errno;
char *bufptr = buf;
/* 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)
{
/* 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);
nis_freeresult (result);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
}
if (result == NULL)
{
*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);
if (parse_res > 0)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
/* 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
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
/* 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, NULL, NULL);
}
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
retval = niserr2nss (result->status);
if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0))
{
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);
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;
}
enum nss_status
@ -431,17 +453,6 @@ _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,
@ -469,62 +480,63 @@ _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;
else
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)
{
nis_result *result;
char buf[255 + tablename_len];
int retval, parse_res;
int olderr = errno;
__set_errno (ENOMEM);
return 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)
retval = niserr2nss (result->status);
if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0))
{
if (retval == NSS_STATUS_TRYAGAIN)
{
__set_errno (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,
((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0));
nis_freeresult (result);
if (parse_res > 0)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
*errnop = errno;
*herrnop = NETDB_INTERNAL;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
__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);
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;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997,1998,2000,2001,2002,2003 Free Software Foundation, Inc.
/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@ -17,15 +17,16 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <nss.h>
#include <netdb.h>
#include <errno.h>
#include <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>
#include <bits/libc-lock.h>
#include <rpcsvc/nis.h>
#include <bits/libc-lock.h>
#include "nss-nisplus.h"
@ -44,12 +45,10 @@ static u_long tablename_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;
@ -61,7 +60,7 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
|| 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,7 +68,7 @@ _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;
@ -77,10 +76,10 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
first_unused += strlen (first_unused) +1;
network->n_addrtype = 0;
network->n_net = inet_network (NISENTRYVAL (0, 2, result));
p = first_unused;
char *p = first_unused;
line = p;
for (i = 0; i < result->objects.objects_len; ++i)
char *line = p;
for (unsigned int i = 0; i < result->objects.objects_len; ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), network->n_name) != 0)
{
@ -107,12 +106,12 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
room_left -= (2 * sizeof (char *));
network->n_aliases[0] = NULL;
i = 0;
unsigned int i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
line++;
++line;
if (*line == '\0')
break;
@ -133,7 +132,7 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
++i;
}
else
network->n_aliases[i+1] = NULL;
network->n_aliases[i + 1] = NULL;
}
return 1;
@ -144,19 +143,26 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "networks.org_dir.";
p = __stpcpy (buf, "networks.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -164,16 +170,20 @@ enum nss_status
_nss_nisplus_setnetent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename (&err);
{
int err;
status = _nss_create_tablename (&err);
}
__libc_lock_unlock (lock);
@ -185,9 +195,11 @@ _nss_nisplus_endnetent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
@ -220,9 +232,7 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
result = nis_first_entry (tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
retval = niserr2nss (result->status);
int retval = niserr2nss (result->status);
nis_freeresult (result);
result = NULL;
if (retval == NSS_STATUS_TRYAGAIN)
@ -237,16 +247,12 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
}
else
{
nis_result *res;
res = nis_next_entry (tablename_val, &result->cookie);
nis_result *res = nis_next_entry (tablename_val, &result->cookie);
saved_res = result;
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
retval = niserr2nss (result->status);
int retval = niserr2nss (result->status);
nis_freeresult (result);
result = saved_res;
if (retval == NSS_STATUS_TRYAGAIN)
@ -266,7 +272,8 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
return NSS_STATUS_TRYAGAIN;
}
} while (!parse_res);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
@ -296,8 +303,12 @@ _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;
}
@ -308,76 +319,82 @@ _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) + 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);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
if (result != NULL)
{
nis_result *result;
char buf[strlen (name) + 255 + tablename_len];
int olderr = errno;
char *bufptr = buf;
/* 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);
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)
{
__set_errno (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_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;
}
/* 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
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
/* 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_LINKS | FOLLOW_PATH, NULL, NULL);
}
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
retval = niserr2nss (result->status);
if (__builtin_expect (retval != NSS_STATUS_SUCCESS, 0))
{
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);
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;
}
/* XXX type is ignored, SUN's NIS+ table doesn't support it */
@ -388,8 +405,12 @@ _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;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@ -17,13 +17,14 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <nss.h>
#include <errno.h>
#include <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <bits/libc-lock.h>
#include <rpcsvc/nis.h>
#include <bits/libc-lock.h>
#include "nss-nisplus.h"
@ -141,19 +142,26 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "protocols.org_dir.";
p = __stpcpy (buf, "protocols.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -164,9 +172,11 @@ _nss_nisplus_setprotoent (int stayopen)
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
{
@ -184,9 +194,11 @@ _nss_nisplus_endprotoent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
@ -221,11 +233,8 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
}
else
{
nis_result *res;
saved_res = result;
res = nis_next_entry (tablename_val, &result->cookie);
result = res;
result = nis_next_entry (tablename_val, &result->cookie);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
@ -277,79 +286,91 @@ _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
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);
if (result != NULL)
{
nis_result *result;
char buf[strlen (name) + 255 + tablename_len];
int olderr = errno;
char *bufptr = buf;
/* 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)
{
/* 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,
/* 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)
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);
}
if (result == NULL)
|| result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val);
else
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
/* 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 (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
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;
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
}
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
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;
}
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;
}
enum nss_status
@ -358,55 +379,57 @@ _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;
}
{
int parse_res;
nis_result *result;
char buf[46 + tablename_len];
int olderr = errno;
char buf[12 + 3 * sizeof (number) + tablename_len];
int olderr = errno;
sprintf (buf, "[number=%d],%s", number, tablename_val);
snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
nis_result *result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, 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;
}
nis_freeresult (result);
int parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen,
errnop);
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);
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;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@ -17,13 +17,14 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <nss.h>
#include <errno.h>
#include <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <nss.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"
@ -138,19 +139,26 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "rpc.org_dir.";
p = __stpcpy (buf, "rpc.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -159,16 +167,20 @@ enum nss_status
_nss_nisplus_setrpcent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename (&err);
{
int err;
status = _nss_create_tablename (&err);
}
__libc_lock_unlock (lock);
@ -180,9 +192,11 @@ _nss_nisplus_endrpcent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
@ -217,11 +231,8 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
}
else
{
nis_result *res;
saved_res = result;
res = nis_next_entry (tablename_val, &result->cookie);
result = res;
result = nis_next_entry (tablename_val, &result->cookie);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
@ -243,7 +254,8 @@ 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;
}
@ -271,77 +283,89 @@ _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
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);
if (result != NULL)
{
nis_result *result;
char buf[strlen (name) + 255 + tablename_len];
int olderr = errno;
char *bufptr = buf;
/* 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)
/* 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 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);
nis_freeresult (result);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS , NULL, 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 (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;
}
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;
}
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS , 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);
__set_errno (olderr);
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;
}
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
@ -350,55 +374,57 @@ _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;
}
{
int parse_res;
nis_result *result;
char buf[100 + tablename_len];
int olderr = errno;
char buf[12 + 3 * sizeof (number) + tablename_len];
int olderr = errno;
sprintf (buf, "[number=%d],%s", number, tablename_val);
snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
nis_result *result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, 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_rpcent (result, rpc, buffer, buflen,
errnop);
nis_freeresult (result);
return status;
}
nis_freeresult (result);
int parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen,
errnop);
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);
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;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997,1998,1999,2001,2002,2003 Free Software Foundation, Inc.
/* Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@ -17,13 +17,14 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <nss.h>
#include <errno.h>
#include <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <bits/libc-lock.h>
#include <rpcsvc/nis.h>
#include <bits/libc-lock.h>
#include "nss-nisplus.h"
@ -45,8 +46,6 @@ _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;
@ -81,10 +80,10 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
first_unused += strlen (first_unused) + 1;
serv->s_port = htons (atoi (NISENTRYVAL (0, 3, result)));
p = first_unused;
char *p = first_unused;
line = p;
for (i = 0; i < result->objects.objects_len; ++i)
char *line = p;
for (unsigned int i = 0; i < result->objects.objects_len; ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), serv->s_name) != 0)
{
@ -110,7 +109,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
room_left -= (sizeof (char *));
serv->s_aliases[0] = NULL;
i = 0;
unsigned int i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
@ -147,19 +146,26 @@ _nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "services.org_dir.";
p = __stpcpy (buf, "services.org_dir.");
p = __stpcpy (p, nis_local_directory ());
tablename_val = __strdup (buf);
char *p = malloc (sizeof (prefix) + local_dir_len);
if (tablename_val == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
tablename_len = strlen (tablename_val);
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
@ -172,9 +178,11 @@ _nss_nisplus_setservent (int stayopen)
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename (&err);
@ -189,9 +197,11 @@ _nss_nisplus_endservent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
@ -226,11 +236,8 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
}
else
{
nis_result *res;
saved_res = result;
res = nis_next_entry (tablename_val, &result->cookie);
result = res;
result = nis_next_entry (tablename_val, &result->cookie);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
@ -240,7 +247,7 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
parse_res = _nss_nisplus_parse_servent (result, serv, buffer,
buflen, errnop);
if (parse_res == -1)
if (__builtin_expect (parse_res == -1, 0))
{
nis_freeresult (result);
result = saved_res;
@ -262,11 +269,9 @@ enum nss_status
_nss_nisplus_getservent_r (struct servent *result, char *buffer,
size_t buflen, int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getservent_r (result, buffer, buflen, errnop);
int status = internal_nisplus_getservent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
@ -278,12 +283,14 @@ _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;
}
@ -293,72 +300,82 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
*errnop = EINVAL;
return NSS_STATUS_NOTFOUND;
}
else
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, NULL, NULL);
if (result != NULL)
{
nis_result *result;
char buf[strlen (name) + 255 + tablename_len];
int olderr = errno;
char *bufptr = buf;
/* 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)
/* 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,
"services_tbl") != 0
|| result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
snprintf (buf, sizeof (buf), "[cname=%s,proto=%s],%s", name, protocol,
tablename_val);
else
{
/* 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 (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, 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 (result == NULL)
nis_freeresult (result);
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS, 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);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen,
errnop);
nis_freeresult (result);
if (__builtin_expect (parse_res < 1, 0))
{
if (parse_res == -1)
{
*errnop = ENOMEM;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
else
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
return NSS_STATUS_NOTFOUND;
}
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;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
@ -368,8 +385,12 @@ _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;
}
@ -379,50 +400,48 @@ _nss_nisplus_getservbyport_r (const int number, const char *protocol,
*errnop = EINVAL;
return NSS_STATUS_NOTFOUND;
}
else
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, NULL, NULL);
if (result == NULL)
{
int parse_res;
nis_result *result;
char buf[60 + strlen (protocol) + tablename_len];
int olderr = errno;
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
sprintf (buf, "[port=%d,proto=%s],%s",
number, protocol, tablename_val);
if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
{
enum nss_status status = niserr2nss (result->status);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
__set_errno (olderr);
if (result == NULL)
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen,
errnop);
nis_freeresult (result);
if (__builtin_expect (parse_res < 1, 0))
{
if (parse_res == -1)
{
*errnop = ENOMEM;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
else
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
return NSS_STATUS_NOTFOUND;
}
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;
}
return NSS_STATUS_SUCCESS;
}