getent(1) hosts enumeration defunc (getent.c 1.6)

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

getent(1) hosts enumeration defunc (getent.c 1.6)

Marcus MERIGHI
there is no more listing (enumerating) of hosts entries. Suspect: [1]
+++++++
$ getent hosts; echo $?
0
$ getent hosts fifi
127.0.0.1                               fifi
$ getent ethers
getent: Enumeration not supported on ethers
+++++++
So this is inconsistent at least and it introduced different behaviour.

I could provide a man page fix and/or a current.html entry but fixing
getent.c is beyond my coding foo.

[1]
http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/getent/getent.c.diff?r1=1.5;r2=1.6

OpenBSD 5.3-current (GENERIC.MP) #103: Wed Apr 24 09:33:02 MDT 2013
    [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc (getent.c 1.6)

Stuart Henderson-6
On 2013/04/26 12:57, MERIGHI Marcus wrote:

> there is no more listing (enumerating) of hosts entries. Suspect: [1]
> +++++++
> $ getent hosts; echo $?
> 0
> $ getent hosts fifi
> 127.0.0.1                               fifi
> $ getent ethers
> getent: Enumeration not supported on ethers
> +++++++
> So this is inconsistent at least and it introduced different behaviour.
>
> I could provide a man page fix and/or a current.html entry but fixing
> getent.c is beyond my coding foo.
>
> [1]
> http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/getent/getent.c.diff?r1=1.5;r2=1.6
>
> OpenBSD 5.3-current (GENERIC.MP) #103: Wed Apr 24 09:33:02 MDT 2013
>     [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>

This wasn't caused by that commit; previously there was no output
but exit code 127.

This does work as expected on a Mar 12 system, so this was more likely
caused by the switch to asr.

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc (getent.c 1.6)

Florian Obser-2
In reply to this post by Marcus MERIGHI
On Fri, Apr 26, 2013 at 12:57:32PM +0200, MERIGHI Marcus wrote:
> there is no more listing (enumerating) of hosts entries. Suspect: [1]
[...]
> [1]
> http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/getent/getent.c.diff?r1=1.5;r2=1.6
>
> OpenBSD 5.3-current (GENERIC.MP) #103: Wed Apr 24 09:33:02 MDT 2013
>     [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>

nope, this change works fine on a Mar 13 snap, I suspect asr

--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Marcus MERIGHI
Hello,

(this was on tech@, therefore reviving it here.)

getent(1) manual and output stil do not match. It does not enumerate for
database ``hosts'' and does not return 3 as exit status, as stated by
the man page.

Bye, Marcus

[hidden email] (Stuart Henderson), 2013.04.26 (Fri) 13:27 (CEST):

> On 2013/04/26 12:57, MERIGHI Marcus wrote:
> > there is no more listing (enumerating) of hosts entries. Suspect: [1]
> > +++++++
> > $ getent hosts; echo $?
> > 0
> > $ getent hosts fifi
> > 127.0.0.1                               fifi
> > $ getent ethers
> > getent: Enumeration not supported on ethers
> > +++++++
> > So this is inconsistent at least and it introduced different behaviour.
> >
> > I could provide a man page fix and/or a current.html entry but fixing
> > getent.c is beyond my coding foo.
> >
> > [1]
> > http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/getent/getent.c.diff?r1=1.5;r2=1.6
> >
> > OpenBSD 5.3-current (GENERIC.MP) #103: Wed Apr 24 09:33:02 MDT 2013
> >     [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> >
>
> This wasn't caused by that commit; previously there was no output
> but exit code 127.
>
> This does work as expected on a Mar 12 system, so this was more likely
> caused by the switch to asr.

[hidden email] (Florian Obser), 2013.04.26 (Fri) 13:31 (CEST):

> On Fri, Apr 26, 2013 at 12:57:32PM +0200, MERIGHI Marcus wrote:
> > there is no more listing (enumerating) of hosts entries. Suspect: [1]
> [...]
> > [1]
> > http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/getent/getent.c.diff?r1=1.5;r2=1.6
> >
> > OpenBSD 5.3-current (GENERIC.MP) #103: Wed Apr 24 09:33:02 MDT 2013
> >     [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> >
>
> nope, this change works fine on a Mar 13 snap, I suspect asr

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Ingo Schwarze
Hi,

this summer, Marcus MERIGHI reported that gethostent(3) was completely
destroyed during the switch to asr, i guess unintentionally.

Until somebody writes something better, i suggest to resurrect
the last working version from the Attic, file gethostnamadr.c,v 1.73.
I'm not attempting to do anything clever here, just putting back
the old code into the new location (the old location can no longer
be used because asr is now squatting on the filename), with minimal
changes to the glue to make it work again.

Probably, this code could be improved (code cleanup, YP integration,
...) but i'm not doing that here: One thing at a time.

The Copyright notice states the year when this particular code was
actually added to the CSRG SCCS repository by Kevin Dunlap (kjd).
Between 1986 and the import into OpenBSD, no significant changes
happened to these functions.  In particular, no part of this came
from BIND and no part is covered by DEC Copyright.  After OpenBSD
import, there were significant changes (in particular with respect
to IPv6), but as those authors did not add their Copyright notices,
i'm not doing that in this patch, either.

OK?
  Ingo


Index: asr/sethostent.c
===================================================================
RCS file: /cvs/src/lib/libc/asr/sethostent.c,v
retrieving revision 1.1
diff -u -p -r1.1 sethostent.c
--- asr/sethostent.c 8 Sep 2012 11:08:21 -0000 1.1
+++ asr/sethostent.c 18 Oct 2014 22:59:10 -0000
@@ -1,41 +1,140 @@
-/* $OpenBSD: sethostent.c,v 1.1 2012/09/08 11:08:21 eric Exp $ */
+/* $OpenBSD: gethostnamadr.c,v 1.73 2009/11/18 07:43:22 guenther Exp $ */
 /*
- * Copyright (c) 2012 Eric Faurot <[hidden email]>
+ * Copyright (c) 1986
+ * The Regents of the University of California.  All rights reserved.
  *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
-#include <sys/types.h>
-#include <netinet/in.h>
-
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
 #include <netdb.h>
-#include <resolv.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+static char *h_addr_ptrs[MAXADDRS + 1];
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[BUFSIZ+1];
+static union {
+ struct in_addr _host_in_addr;
+ u_char _host_addr[16]; /* IPv4 or IPv6 */
+} _host_addr_u;
+#define host_addr _host_addr_u._host_addr
+static FILE *hostf = NULL;
 
-/* XXX these functions do nothing for now */
+extern int h_errno;
 
 void
-sethostent(int stayopen)
+sethostent(int dummy)
 {
+ if (hostf != NULL)
+ rewind(hostf);
 }
 
 void
 endhostent(void)
 {
+ if (hostf != NULL) {
+ fclose(hostf);
+ hostf = NULL;
+ }
 }
 
 struct hostent *
 gethostent(void)
 {
- h_errno = NETDB_INTERNAL;
- return (NULL);
+ char *p, *cp, **q;
+ int af;
+ size_t len;
+
+ host.h_addrtype = AF_UNSPEC;
+ host.h_length = 0;
+
+ if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ again:
+ if ((p = fgetln(hostf, &len)) == NULL) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ if (p[len-1] == '\n')
+ len--;
+ if (len >= sizeof(hostbuf) || len == 0)
+ goto again;
+ p = memcpy(hostbuf, p, len);
+ hostbuf[len] = '\0';
+ if (*p == '#')
+ goto again;
+ if ((cp = strchr(p, '#')))
+ *cp = '\0';
+ if (!(cp = strpbrk(p, " \t")))
+ goto again;
+ *cp++ = '\0';
+ if (inet_pton(AF_INET6, p, host_addr) > 0) {
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else if (inet_pton(AF_INET, p, host_addr) > 0) {
+ af = AF_INET;
+ len = INADDRSZ;
+ } else {
+ goto again;
+ }
+ /* if this is not something we're looking for, skip it. */
+ if (host.h_addrtype != AF_UNSPEC && host.h_addrtype != af)
+ goto again;
+ if (host.h_length != 0 && host.h_length != len)
+ goto again;
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ host.h_length = len;
+ host.h_addrtype = af;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ host.h_name = cp;
+ q = host.h_aliases = host_aliases;
+ if ((cp = strpbrk(cp, " \t")))
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ if ((cp = strpbrk(cp, " \t")))
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ h_errno = NETDB_SUCCESS;
+ return (&host);
 }

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Philip Guenther-2
On Saturday, October 18, 2014, Ingo Schwarze <[hidden email]> wrote:
>
> this summer, Marcus MERIGHI reported that gethostent(3) was completely
> destroyed during the switch to asr, i guess unintentionally
>

Does someone have a legitimate use for gethostent(), even the simple
version that just uses /etc/hosts?  It's been removed from POSIX and I'm at
loss to think of a use of it that wouldnt make further nonportable
assumptions.

Maybe we just fix getent(1) to return an error like it does for ethers?


Philip Guenther
Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Theo de Raadt
In reply to this post by Marcus MERIGHI
> Maybe we just fix getent(1) to return an error like it does for ethers?

That is my take on this too.  /etc/networks scanning serves no modern
purpose, and programs that do so only show their age.

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Ingo Schwarze
In reply to this post by Philip Guenther-2
Hi Philip,

Philip Guenther wrote on Sat, Oct 18, 2014 at 04:38:09PM -0700:

> Maybe we just fix getent(1) to return an error like it does for ethers?

Whatever we do with gethostent(3) - maybe it's really expendable,
maybe tons of ports depend on it, who knows - i'm fine with
removing hosts enumeration support from getent(1).

Almost the same can be accomplished with

  cat /etc/hosts

and with more clarity as to what it does and what the shortcomings are.

That would be the following patch:

Yours,
  Ingo


Index: getent.c
===================================================================
RCS file: /cvs/src/usr.bin/getent/getent.c,v
retrieving revision 1.6
diff -u -p -r1.6 getent.c
--- getent.c 30 Mar 2013 14:03:08 -0000 1.6
+++ getent.c 19 Oct 2014 00:23:47 -0000
@@ -270,8 +270,9 @@ hosts(int argc, char *argv[])
 
  sethostent(1);
  if (argc == 2) {
- while ((he = gethostent()) != NULL)
- hostsprint(he);
+ fprintf(stderr, "%s: Enumeration not supported on hosts\n",
+    __progname);
+ rv = RV_NOENUM;
  } else {
  for (i = 2; i < argc; i++) {
  he = NULL;

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Theo de Raadt
In reply to this post by Marcus MERIGHI
>> Maybe we just fix getent(1) to return an error like it does for ethers?
>
>Whatever we do with gethostent(3) - maybe it's really expendable,
>maybe tons of ports depend on it, who knows - i'm fine with
>removing hosts enumeration support from getent(1).
>
>Almost the same can be accomplished with
>
>  cat /etc/hosts
>
>and with more clarity as to what it does and what the shortcomings are.
>
>That would be the following patch:
>
>Yours,
>  Ingo
>
>
>Index: getent.c
>===================================================================
>RCS file: /cvs/src/usr.bin/getent/getent.c,v
>retrieving revision 1.6
>diff -u -p -r1.6 getent.c
>--- getent.c 30 Mar 2013 14:03:08 -0000 1.6
>+++ getent.c 19 Oct 2014 00:23:47 -0000
>@@ -270,8 +270,9 @@ hosts(int argc, char *argv[])
>
> sethostent(1);
> if (argc == 2) {
>- while ((he = gethostent()) != NULL)
>- hostsprint(he);
>+ fprintf(stderr, "%s: Enumeration not supported on hosts\n",
>+    __progname);
>+ rv = RV_NOENUM;
> } else {
> for (i = 2; i < argc; i++) {
> he = NULL;

Looks good.  Nothing else in base uses gethostent(3) except for perl
supplying it as a stub, and I see nothing using that.

The ports situation might be interesting.  Any program using gethostent(3)
will be returning different information than the other APIs -- it always
has..

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Philip Guenther-2
In reply to this post by Ingo Schwarze
On Sat, Oct 18, 2014 at 5:24 PM, Ingo Schwarze <[hidden email]> wrote:

> Index: getent.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/getent/getent.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 getent.c
> --- getent.c    30 Mar 2013 14:03:08 -0000      1.6
> +++ getent.c    19 Oct 2014 00:23:47 -0000
> @@ -270,8 +270,9 @@ hosts(int argc, char *argv[])
>
>         sethostent(1);
>         if (argc == 2) {
> -               while ((he = gethostent()) != NULL)
> -                       hostsprint(he);
> +               fprintf(stderr, "%s: Enumeration not supported on hosts\n",
> +                   __progname);
> +               rv = RV_NOENUM;
>         } else {
>                 for (i = 2; i < argc; i++) {
>                         he = NULL;

ok guenther@

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Florian Obser-2
In reply to this post by Ingo Schwarze
Hi Ingo,

On Sun, Oct 19, 2014 at 02:24:27AM +0200, Ingo Schwarze wrote:

> Hi Philip,
>
> Philip Guenther wrote on Sat, Oct 18, 2014 at 04:38:09PM -0700:
>
> > Maybe we just fix getent(1) to return an error like it does for ethers?
>
> Whatever we do with gethostent(3) - maybe it's really expendable,
> maybe tons of ports depend on it, who knows - i'm fine with
> removing hosts enumeration support from getent(1).
>
> Almost the same can be accomplished with
>
>   cat /etc/hosts
>
> and with more clarity as to what it does and what the shortcomings are.

thanks for looking into it, this has been on my not-todo pile for quite some time. :)

>
> That would be the following patch:

You can get rid of sethostent(3)/endhostent(3) at the same time. They
are stups in asr and even if they weren't they serve no purpose with
gethostent(3) gone, tweaked patch at the end.

witht that OK florian@

>
> Yours,
>   Ingo
>

diff --git getent.c getent.c
index d991d0c..f479d67 100644
--- getent.c
+++ getent.c
@@ -268,10 +268,10 @@ hosts(int argc, char *argv[])
  int i, rv = RV_OK;
  struct hostent *he;
 
- sethostent(1);
  if (argc == 2) {
- while ((he = gethostent()) != NULL)
- hostsprint(he);
+ fprintf(stderr, "%s: Enumeration not supported on hosts\n",
+    __progname);
+ rv = RV_NOENUM;
  } else {
  for (i = 2; i < argc; i++) {
  he = NULL;
@@ -285,7 +285,6 @@ hosts(int argc, char *argv[])
  break;
  }
  }
- endhostent();
  return rv;
 }
 


--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Theo de Raadt
In reply to this post by Marcus MERIGHI
>You can get rid of sethostent(3)/endhostent(3) at the same time.

Those have to remain stubs for a while longer, because there are
ports which poke at them.

Reply | Threaded
Open this post in threaded view
|

Re: getent(1) hosts enumeration defunc

Ingo Schwarze
Hi Theo,

Theo de Raadt wrote on Sun, Oct 19, 2014 at 07:35:06AM -0600:
> Florian Obser wrote:

>> You can get rid of sethostent(3)/endhostent(3) at the same time.

> Those have to remain stubs for a while longer, because there are
> ports which poke at them.

Oh the joys of terseness.  Florian meant deleting the calls from
the getent(1) source code, not deleting the interface from libc.

Yours,
  Ingo