tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lpd with clients using "privacy" addresses



Hi,

I noticed that modern Windows machines couldn't lpr-print via our
lpd anymore after upgrading it to dual-stack.

The reason is that a) Windows (post-XP) has privacy addresses and
interface id randomization enabled per default, and especially the
former somehow don't make it easy (or actually, desirable) to have
matching forward and backward resolved names in DNS.

OTOH, lpd checks for matching reverse and forward resolved names
*before* checking whether it needs to test for an explicit hostname.

The patch below makes this test, but saves the result for later, and
checks for a '+'-Entry in /etc/hosts.lpd or /etc/hosts.equiv if
needed.

This is in production use at my (work) institution.

You still need a reverse DNS entry, but this alone can be easily done
with a catch-all like

*       IN PTR  unknown-vlan169.department.institution.example.

(The planned big rewriting/replacing of lpd should take this situation
into account btw. - but I need a solution *now* for the existing one.)


I plan to commit next week. Comments?

        -is


Index: lpd.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/lpr/lpd/lpd.8,v
retrieving revision 1.33
diff -u -r1.33 lpd.8
--- lpd.8       22 Jan 2006 21:31:17 -0000      1.33
+++ lpd.8       25 Mar 2011 14:25:14 -0000
@@ -177,6 +177,9 @@
 .Pa /etc/hosts.equiv
 or
 .Pa /etc/hosts.lpd .
+A machine using IPv6 privacy addresses (which, by definition, can't have
+name resolution in both directions) will match a '+' host entry, if the
+reverse zone has at least a catch-all name.
 Lastly, if the
 .Li rs
 capability is specified in the
@@ -186,6 +189,7 @@
 requests will only be honored for those users with accounts on the
 machine with the printer.
 Requests must pass all three tests.
+
 .Pp
 The file
 .Em minfree
Index: lpd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/lpr/lpd/lpd.c,v
retrieving revision 1.55
diff -u -r1.55 lpd.c
--- lpd.c       21 Jul 2008 13:36:58 -0000      1.55
+++ lpd.c       25 Mar 2011 14:25:14 -0000
@@ -133,6 +133,7 @@
 static void            chkhost(struct sockaddr *, int);
 static void            usage(void);
 static struct pollfd   *socksetup(int, int, const char *, int *);
+static void            chkplushost(int, FILE *, char*);
 
 uid_t  uid, euid;
 int child_count;
@@ -362,6 +363,35 @@
        }
 }
 
+/*
+ * If there was a forward/backward name resolution mismatch, check
+ * that there's a '+' entry in fhost.
+ */
+
+void
+chkplushost(int good, FILE *fhost, char *hst)
+{
+       int c1, c2, c3;
+
+       if (good) {
+               return;
+       }
+
+       rewind(fhost);
+       while (EOF != (c1 = fgetc(fhost))) {
+               if (c1 == '+') {
+                       c2 = fgetc(fhost);
+                       if (c2 == ' ' || c2 == '\t' || c2 == '\n') {
+                               return;
+                       }
+               }
+               do {
+                       c3 = fgetc(fhost);
+               } while (c3 != EOF && c3 != '\n');
+       }
+       fatal("address for your hostname (%s) not matched", hst);
+}
+
 static void
 reapchild(int signo)
 {
@@ -606,25 +636,23 @@
                fatal("Cannot print address");
 
        /* Check for spoof, ala rlogind */
+       good = 0;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_UNSPEC;
        hints.ai_socktype = SOCK_DGRAM; /*dummy*/
        error = getaddrinfo(fromb, NULL, &hints, &res);
-       if (error) {
-               fatal("hostname for your address (%s) unknown: %s", hst,
-                   gai_strerror(error));
+       if (!error) {
+               for (r = res; good == 0 && r; r = r->ai_next) {
+                       error = getnameinfo(r->ai_addr, r->ai_addrlen,
+                                   ip, sizeof(ip), NULL, 0, NI_NUMERICHOST);
+                       if (!error && !strcmp(hst, ip))
+                               good = 1;
+               }
+               if (res)
+                       freeaddrinfo(res);
        }
-       good = 0;
-       for (r = res; good == 0 && r; r = r->ai_next) {
-               error = getnameinfo(r->ai_addr, r->ai_addrlen, ip, sizeof(ip),
-                                   NULL, 0, NI_NUMERICHOST);
-               if (!error && !strcmp(hst, ip))
-                       good = 1;
-       }
-       if (res)
-               freeaddrinfo(res);
-       if (good == 0)
-               fatal("address for your hostname (%s) not matched", hst);
+
+       /* complain about !good later in chkplushost if needed. */
 
        setproctitle("serving %s", from);
 
@@ -639,6 +667,7 @@
        hostf = fopen(_PATH_HOSTSEQUIV, "r");
        if (hostf) {
                if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) {
+                       chkplushost(good, hostf, hst);
                        (void)fclose(hostf);
                        return;
                }
@@ -647,6 +676,7 @@
        hostf = fopen(_PATH_HOSTSLPD, "r");
        if (hostf) {
                if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) {
+                       chkplushost(good, hostf, hst);
                        (void)fclose(hostf);
                        return;
                }


Home | Main Index | Thread Index | Old Index