2c84d2e
diff -up cups-1.4b2-svn8404/CHANGES-1.3.txt.CVE-2009-0164 cups-1.4b2-svn8404/CHANGES-1.3.txt
2c84d2e
--- cups-1.4b2-svn8404/CHANGES-1.3.txt.CVE-2009-0164	2009-03-05 10:54:00.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/CHANGES-1.3.txt	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -69,11 +69,6 @@ CHANGES IN CUPS V1.3.10
2c84d2e
 	- The scheduler now rejects ATTR: messages with empty values.
2c84d2e
 	- The scheduler could consume all CPU handling closed connections
2c84d2e
 	  (STR #2988)
2c84d2e
-	- The scheduler now protects against DNS rebinding attacks on
2c84d2e
-	  localhost.
2c84d2e
-	- SECURITY: The PNG image reading code did not validate the
2c84d2e
-	  image size properly, leading to a potential buffer overflow
2c84d2e
-	  (STR #2974)
2c84d2e
 	- Fixed some configure script bugs with rc/xinetd directories
2c84d2e
 	  (STR #2970)
2c84d2e
 	- The Epson sample driver PPDs contained errors (STR #2979)
2c84d2e
diff -up cups-1.4b2-svn8404/cups/http-addr.c.CVE-2009-0164 cups-1.4b2-svn8404/cups/http-addr.c
2c84d2e
--- cups-1.4b2-svn8404/cups/http-addr.c.CVE-2009-0164	2009-02-17 17:45:27.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/cups/http-addr.c	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -154,7 +154,7 @@ httpAddrLocalhost(
2c84d2e
 #endif /* AF_LOCAL */
2c84d2e
 
2c84d2e
   if (addr->addr.sa_family == AF_INET &&
2c84d2e
-      ntohl(addr->ipv4.sin_addr.s_addr) == 0x7f000001)
2c84d2e
+      (ntohl(addr->ipv4.sin_addr.s_addr) & 0xff000000) == 0x7f000000)
2c84d2e
     return (1);
2c84d2e
 
2c84d2e
   return (0);
2c84d2e
diff -up cups-1.4b2-svn8404/cups/http.c.CVE-2009-0164 cups-1.4b2-svn8404/cups/http.c
ed173fc
--- cups-1.4b2-svn8404/cups/http.c.CVE-2009-0164	2009-04-26 13:22:11.000000000 +0100
ed173fc
+++ cups-1.4b2-svn8404/cups/http.c	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -1842,18 +1842,35 @@ httpSetField(http_t       *http,	/* I - 
2c84d2e
 
2c84d2e
   strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
2c84d2e
 
2c84d2e
- /*
2c84d2e
-  * Special case for Authorization: as its contents can be
2c84d2e
-  * longer than HTTP_MAX_VALUE
2c84d2e
-  */
2c84d2e
-
2c84d2e
   if (field == HTTP_FIELD_AUTHORIZATION)
2c84d2e
   {
2c84d2e
+   /*
2c84d2e
+    * Special case for Authorization: as its contents can be
2c84d2e
+    * longer than HTTP_MAX_VALUE
2c84d2e
+    */
2c84d2e
+
2c84d2e
     if (http->field_authorization)
2c84d2e
       free(http->field_authorization);
2c84d2e
 
2c84d2e
     http->field_authorization = strdup(value);
2c84d2e
   }
2c84d2e
+  else if (field == HTTP_FIELD_HOST)
2c84d2e
+  {
2c84d2e
+   /*
2c84d2e
+    * Special-case for Host: as we don't want a trailing "." on the hostname.
2c84d2e
+    */
2c84d2e
+
2c84d2e
+    char *ptr = http->fields[HTTP_FIELD_HOST];
2c84d2e
+					/* Pointer into Host: field */
2c84d2e
+
2c84d2e
+    if (*ptr)
2c84d2e
+    {
2c84d2e
+      ptr += strlen(ptr) - 1;
2c84d2e
+
2c84d2e
+      if (*ptr == '.')
2c84d2e
+        *ptr = '\0';
2c84d2e
+    }
2c84d2e
+  }
2c84d2e
 }
2c84d2e
 
2c84d2e
 
2c84d2e
diff -up cups-1.4b2-svn8404/man/cupsd.conf.man.in.CVE-2009-0164 cups-1.4b2-svn8404/man/cupsd.conf.man.in
2c84d2e
--- cups-1.4b2-svn8404/man/cupsd.conf.man.in.CVE-2009-0164	2009-02-17 17:45:27.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/man/cupsd.conf.man.in	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -617,6 +617,11 @@ ServerAdmin user@domain.com
2c84d2e
 .br
2c84d2e
 Specifies the email address of the server administrator.
2c84d2e
 .TP 5
2c84d2e
+ServerAlias hostname
2c84d2e
+.br
2c84d2e
+Specifies an alternate name that the server is known by. The special name "*"
2c84d2e
+allows any name to be used.
2c84d2e
+.TP 5
2c84d2e
 ServerBin directory
2c84d2e
 .br
2c84d2e
 Specifies the directory where backends, CGIs, daemons, and filters may
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/client.c.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/client.c
2c84d2e
--- cups-1.4b2-svn8404/scheduler/client.c.CVE-2009-0164	2009-03-05 10:54:00.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/scheduler/client.c	2009-04-26 13:38:34.000000000 +0100
2c84d2e
@@ -39,6 +39,7 @@
2c84d2e
  *   is_path_absolute()      - Is a path absolute and free of relative elements.
2c84d2e
  *   make_certificate()      - Make a self-signed SSL/TLS certificate.
2c84d2e
  *   pipe_command()          - Pipe the output of a command to the remote client.
2c84d2e
+ *   valid_host()            - Is the Host: field valid?
2c84d2e
  *   write_file()            - Send a file via HTTP.
2c84d2e
  *   write_pipe()            - Flag that data is available on the CGI pipe.
2c84d2e
  */
2c84d2e
@@ -108,6 +109,7 @@ static int		make_certificate(cupsd_clien
2c84d2e
 #endif /* HAVE_SSL */
2c84d2e
 static int		pipe_command(cupsd_client_t *con, int infile, int *outfile,
2c84d2e
 			             char *command, char *options, int root);
2c84d2e
+static int		valid_host(cupsd_client_t *con);
2c84d2e
 static int		write_file(cupsd_client_t *con, http_status_t code,
2c84d2e
 		        	   char *filename, char *type,
2c84d2e
 				   struct stat *filestats);
2c84d2e
@@ -1129,13 +1131,7 @@ cupsdReadClient(cupsd_client_t *con)	/* 
2c84d2e
 	return;
2c84d2e
       }
2c84d2e
     }
2c84d2e
-    else if (httpAddrLocalhost(con->http.hostaddr) &&
2c84d2e
-             strcasecmp(con->http.fields[HTTP_FIELD_HOST], "localhost") &&
2c84d2e
-	     strncasecmp(con->http.fields[HTTP_FIELD_HOST], "localhost:", 10) &&
2c84d2e
-	     strcmp(con->http.fields[HTTP_FIELD_HOST], "127.0.0.1") &&
2c84d2e
-	     strncmp(con->http.fields[HTTP_FIELD_HOST], "127.0.0.1:", 10) &&
2c84d2e
-	     strcmp(con->http.fields[HTTP_FIELD_HOST], "[::1]") &&
2c84d2e
-	     strncmp(con->http.fields[HTTP_FIELD_HOST], "[::1]:", 6))
2c84d2e
+    else if (!valid_host(con))
2c84d2e
     {
2c84d2e
      /*
2c84d2e
       * Access to localhost must use "localhost" or the corresponding IPv4
2c84d2e
@@ -3278,6 +3274,10 @@ get_cdsa_certificate(cupsd_client_t *con
2c84d2e
   ssl_options.ServerName = con->servername;
2c84d2e
   ssl_options.ServerNameLen = strlen(con->servername);
2c84d2e
 
2c84d2e
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
2c84d2e
+                  "get_cdsa_certificate: Looking for certs for \"%s\"...",
2c84d2e
+		  con->servername);
2c84d2e
+
2c84d2e
   options.Data = (uint8 *)&ssl_options;
2c84d2e
   options.Length = sizeof(ssl_options);
2c84d2e
 
2c84d2e
@@ -3970,7 +3970,7 @@ make_certificate(cupsd_client_t *con)	/*
2c84d2e
     envp[envc]   = NULL;
2c84d2e
 
2c84d2e
     if (!cupsdStartProcess(command, argv, envp, -1, -1, -1, -1, -1, 1, NULL, 0,
2c84d2e
-                           &pid))
2c84d2e
+                           NULL, &pid))
2c84d2e
     {
2c84d2e
       unlink(seedfile);
2c84d2e
       return (0);
ed173fc
@@ -4862,6 +4862,166 @@ pipe_command(cupsd_client_t *con,	/* I -
2c84d2e
 
2c84d2e
 
2c84d2e
 /*
2c84d2e
+ * 'valid_host()' - Is the Host: field valid?
2c84d2e
+ */
2c84d2e
+
2c84d2e
+static int				/* O - 1 if valid, 0 if not */
2c84d2e
+valid_host(cupsd_client_t *con)		/* I - Client connection */
2c84d2e
+{
2c84d2e
+  cupsd_alias_t	*a;			/* Current alias */
2c84d2e
+  cupsd_netif_t	*netif;			/* Current network interface */
2c84d2e
+  const char	*host,			/* Host field */
2c84d2e
+		*end;			/* End character */
2c84d2e
+
2c84d2e
+
2c84d2e
+  host = con->http.fields[HTTP_FIELD_HOST];
2c84d2e
+
2c84d2e
+  if (httpAddrLocalhost(con->http.hostaddr))
2c84d2e
+  {
2c84d2e
+   /*
2c84d2e
+    * Only allow "localhost" or the equivalent IPv4 or IPv6 numerical
2c84d2e
+    * addresses when accessing CUPS via the loopback interface...
2c84d2e
+    */
2c84d2e
+
2c84d2e
+    return (!strcasecmp(host, "localhost") ||
2c84d2e
+            !strncasecmp(host, "localhost:", 10) ||
2c84d2e
+	    !strcasecmp(host, "localhost.") ||
2c84d2e
+            !strncasecmp(host, "localhost.:", 11) ||
2c84d2e
+#ifdef __linux
2c84d2e
+	    !strcasecmp(host, "localhost.localdomain") ||
2c84d2e
+            !strncasecmp(host, "localhost.localdomain:", 22) ||
2c84d2e
+#endif /* __linux */
2c84d2e
+            !strcmp(host, "127.0.0.1") ||
2c84d2e
+	    !strncmp(host, "127.0.0.1:", 10) ||
2c84d2e
+	    !strcmp(host, "[::1]") ||
ed173fc
+	    !strncmp(host, "[::1]:", 6) ||
ed173fc
+	    !strcmp(host, "::1"));
2c84d2e
+  }
2c84d2e
+
2c84d2e
+#ifdef HAVE_DNSSD
2c84d2e
+ /*
2c84d2e
+  * Check if the hostname is something.local (Bonjour); if so, allow it.
2c84d2e
+  */
2c84d2e
+
2c84d2e
+  if ((end = strrchr(host, '.')) != NULL &&
2c84d2e
+      (!strcasecmp(end, ".local") || !strncasecmp(end, ".local:", 7) ||
2c84d2e
+       !strcasecmp(end, ".local.") || !strncasecmp(end, ".local.:", 8)))
2c84d2e
+    return (1);
2c84d2e
+#endif /* HAVE_DNSSD */
2c84d2e
+
2c84d2e
+ /*
2c84d2e
+  * Check if the hostname is an IP address...
2c84d2e
+  */
2c84d2e
+
2c84d2e
+  if (isdigit(*host & 255) || *host == '[')
2c84d2e
+  {
2c84d2e
+   /*
2c84d2e
+    * Possible IPv4/IPv6 address...
2c84d2e
+    */
2c84d2e
+
2c84d2e
+    char	temp[1024],		/* Temporary string */
2c84d2e
+		*ptr;			/* Pointer into temporary string */
2c84d2e
+    http_addrlist_t *addrlist;		/* List of addresses */
2c84d2e
+
2c84d2e
+
2c84d2e
+    strlcpy(temp, host, sizeof(temp));
2c84d2e
+    if ((ptr = strrchr(temp, ':')) != NULL && !strchr(ptr, ']'))
2c84d2e
+      *ptr = '\0';			/* Strip :port from host value */
2c84d2e
+
2c84d2e
+    if ((addrlist = httpAddrGetList(temp, AF_UNSPEC, NULL)) != NULL)
2c84d2e
+    {
2c84d2e
+     /*
2c84d2e
+      * Good IPv4/IPv6 address...
2c84d2e
+      */
2c84d2e
+
2c84d2e
+      httpAddrFreeList(addrlist);
2c84d2e
+      return (1);
2c84d2e
+    }
2c84d2e
+  }
2c84d2e
+
2c84d2e
+ /*
2c84d2e
+  * Check for (alias) name matches...
2c84d2e
+  */
2c84d2e
+
2c84d2e
+  for (a = (cupsd_alias_t *)cupsArrayFirst(ServerAlias);
2c84d2e
+       a;
2c84d2e
+       a = (cupsd_alias_t *)cupsArrayNext(ServerAlias))
2c84d2e
+  {
2c84d2e
+   /*
2c84d2e
+    * "ServerAlias *" allows all host values through...
2c84d2e
+    */
2c84d2e
+
2c84d2e
+    if (!strcmp(a->name, "*"))
2c84d2e
+      return (1);
2c84d2e
+
2c84d2e
+    if (!strncasecmp(host, a->name, a->namelen))
2c84d2e
+    {
2c84d2e
+     /*
2c84d2e
+      * Prefix matches; check the character at the end - it must be ":", ".",
2c84d2e
+      * ".:", or nul...
2c84d2e
+      */
2c84d2e
+
2c84d2e
+      end = host + a->namelen;
2c84d2e
+
2c84d2e
+      if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':')))
2c84d2e
+        return (1);
2c84d2e
+    }
2c84d2e
+  }
2c84d2e
+
2c84d2e
+#ifdef HAVE_DNSSD
2c84d2e
+  for (a = (cupsd_alias_t *)cupsArrayFirst(DNSSDAlias);
2c84d2e
+       a;
2c84d2e
+       a = (cupsd_alias_t *)cupsArrayNext(DNSSDAlias))
2c84d2e
+  {
2c84d2e
+   /*
2c84d2e
+    * "ServerAlias *" allows all host values through...
2c84d2e
+    */
2c84d2e
+
2c84d2e
+    if (!strcmp(a->name, "*"))
2c84d2e
+      return (1);
2c84d2e
+
2c84d2e
+    if (!strncasecmp(host, a->name, a->namelen))
2c84d2e
+    {
2c84d2e
+     /*
2c84d2e
+      * Prefix matches; check the character at the end - it must be ":", ".",
2c84d2e
+      * ".:", or nul...
2c84d2e
+      */
2c84d2e
+
2c84d2e
+      end = host + a->namelen;
2c84d2e
+
2c84d2e
+      if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':')))
2c84d2e
+        return (1);
2c84d2e
+    }
2c84d2e
+  }
2c84d2e
+#endif /* HAVE_DNSSD */
2c84d2e
+
2c84d2e
+ /*
2c84d2e
+  * Check for interface hostname matches...
2c84d2e
+  */
2c84d2e
+
2c84d2e
+  for (netif = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
2c84d2e
+       netif;
2c84d2e
+       netif = (cupsd_netif_t *)cupsArrayNext(NetIFList))
2c84d2e
+  {
2c84d2e
+    if (!strncasecmp(host, netif->hostname, netif->hostlen))
2c84d2e
+    {
2c84d2e
+     /*
2c84d2e
+      * Prefix matches; check the character at the end - it must be ":", ".",
2c84d2e
+      * ".:", or nul...
2c84d2e
+      */
2c84d2e
+
2c84d2e
+      end = host + netif->hostlen;
2c84d2e
+
2c84d2e
+      if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':')))
2c84d2e
+        return (1);
2c84d2e
+    }
2c84d2e
+  }
2c84d2e
+
2c84d2e
+  return (0);
2c84d2e
+}
2c84d2e
+
2c84d2e
+
2c84d2e
+/*
2c84d2e
  * 'write_file()' - Send a file via HTTP.
2c84d2e
  */
2c84d2e
 
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/conf.c.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/conf.c
ed173fc
--- cups-1.4b2-svn8404/scheduler/conf.c.CVE-2009-0164	2009-04-26 13:22:11.000000000 +0100
ed173fc
+++ cups-1.4b2-svn8404/scheduler/conf.c	2009-04-26 13:43:59.000000000 +0100
2c84d2e
@@ -14,13 +14,15 @@
2c84d2e
  *
2c84d2e
  * Contents:
2c84d2e
  *
2c84d2e
+ *   cupsdAddAlias()          - Add a host alias.
2c84d2e
  *   cupsdCheckPermissions()  - Fix the mode and ownership of a file or
2c84d2e
  *                              directory.
2c84d2e
+ *   cupsdFreeAliases()       - Free all of the alias entries.
2c84d2e
  *   cupsdReadConfiguration() - Read the cupsd.conf file.
2c84d2e
  *   get_address()            - Get an address + port number from a line.
2c84d2e
  *   get_addr_and_mask()      - Get an IP address and netmask.
2c84d2e
- *   parse_aaa()              - Parse authentication, authorization, and
2c84d2e
- *                              access control lines.
2c84d2e
+ *   parse_aaa()              - Parse authentication, authorization, and access
2c84d2e
+ *                              control lines.
2c84d2e
  *   parse_fatal_errors()     - Parse FatalErrors values in a string.
2c84d2e
  *   parse_groups()           - Parse system group names in a string.
2c84d2e
  *   parse_protocols()        - Parse browse protocols in a string.
2c84d2e
@@ -197,6 +199,7 @@ static const unsigned	zeros[4] =
2c84d2e
 /*
2c84d2e
  * Local functions...
2c84d2e
  */
2c84d2e
+
2c84d2e
 static http_addrlist_t	*get_address(const char *value, int defport);
2c84d2e
 static int		get_addr_and_mask(const char *value, unsigned *ip,
2c84d2e
 			                  unsigned *mask);
2c84d2e
@@ -211,6 +214,30 @@ static int		read_policy(cups_file_t *fp,
2c84d2e
 
2c84d2e
 
2c84d2e
 /*
2c84d2e
+ * 'cupsdAddAlias()' - Add a host alias.
2c84d2e
+ */
2c84d2e
+
2c84d2e
+void
2c84d2e
+cupsdAddAlias(cups_array_t *aliases,	/* I - Array of aliases */
2c84d2e
+              const char   *name)	/* I - Name to add */
2c84d2e
+{
2c84d2e
+  cupsd_alias_t	*a;			/*  New alias */
2c84d2e
+  size_t	namelen;		/* Length of name */
2c84d2e
+
2c84d2e
+
2c84d2e
+  namelen = strlen(name);
2c84d2e
+
2c84d2e
+  if ((a = (cupsd_alias_t *)malloc(sizeof(cupsd_alias_t) + namelen)) == NULL)
2c84d2e
+    return;
2c84d2e
+
2c84d2e
+  a->namelen = namelen;
2c84d2e
+  strcpy(a->name, name);		/* OK since a->name is allocated */
2c84d2e
+
2c84d2e
+  cupsArrayAdd(aliases, a);
2c84d2e
+}
2c84d2e
+
2c84d2e
+
2c84d2e
+/*
2c84d2e
  * 'cupsdCheckPermissions()' - Fix the mode and ownership of a file or directory.
2c84d2e
  */
2c84d2e
 
2c84d2e
@@ -362,6 +389,25 @@ cupsdCheckPermissions(
2c84d2e
 
2c84d2e
 
2c84d2e
 /*
2c84d2e
+ * 'cupsdFreeAliases()' - Free all of the alias entries.
2c84d2e
+ */
2c84d2e
+
2c84d2e
+void
2c84d2e
+cupsdFreeAliases(cups_array_t *aliases)	/* I - Array of aliases */
2c84d2e
+{
2c84d2e
+  cupsd_alias_t	*a;			/* Current alias */
2c84d2e
+
2c84d2e
+
2c84d2e
+  for (a = (cupsd_alias_t *)cupsArrayFirst(ServerAlias);
2c84d2e
+       a;
2c84d2e
+       a = (cupsd_alias_t *)cupsArrayNext(ServerAlias))
2c84d2e
+    free(a);
2c84d2e
+
2c84d2e
+  cupsArrayDelete(aliases);
2c84d2e
+}
2c84d2e
+
2c84d2e
+
2c84d2e
+/*
2c84d2e
  * 'cupsdReadConfiguration()' - Read the cupsd.conf file.
2c84d2e
  */
2c84d2e
 
2c84d2e
@@ -433,6 +479,9 @@ cupsdReadConfiguration(void)
2c84d2e
   * String options...
2c84d2e
   */
2c84d2e
 
2c84d2e
+  cupsdFreeAliases(ServerAlias);
2c84d2e
+  ServerAlias = NULL;
2c84d2e
+
2c84d2e
   cupsdClearString(&ServerName);
2c84d2e
   cupsdClearString(&ServerAdmin);
2c84d2e
   cupsdSetString(&ServerBin, CUPS_SERVERBIN);
2c84d2e
@@ -674,9 +723,7 @@ cupsdReadConfiguration(void)
2c84d2e
 
2c84d2e
   if (!ServerName)
2c84d2e
   {
2c84d2e
-    if (HostNameLookups || RemoteAccessEnabled)
2c84d2e
-      httpGetHostname(NULL, temp, sizeof(temp));
2c84d2e
-    else if (gethostname(temp, sizeof(temp)))
2c84d2e
+    if (gethostname(temp, sizeof(temp)))
2c84d2e
     {
2c84d2e
       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get hostname: %s",
2c84d2e
                       strerror(errno));
ed173fc
@@ -686,6 +733,54 @@ cupsdReadConfiguration(void)
2c84d2e
     cupsdSetString(&ServerName, temp);
ed173fc
   }
ed173fc
 
ed173fc
+  if (!ServerAlias)
ed173fc
+    ServerAlias = cupsArrayNew(NULL, NULL);
2c84d2e
+
ed173fc
+  cupsdAddAlias(ServerAlias, ServerName);
ed173fc
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", ServerName);
2c84d2e
+
ed173fc
+  if (HostNameLookups || RemoteAccessEnabled)
ed173fc
+  {
ed173fc
+    struct hostent	*host;		/* Host entry to get FQDN */
2c84d2e
+
ed173fc
+    if ((host = gethostbyname(ServerName)) != NULL)
2c84d2e
+    {
ed173fc
+      if (strcasecmp(ServerName, host->h_name))
ed173fc
+      {
ed173fc
+	cupsdSetString(&ServerName, host->h_name);
ed173fc
+	cupsdAddAlias(ServerAlias, host->h_name);
ed173fc
+	cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s",
ed173fc
+			host->h_name);
ed173fc
+      }
2c84d2e
+
ed173fc
+      if (host->h_aliases)
2c84d2e
+      {
ed173fc
+	for (i = 0; host->h_aliases[i]; i ++)
ed173fc
+	  if (strcasecmp(ServerName, host->h_aliases[i]))
ed173fc
+	  {
ed173fc
+	    cupsdAddAlias(ServerAlias, host->h_aliases[i]);
ed173fc
+	    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s",
ed173fc
+			    host->h_aliases[i]);
ed173fc
+	  }
2c84d2e
+      }
2c84d2e
+    }
ed173fc
+  }
2c84d2e
+
ed173fc
+ /*
ed173fc
+  * Make sure we have the base hostname added as an alias, too!
ed173fc
+  */
ed173fc
+
ed173fc
+  if ((slash = strchr(ServerName, '.')) != NULL)
ed173fc
+  {
ed173fc
+    size_t n = slash - ServerName;
ed173fc
+    if (n > sizeof(temp) - 1)
ed173fc
+      n = sizeof(temp) - 1;
ed173fc
+    memcpy (temp, ServerName, n);
ed173fc
+    temp[n] = '\0';
ed173fc
+    cupsdAddAlias(ServerAlias, temp);
ed173fc
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp);
ed173fc
+  }
2c84d2e
+
2c84d2e
   for (slash = ServerName; isdigit(*slash & 255) || *slash == '.'; slash ++);
ed173fc
 
ed173fc
   ServerNameIsIP = !*slash;
ed173fc
@@ -3278,6 +3373,13 @@ read_configuration(cups_file_t *fp)	/* I
2c84d2e
 	    break;
2c84d2e
       }
2c84d2e
     }
2c84d2e
+    else if (!strcasecmp(line, "ServerAlias") && value)
2c84d2e
+    {
2c84d2e
+      if (!ServerAlias)
2c84d2e
+        ServerAlias = cupsArrayNew(NULL, NULL);
2c84d2e
+
2c84d2e
+      cupsdAddAlias(ServerAlias, value);
2c84d2e
+    }
2c84d2e
     else if (!strcasecmp(line, "SetEnv") && value)
2c84d2e
     {
2c84d2e
      /*
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/conf.h.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/conf.h
ed173fc
--- cups-1.4b2-svn8404/scheduler/conf.h.CVE-2009-0164	2009-04-26 13:22:11.000000000 +0100
ed173fc
+++ cups-1.4b2-svn8404/scheduler/conf.h	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -82,6 +82,17 @@ typedef enum
2c84d2e
 
2c84d2e
 
2c84d2e
 /*
2c84d2e
+ * ServerAlias data...
2c84d2e
+ */
2c84d2e
+
2c84d2e
+typedef struct
2c84d2e
+{
2c84d2e
+  size_t	namelen;		/* Length of alias name */
2c84d2e
+  char		name[1];		/* Alias name */
2c84d2e
+} cupsd_alias_t;
2c84d2e
+
2c84d2e
+
2c84d2e
+/*
2c84d2e
  * Globals...
2c84d2e
  */
2c84d2e
 
2c84d2e
@@ -105,6 +116,8 @@ VAR char		*ConfigurationFile	VALUE(NULL)
2c84d2e
 					/* Directory for request files */
2c84d2e
 			*DocumentRoot		VALUE(NULL);
2c84d2e
 					/* Root directory for documents */
2c84d2e
+VAR cups_array_t	*ServerAlias		VALUE(NULL);
2c84d2e
+					/* Alias names for server */
2c84d2e
 VAR int			RemoteAccessEnabled	VALUE(0),
2c84d2e
 					/* Are we listening on non-local addresses? */
2c84d2e
 			ServerNameIsIP		VALUE(0);
2c84d2e
@@ -269,10 +282,12 @@ VAR char		*SystemGroupAuthKey	VALUE(NULL
2c84d2e
  * Prototypes...
2c84d2e
  */
2c84d2e
 
2c84d2e
+extern void	cupsdAddAlias(cups_array_t *aliases, const char *name);
2c84d2e
 extern int	cupsdCheckPermissions(const char *filename,
2c84d2e
 		                      const char *suffix, int mode,
2c84d2e
 	 			      int user, int group, int is_dir,
2c84d2e
 				      int create_dir);
2c84d2e
+extern void	cupsdFreeAliases(cups_array_t *aliases);
2c84d2e
 extern char	*cupsdGetDateTime(struct timeval *t, cupsd_time_t format);
2c84d2e
 #ifdef HAVE_GSSAPI
2c84d2e
 extern int	cupsdLogGSSMessage(int level, int major_status,
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/dirsvc.c.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/dirsvc.c
ed173fc
--- cups-1.4b2-svn8404/scheduler/dirsvc.c.CVE-2009-0164	2009-04-26 13:22:11.000000000 +0100
ed173fc
+++ cups-1.4b2-svn8404/scheduler/dirsvc.c	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -38,6 +38,7 @@
2c84d2e
  *   cupsdUpdateLDAPBrowse()    - Scan for new printers via LDAP...
2c84d2e
  *   cupsdUpdateSLPBrowse()     - Get browsing information via SLP.
2c84d2e
  *   dequote()                  - Remote quotes from a string.
2c84d2e
+ *   dnssdAddAlias()            - Add a DNS-SD alias name.
2c84d2e
  *   dnssdBuildTxtRecord()      - Build a TXT record from printer info.
2c84d2e
  *   dnssdComparePrinters()     - Compare the registered names of two printers.
2c84d2e
  *   dnssdDeregisterPrinter()   - Stop sending broadcast information for a
2c84d2e
@@ -155,6 +156,10 @@ static void	update_smb(int onoff);
2c84d2e
 
2c84d2e
 
2c84d2e
 #ifdef HAVE_DNSSD
2c84d2e
+#  ifdef HAVE_COREFOUNDATION
2c84d2e
+static void	dnssdAddAlias(const void *key, const void *value,
2c84d2e
+		              void *context);
2c84d2e
+#  endif /* HAVE_COREFOUNDATION */
2c84d2e
 static char	*dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
2c84d2e
 		                     int for_lpd);
2c84d2e
 static int	dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
2c84d2e
@@ -2199,6 +2204,38 @@ dequote(char       *d,			/* I - Destinat
2c84d2e
 
2c84d2e
 
2c84d2e
 #ifdef HAVE_DNSSD
2c84d2e
+#  ifdef HAVE_COREFOUNDATION
2c84d2e
+/*
2c84d2e
+ * 'dnssdAddAlias()' - Add a DNS-SD alias name.
2c84d2e
+ */
2c84d2e
+
2c84d2e
+static void
2c84d2e
+dnssdAddAlias(const void *key,		/* I - Key */
2c84d2e
+              const void *value,	/* I - Value (domain) */
2c84d2e
+	      void       *context)	/* I - Unused */
2c84d2e
+{
2c84d2e
+  char	valueStr[1024],			/* Domain string */
2c84d2e
+	hostname[1024];			/* Complete hostname */
2c84d2e
+
2c84d2e
+
2c84d2e
+  (void)context;
2c84d2e
+
2c84d2e
+  if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() &&
2c84d2e
+      CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr),
2c84d2e
+                         kCFStringEncodingUTF8))
2c84d2e
+  {
2c84d2e
+    snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDName, valueStr);
2c84d2e
+    if (!DNSSDAlias)
2c84d2e
+      DNSSDAlias = cupsArrayNew(NULL, NULL);
2c84d2e
+
2c84d2e
+    cupsdAddAlias(DNSSDAlias, hostname);
2c84d2e
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s",
2c84d2e
+		    hostname);
2c84d2e
+  }
2c84d2e
+}
2c84d2e
+#  endif /* HAVE_COREFOUNDATION */
2c84d2e
+
2c84d2e
+
2c84d2e
 /*
2c84d2e
  * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
2c84d2e
  */
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/dirsvc.h.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/dirsvc.h
2c84d2e
--- cups-1.4b2-svn8404/scheduler/dirsvc.h.CVE-2009-0164	2009-02-17 17:45:27.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/scheduler/dirsvc.h	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -4,7 +4,7 @@
2c84d2e
  *   Directory services definitions for the Common UNIX Printing System
2c84d2e
  *   (CUPS) scheduler.
2c84d2e
  *
2c84d2e
- *   Copyright 2007-2008 by Apple Inc.
2c84d2e
+ *   Copyright 2007-2009 by Apple Inc.
2c84d2e
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
2c84d2e
  *
2c84d2e
  *   These coded instructions, statements, and computer programs are the
2c84d2e
@@ -135,6 +135,8 @@ VAR cupsd_statbuf_t	*PollStatusBuffer VA
2c84d2e
 #ifdef HAVE_DNSSD
2c84d2e
 VAR char		*DNSSDName	VALUE(NULL);
2c84d2e
 					/* Computer/server name */
2c84d2e
+VAR cups_array_t	*DNSSDAlias	VALUE(NULL);
2c84d2e
+					/* List of dynamic ServerAlias's */
2c84d2e
 VAR int			DNSSDPort	VALUE(0);
2c84d2e
 					/* Port number to register */
2c84d2e
 VAR cups_array_t	*DNSSDPrinters	VALUE(NULL);
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/network.c.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/network.c
2c84d2e
--- cups-1.4b2-svn8404/scheduler/network.c.CVE-2009-0164	2009-02-05 10:57:28.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/scheduler/network.c	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -101,6 +101,7 @@ cupsdNetIFUpdate(void)
2c84d2e
   struct ifaddrs	*addrs,		/* Interface address list */
2c84d2e
 			*addr;		/* Current interface address */
2c84d2e
   char			hostname[1024];	/* Hostname for address */
2c84d2e
+  size_t		hostlen;	/* Length of hostname */
2c84d2e
 
2c84d2e
 
2c84d2e
  /*
2c84d2e
@@ -176,8 +177,8 @@ cupsdNetIFUpdate(void)
2c84d2e
     * Create a new address element...
2c84d2e
     */
2c84d2e
 
2c84d2e
-    if ((temp = calloc(1, sizeof(cupsd_netif_t) +
2c84d2e
-                          strlen(hostname))) == NULL)
2c84d2e
+    hostlen = strlen(hostname);
2c84d2e
+    if ((temp = calloc(1, sizeof(cupsd_netif_t) + hostlen)) == NULL)
2c84d2e
       break;
2c84d2e
 
2c84d2e
    /*
2c84d2e
@@ -185,6 +186,7 @@ cupsdNetIFUpdate(void)
2c84d2e
     */
2c84d2e
 
2c84d2e
     strlcpy(temp->name, addr->ifa_name, sizeof(temp->name));
2c84d2e
+    temp->hostlen = hostlen;
2c84d2e
     strcpy(temp->hostname, hostname);	/* Safe because hostname is allocated */
2c84d2e
 
2c84d2e
     if (addr->ifa_addr->sa_family == AF_INET)
2c84d2e
diff -up cups-1.4b2-svn8404/scheduler/network.h.CVE-2009-0164 cups-1.4b2-svn8404/scheduler/network.h
2c84d2e
--- cups-1.4b2-svn8404/scheduler/network.h.CVE-2009-0164	2008-12-03 15:39:53.000000000 +0000
ed173fc
+++ cups-1.4b2-svn8404/scheduler/network.h	2009-04-26 13:22:11.000000000 +0100
2c84d2e
@@ -4,7 +4,7 @@
2c84d2e
  *   Network interface definitions for the Common UNIX Printing System
2c84d2e
  *   (CUPS) scheduler.
2c84d2e
  *
2c84d2e
- *   Copyright 2007 by Apple Inc.
2c84d2e
+ *   Copyright 2007-2009 by Apple Inc.
2c84d2e
  *   Copyright 1997-2006 by Easy Software Products, all rights reserved.
2c84d2e
  *
2c84d2e
  *   These coded instructions, statements, and computer programs are the
2c84d2e
@@ -25,6 +25,7 @@ typedef struct cupsd_netif_s		/**** Netw
2c84d2e
   http_addr_t		address,	/* Network address */
2c84d2e
 			mask,		/* Network mask */
2c84d2e
 			broadcast;	/* Broadcast address */
2c84d2e
+  size_t		hostlen;	/* Length of hostname */
2c84d2e
   char			name[32],	/* Network interface name */
2c84d2e
 			hostname[1];	/* Hostname associated with interface */
2c84d2e
 } cupsd_netif_t;