]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/dirsvc.c
Merge changes from CUPS 1.5svn-r9641
[thirdparty/cups.git] / scheduler / dirsvc.c
index dfa996a86c59e58a4a7eb019b35220252d8ceba7..ad05fe4c3818266b42af443623e9c3afd9daf6d7 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * "$Id: dirsvc.c 7933 2008-09-11 00:44:58Z mike $"
  *
- *   Directory services routines for the Common UNIX Printing System (CUPS).
+ *   Directory services routines for the CUPS scheduler.
  *
- *   Copyright 2007-2009 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -38,6 +38,7 @@
  *   cupsdUpdateLDAPBrowse()    - Scan for new printers via LDAP...
  *   cupsdUpdateSLPBrowse()     - Get browsing information via SLP.
  *   dequote()                  - Remote quotes from a string.
+ *   dnssdAddAlias()            - Add a DNS-SD alias name.
  *   dnssdBuildTxtRecord()      - Build a TXT record from printer info.
  *   dnssdComparePrinters()     - Compare the registered names of two printers.
  *   dnssdDeregisterPrinter()   - Stop sending broadcast information for a
@@ -49,6 +50,7 @@
  *                                printer or update the broadcast contents.
  *   dnssdStop()                - Stop all DNS-SD registrations.
  *   dnssdUpdate()              - Handle DNS-SD queries.
+ *   get_auth_info_required()   - Get the auth-info-required value to advertise.
  *   get_hostconfig()           - Get an /etc/hostconfig service setting.
  *   is_local_queue()           - Determine whether the URI points at a local
  *                                queue.
@@ -62,6 +64,7 @@
  *   send_ldap_ou()             - Send LDAP ou registrations.
  *   send_ldap_browse()         - Send LDAP printer registrations.
  *   ldap_dereg_printer()       - Delete printer from directory
+ *   ldap_dereg_ou()            - Remove the organizational unit.
  *   send_slp_browse()          - Register the specified printer with SLP.
  *   slp_attr_callback()        - SLP attribute callback
  *   slp_dereg_printer()        - SLPDereg() the specified printer
  */
 
 static char    *dequote(char *d, const char *s, int dlen);
+static char    *get_auth_info_required(cupsd_printer_t *p, char *buffer,
+                                       size_t bufsize);
 #ifdef __APPLE__
 static int     get_hostconfig(const char *name);
 #endif /* __APPLE__ */
@@ -115,7 +120,7 @@ static void process_implicit_classes(void);
 static void    send_cups_browse(cupsd_printer_t *p);
 #ifdef HAVE_LDAP
 static LDAP    *ldap_connect(void);
-static void    ldap_reconnect(void);
+static LDAP    *ldap_reconnect(void);
 static void    ldap_disconnect(LDAP *ld);
 static int     ldap_search_rec(LDAP *ld, char *base, int scope,
                                 char *filter, char *attrs[],
@@ -155,6 +160,10 @@ static void        update_smb(int onoff);
 
 
 #ifdef HAVE_DNSSD
+#  ifdef HAVE_COREFOUNDATION
+static void    dnssdAddAlias(const void *key, const void *value,
+                             void *context);
+#  endif /* HAVE_COREFOUNDATION */
 static char    *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
                                     int for_lpd);
 static int     dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
@@ -245,7 +254,8 @@ cupsdDeregisterPrinter(
                  removeit);
 
   if (!Browsing || !p->shared ||
-      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                  CUPS_PRINTER_SCANNER)))
     return;
 
  /*
@@ -451,6 +461,14 @@ cupsdLoadRemoteCache(void)
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Syntax error on line %d of remote.cache.", linenum);
     }
+    else if (!strcasecmp(line, "UUID"))
+    {
+      if (value && !strncmp(value, "urn:uuid:", 9))
+        cupsdSetString(&(p->uuid), value);
+      else
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Bad UUID on line %d of remote.cache.", linenum);
+    }
     else if (!strcasecmp(line, "Info"))
     {
       if (value)
@@ -624,7 +642,7 @@ cupsdLoadRemoteCache(void)
       if (value)
       {
         p->deny_users = 0;
-        cupsdAddPrinterUser(p, value);
+        cupsdAddString(&(p->users), value);
       }
       else
        cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -635,7 +653,7 @@ cupsdLoadRemoteCache(void)
       if (value)
       {
         p->deny_users = 1;
-        cupsdAddPrinterUser(p, value);
+        cupsdAddString(&(p->users), value);
       }
       else
        cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -675,7 +693,8 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
                   p->name);
 
   if (!Browsing || !BrowseLocalProtocols ||
-      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                  CUPS_PRINTER_SCANNER)))
     return;
 
 #ifdef HAVE_LIBSLP
@@ -717,7 +736,8 @@ cupsdSaveRemoteCache(void)
   int                  i;              /* Looping var */
   cups_file_t          *fp;            /* printers.conf file */
   char                 temp[1024],     /* Temporary string */
-                       value[2048];    /* Value string */
+                       value[2048],    /* Value string */
+                       *name;          /* Current user name */
   cupsd_printer_t      *printer;       /* Current printer class */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
@@ -788,6 +808,8 @@ cupsdSaveRemoteCache(void)
 
     cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire);
 
+    cupsFilePrintf(fp, "UUID %s\n", printer->uuid);
+
     if (printer->info)
       cupsFilePutConf(fp, "Info", printer->info);
 
@@ -818,9 +840,10 @@ cupsdSaveRemoteCache(void)
              printer->job_sheets[1]);
     cupsFilePutConf(fp, "JobSheets", value);
 
-    for (i = 0; i < printer->num_users; i ++)
-      cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser",
-                      printer->users[i]);
+    for (name = (char *)cupsArrayFirst(printer->users);
+        name;
+        name = (char *)cupsArrayNext(printer->users))
+      cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", name);
 
     for (i = printer->num_options, option = printer->options;
          i > 0;
@@ -883,7 +906,8 @@ cupsdSendBrowseList(void)
     for (count = 0, p = (cupsd_printer_t *)cupsArrayFirst(Printers);
          count < max_count && p != NULL;
         p = (cupsd_printer_t *)cupsArrayNext(Printers))
-      if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) &&
+      if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                       CUPS_PRINTER_SCANNER)) &&
           p->shared && p->browse_time < ut)
         count ++;
 
@@ -909,7 +933,8 @@ cupsdSendBrowseList(void)
 
       if (!p)
         break;
-      else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
+      else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                           CUPS_PRINTER_SCANNER)) ||
                !p->shared)
         continue;
       else if (p->browse_time < ut)
@@ -985,93 +1010,91 @@ cupsdSendBrowseList(void)
  * 'ldap_rebind_proc()' - Callback function for LDAP rebind
  */
 
-static int
-ldap_rebind_proc (LDAP *RebindLDAPHandle,
-                  LDAP_CONST char *refsp,
-                  ber_tag_t request,
-                  ber_int_t msgid,
-                  void *params)
+static int                             /* O - Result code */
+ldap_rebind_proc(
+    LDAP            *RebindLDAPHandle, /* I - LDAP handle */
+    LDAP_CONST char *refsp,            /* I - ??? */
+    ber_tag_t       request,           /* I - ??? */
+    ber_int_t       msgid,             /* I - ??? */
+    void            *params)           /* I - ??? */
 {
-  int               rc;
+  int          rc;                     /* Result code */
+#    if LDAP_API_VERSION > 3000
+  struct berval        bval;                   /* Bind value */
+#    endif /* LDAP_API_VERSION > 3000 */
 
  /*
   * Bind to new LDAP server...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "ldap_rebind_proc: Rebind to %s", refsp);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_rebind_proc: Rebind to %s", refsp);
 
 #    if LDAP_API_VERSION > 3000
-  struct berval bval;
   bval.bv_val = BrowseLDAPPassword;
   bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
 
-  rc = ldap_sasl_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
+  rc = ldap_sasl_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE,
+                        &bval, NULL, NULL, NULL);
 #    else
-  rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN,
-                   BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
+  rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword,
+                   LDAP_AUTH_SIMPLE);
 #    endif /* LDAP_API_VERSION > 3000 */
 
   return (rc);
 }
 
-#  else /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
 
+#  else /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
 /*
  * 'ldap_rebind_proc()' - Callback function for LDAP rebind
  */
 
-static int
-ldap_rebind_proc (LDAP *RebindLDAPHandle,
-                  char **dnp,
-                  char **passwdp,
-                  int *authmethodp,
-                  int freeit,
-                  void *arg)
+static int                             /* O - Result code */
+ldap_rebind_proc(
+    LDAP *RebindLDAPHandle,            /* I - LDAP handle */
+    char **dnp,                                /* I - ??? */
+    char **passwdp,                    /* I - ??? */
+    int  *authmethodp,                 /* I - ??? */
+    int  freeit,                       /* I - ??? */
+    void *arg)                         /* I - ??? */
 {
-  switch ( freeit ) {
-
-  case 1:
-
-     /*
-      * Free current values...
-      */
-
-      cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                     "ldap_rebind_proc: Free values...");
+  switch (freeit)
+  {
+    case 1:
+       /*
+        * Free current values...
+        */
 
-      if ( dnp && *dnp ) {
-        free( *dnp );
-      }
-      if ( passwdp && *passwdp ) {
-        free( *passwdp );
-      }
-      break;
+        cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_rebind_proc: Free values...");
 
-  case 0:
+        if (dnp && *dnp)
+          free(*dnp);
 
-     /*
-      * Return credentials for LDAP referal...
-      */
-
-      cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                     "ldap_rebind_proc: Return necessary values...");
+        if (passwdp && *passwdp)
+          free(*passwdp);
+        break;
 
-      *dnp = strdup(BrowseLDAPBindDN);
-      *passwdp = strdup(BrowseLDAPPassword);
-      *authmethodp = LDAP_AUTH_SIMPLE;
-      break;
+    case 0:
+       /*
+        * Return credentials for LDAP referal...
+        */
 
-  default:
+        cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                        "ldap_rebind_proc: Return necessary values...");
 
-     /*
-      * Should never happen...
-      */
+        *dnp         = strdup(BrowseLDAPBindDN);
+        *passwdp     = strdup(BrowseLDAPPassword);
+        *authmethodp = LDAP_AUTH_SIMPLE;
+        break;
 
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "LDAP rebind has been called with wrong freeit value!");
-      break;
+    default:
+       /*
+        * Should never happen...
+        */
 
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                        "LDAP rebind has been called with wrong freeit value!");
+        break;
   }
 
   return (LDAP_SUCCESS);
@@ -1085,25 +1108,22 @@ ldap_rebind_proc (LDAP *RebindLDAPHandle,
  * 'ldap_connect()' - Start new LDAP connection
  */
 
-static LDAP *
+static LDAP *                          /* O - LDAP handle */
 ldap_connect(void)
 {
- /* 
-  * Open LDAP handle...
-  */
-
-  int          rc;                             /* LDAP API status */
-  int          version = 3;                    /* LDAP version */
-  struct berval        bv = {0, ""};                   /* SASL bind value */
-  LDAP         *TempBrowseLDAPHandle=NULL;     /* Temporary LDAP Handle */
+  int          rc;                     /* LDAP API status */
+  int          version = 3;            /* LDAP version */
+  struct berval        bv = {0, ""};           /* SASL bind value */
+  LDAP         *TempBrowseLDAPHandle=NULL;
+                                       /* Temporary LDAP Handle */
 #  if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
-  int          ldap_ssl = 0;                   /* LDAP SSL indicator */
-  int          ssl_err = 0;                    /* LDAP SSL error value */
+  int          ldap_ssl = 0;           /* LDAP SSL indicator */
+  int          ssl_err = 0;            /* LDAP SSL error value */
 #  endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
 
+
 #  ifdef HAVE_OPENLDAP
 #    ifdef HAVE_LDAP_SSL
-
  /*
   * Set the certificate file to use for encrypted LDAP sessions...
   */
@@ -1111,7 +1131,7 @@ ldap_connect(void)
   if (BrowseLDAPCACertFile)
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "cupsdStartBrowsing: Setting CA certificate file \"%s\"",
+                   "ldap_connect: Setting CA certificate file \"%s\"",
                     BrowseLDAPCACertFile);
 
     if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
@@ -1120,8 +1140,8 @@ ldap_connect(void)
                       "Unable to set CA certificate file for LDAP "
                       "connections: %d - %s", rc, ldap_err2string(rc));
   }
-
 #    endif /* HAVE_LDAP_SSL */
+
  /*
   * Initialize OPENLDAP connection...
   * LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
@@ -1142,26 +1162,27 @@ ldap_connect(void)
   * Split LDAP URI into its components...
   */
 
-  if (! BrowseLDAPServer)
+  if (!BrowseLDAPServer)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "BrowseLDAPServer not configured! Disable LDAP browsing!");
-    BrowseLocalProtocols &= ~BROWSE_LDAP;
+    cupsdLogMessage(CUPSD_LOG_ERROR, "BrowseLDAPServer not configured!");
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
+    BrowseLocalProtocols  &= ~BROWSE_LDAP;
     BrowseRemoteProtocols &= ~BROWSE_LDAP;
     return (NULL);
   }
 
-  sscanf(BrowseLDAPServer, "%10[^:]://%254[^:/]:%d", ldap_protocol, ldap_host, &ldap_port);
+  sscanf(BrowseLDAPServer, "%10[^:]://%254[^:/]:%d", ldap_protocol, ldap_host,
+         &ldap_port);
 
-  if (strcmp(ldap_protocol, "ldap") == 0) {
+  if (!strcmp(ldap_protocol, "ldap"))
     ldap_ssl = 0;
-  } else if (strcmp(ldap_protocol, "ldaps") == 0) {
+  else if (!strcmp(ldap_protocol, "ldaps"))
     ldap_ssl = 1;
-  } else {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "unrecognised ldap protocol (%s)!", ldap_protocol);
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Disable LDAP browsing!");
+  else
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unrecognized LDAP protocol (%s)!",
+                    ldap_protocol);
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
     BrowseLocalProtocols &= ~BROWSE_LDAP;
     BrowseRemoteProtocols &= ~BROWSE_LDAP;
     return (NULL);
@@ -1175,15 +1196,14 @@ ldap_connect(void)
       ldap_port = LDAP_PORT;
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG,
-                  "LDAP Connection Details: PROT:%s HOST:%s PORT:%d",
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "ldap_connect: PROT:%s HOST:%s PORT:%d",
                   ldap_protocol, ldap_host, ldap_port);
 
  /*
   * Initialize LDAP connection...
   */
 
-  if (! ldap_ssl)
+  if (!ldap_ssl)
   {
     if ((TempBrowseLDAPHandle = ldap_init(ldap_host, ldap_port)) == NULL)
       rc = LDAP_OPERATIONS_ERROR;
@@ -1194,19 +1214,23 @@ ldap_connect(void)
   }
   else
   {
-
    /*
     * Initialize SSL LDAP connection...
     */
+
     if (BrowseLDAPCACertFile)
     {
       rc = ldapssl_client_init(BrowseLDAPCACertFile, (void *)NULL);
-      if (rc != LDAP_SUCCESS) {
+      if (rc != LDAP_SUCCESS)
+      {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                         "Failed to initialize LDAP SSL client!");
         rc = LDAP_OPERATIONS_ERROR;
-      } else {
-        if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port, 1)) == NULL)
+      }
+      else
+      {
+        if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port,
+                                                 1)) == NULL)
           rc = LDAP_OPERATIONS_ERROR;
         else
           rc = LDAP_SUCCESS;
@@ -1226,7 +1250,7 @@ ldap_connect(void)
     */
 
     cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "LDAP client libraries does not support TLS");
+                    "LDAP client libraries do not support SSL");
     rc = LDAP_OPERATIONS_ERROR;
 
 #    endif /* HAVE_LDAP_SSL */
@@ -1239,105 +1263,104 @@ ldap_connect(void)
 
   if (rc != LDAP_SUCCESS)
   {
-    if ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to initialize LDAP! Temporary disable LDAP browsing...");
-    }
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize LDAP!");
+
+    if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Temporarily disabling LDAP browsing...");
     else
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to initialize LDAP! Disable LDAP browsing!");
-      BrowseLocalProtocols &= ~BROWSE_LDAP;
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
+
+      BrowseLocalProtocols  &= ~BROWSE_LDAP;
       BrowseRemoteProtocols &= ~BROWSE_LDAP;
     }
 
     ldap_disconnect(TempBrowseLDAPHandle);
-    TempBrowseLDAPHandle = NULL;
+
+    return (NULL);
   }
 
  /*
   * Upgrade LDAP version...
   */
 
-  else if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
+  if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
                            (const void *)&version) != LDAP_SUCCESS)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                   "Unable to set LDAP protocol version %d! Disable LDAP browsing!",
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set LDAP protocol version %d!",
                    version);
-    BrowseLocalProtocols &= ~BROWSE_LDAP;
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
+
+    BrowseLocalProtocols  &= ~BROWSE_LDAP;
     BrowseRemoteProtocols &= ~BROWSE_LDAP;
     ldap_disconnect(TempBrowseLDAPHandle);
-    TempBrowseLDAPHandle = NULL;
+
+    return (NULL);
   }
-  else
-  {
 
  /*
-    * Register LDAP rebind procedure...
-    */
+ /*
+  * Register LDAP rebind procedure...
+  */
 
 #  ifdef HAVE_LDAP_REBIND_PROC
 #    if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
 
-    rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL);
-    if ( rc != LDAP_SUCCESS )
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Setting LDAP rebind function failed with status %d: %s",
-                      rc, ldap_err2string(rc));
+  rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc,
+                            (void *)NULL);
+  if (rc != LDAP_SUCCESS)
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Setting LDAP rebind function failed with status %d: %s",
+                    rc, ldap_err2string(rc));
 
 #    else
 
-    ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL);
+  ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL);
 
 #    endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
 #  endif /* HAVE_LDAP_REBIND_PROC */
 
  /*
-    * Start LDAP bind...
-    */
+ /*
+  * Start LDAP bind...
+  */
 
 #  if LDAP_API_VERSION > 3000
-    struct berval bval;
-    bval.bv_val = BrowseLDAPPassword;
-    bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
+  struct berval bval;
+  bval.bv_val = BrowseLDAPPassword;
+  bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
+
+  if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
+    rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
+                          NULL, NULL);
+  else
+    rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
 
-    if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
-      rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
-                            NULL, NULL);
-    else
-      rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
 #  else
-      rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
-                       BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
+    rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
+                     BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
 #  endif /* LDAP_API_VERSION > 3000 */
 
-    if (rc != LDAP_SUCCESS)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "LDAP bind failed with error %d: %s",
-                      rc, ldap_err2string(rc));
+  if (rc != LDAP_SUCCESS)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP bind failed with error %d: %s",
+                    rc, ldap_err2string(rc));
+
 #  if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
-      if (ldap_ssl && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR)))
-      {
-        ssl_err = PORT_GetError();
-        if (ssl_err != 0)
-          cupsdLogMessage(CUPSD_LOG_ERROR,
-                          "LDAP SSL error %d: %s",
-                          ssl_err, ldapssl_err2string(ssl_err));
-      }
-#  endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
-      ldap_disconnect(TempBrowseLDAPHandle);
-      TempBrowseLDAPHandle = NULL;
-    }
-    else
+    if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR))
     {
-      cupsdLogMessage(CUPSD_LOG_INFO,
-                     "LDAP connection established");
+      ssl_err = PORT_GetError();
+      if (ssl_err != 0)
+        cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP SSL error %d: %s", ssl_err,
+                        ldapssl_err2string(ssl_err));
     }
+#  endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
 
+    ldap_disconnect(TempBrowseLDAPHandle);
+
+    return (NULL);
   }
+
+  cupsdLogMessage(CUPSD_LOG_INFO, "LDAP connection established");
+
   return (TempBrowseLDAPHandle);
 }
 
@@ -1346,29 +1369,30 @@ ldap_connect(void)
  * 'ldap_reconnect()' - Reconnect to LDAP Server
  */
 
-static void
+static LDAP *                          /* O - New LDAP handle */
 ldap_reconnect(void)
 {
-  LDAP         *TempBrowseLDAPHandle = NULL;   /* Temp Handle to LDAP server */
+  LDAP *TempBrowseLDAPHandle = NULL;   /* Temp Handle to LDAP server */
 
-  cupsdLogMessage(CUPSD_LOG_INFO,
-                  "Try LDAP reconnect...");
 
  /*
   * Get a new LDAP Handle and replace the global Handle
-  * if the new connection was successful
+  * if the new connection was successful.
   */
 
+  cupsdLogMessage(CUPSD_LOG_INFO, "Try LDAP reconnect...");
+
   TempBrowseLDAPHandle = ldap_connect();
 
   if (TempBrowseLDAPHandle != NULL)
   {
     if (BrowseLDAPHandle != NULL)
-    {
       ldap_disconnect(BrowseLDAPHandle);
-    }
+
     BrowseLDAPHandle = TempBrowseLDAPHandle;
   }
+
+  return (BrowseLDAPHandle);
 }
 
 
@@ -1377,9 +1401,10 @@ ldap_reconnect(void)
  */
 
 static void
-ldap_disconnect(LDAP *ld)      /* I - LDAP handle */
+ldap_disconnect(LDAP *ld)              /* I - LDAP handle */
 {
-  int  rc;     /* return code */
+  int  rc;                             /* Return code */
+
 
  /*
   * Close LDAP handle...
@@ -1390,6 +1415,7 @@ ldap_disconnect(LDAP *ld) /* I - LDAP handle */
 #  else
   rc = ldap_unbind_s(ld);
 #  endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
+
   if (rc != LDAP_SUCCESS)
     cupsdLogMessage(CUPSD_LOG_ERROR,
                     "Unbind from LDAP server failed with status %d: %s",
@@ -1547,8 +1573,11 @@ cupsdStartBrowsing(void)
       * Add the master connection to the select list...
       */
 
-      cupsdAddSelect(DNSServiceRefSockFD(DNSSDRef),
-                    (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
+      int fd = DNSServiceRefSockFD(DNSSDRef);
+
+      fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+
+      cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
 
      /*
       * Then get the port we use for registrations.  If we are not listening
@@ -1664,7 +1693,8 @@ cupsdStartBrowsing(void)
   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
        p;
        p = (cupsd_printer_t *)cupsArrayNext(Printers))
-    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                     CUPS_PRINTER_SCANNER)))
       cupsdRegisterPrinter(p);
 }
 
@@ -1748,7 +1778,7 @@ cupsdStartPolling(void)
     argv[1] = pollp->hostname;
 
     if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1,
-                          0, DefaultProfile, 0, &(pollp->pid)) < 0)
+                          0, DefaultProfile, NULL, &(pollp->pid)) < 0)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "cupsdStartPolling: Unable to fork polling daemon - %s",
@@ -1792,7 +1822,8 @@ cupsdStopBrowsing(void)
   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
        p;
        p = (cupsd_printer_t *)cupsArrayNext(Printers))
-    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                     CUPS_PRINTER_SCANNER)))
       cupsdDeregisterPrinter(p, 1);
 
  /*
@@ -1894,11 +1925,13 @@ cupsdUpdateDNSSDName(void)
 {
   DNSServiceErrorType error;           /* Error from service creation */
   char         webif[1024];            /* Web interface share name */
-#ifdef HAVE_COREFOUNDATION_H
-  CFStringRef  nameRef;                /* Computer name CFString */
+#  ifdef HAVE_SYSTEMCONFIGURATION
+  SCDynamicStoreRef sc;                        /* Context for dynamic store */
+  CFDictionaryRef btmm;                        /* Back-to-My-Mac domains */
+  CFStringEncoding nameEncoding;       /* Encoding of computer name */
+  CFStringRef  nameRef;                /* Host name CFString */
   char         nameBuffer[1024];       /* C-string buffer */
-  CFStringEncoding nameEncoding;       /* Computer name encoding */
-#endif /* HAVE_COREFOUNDATION_H */
+#  endif /* HAVE_SYSTEMCONFIGURATION */
 
 
  /*
@@ -1906,6 +1939,7 @@ cupsdUpdateDNSSDName(void)
   * enabled...
   */
 
+
   if (!DNSSDPort)
     return;
 
@@ -1913,22 +1947,102 @@ cupsdUpdateDNSSDName(void)
   * Get the computer name as a c-string...
   */
 
-#ifdef HAVE_COREFOUNDATION_H
-  cupsdClearString(&DNSSDName);
+#  ifdef HAVE_SYSTEMCONFIGURATION
+  sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
 
-  if ((nameRef = SCDynamicStoreCopyComputerName(NULL,
-                                               &nameEncoding)) != NULL)
+  if (sc)
   {
-    if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
-                          kCFStringEncodingUTF8))
-      cupsdSetString(&DNSSDName, nameBuffer);
+   /*
+    * Get the computer name from the dynamic store...
+    */
 
-    CFRelease(nameRef);
-  }
+    cupsdClearString(&DNSSDComputerName);
 
-#else
-  cupsdSetString(&DNSSDName, ServerName);
-#endif /* HAVE_COREFOUNDATION_H */
+    if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL)
+    {
+      if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
+                            kCFStringEncodingUTF8))
+      {
+        cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "Dynamic store computer name is \"%s\".", nameBuffer);
+       cupsdSetString(&DNSSDComputerName, nameBuffer);
+      }
+
+      CFRelease(nameRef);
+    }
+
+    if (!DNSSDComputerName)
+    {
+     /*
+      * Use the ServerName instead...
+      */
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "Using ServerName \"%s\" as computer name.", ServerName);
+      cupsdSetString(&DNSSDComputerName, ServerName);
+    }
+
+   /*
+    * Get the local hostname from the dynamic store...
+    */
+
+    cupsdClearString(&DNSSDHostName);
+
+    if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
+    {
+      if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
+                            kCFStringEncodingUTF8))
+      {
+        cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "Dynamic store host name is \"%s\".", nameBuffer);
+       cupsdSetString(&DNSSDHostName, nameBuffer);
+      }
+
+      CFRelease(nameRef);
+    }
+
+    if (!DNSSDHostName)
+    {
+     /*
+      * Use the ServerName instead...
+      */
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "Using ServerName \"%s\" as host name.", ServerName);
+      cupsdSetString(&DNSSDHostName, ServerName);
+    }
+
+   /*
+    * Get any Back-to-My-Mac domains and add them as aliases...
+    */
+
+    cupsdFreeAliases(DNSSDAlias);
+    DNSSDAlias = NULL;
+
+    btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
+    if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
+    {
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
+                     (int)CFDictionaryGetCount(btmm));
+      CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
+    }
+    else if (btmm)
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                     "Bad Back to My Mac data in dynamic store!");
+    else
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");
+
+    if (btmm)
+      CFRelease(btmm);
+
+    CFRelease(sc);
+  }
+  else
+#  endif /* HAVE_SYSTEMCONFIGURATION */
+  {
+    cupsdSetString(&DNSSDComputerName, ServerName);
+    cupsdSetString(&DNSSDHostName, ServerName);
+  }
 
  /*
   * Then (re)register the web interface if enabled...
@@ -1936,8 +2050,8 @@ cupsdUpdateDNSSDName(void)
 
   if (BrowseWebIF)
   {
-    if (DNSSDName)
-      snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDName);
+    if (DNSSDComputerName)
+      snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
     else
       strlcpy(webif, "CUPS Web Interface", sizeof(webif));
 
@@ -2199,6 +2313,41 @@ dequote(char       *d,                   /* I - Destination string */
 
 
 #ifdef HAVE_DNSSD
+#  ifdef HAVE_COREFOUNDATION
+/*
+ * 'dnssdAddAlias()' - Add a DNS-SD alias name.
+ */
+
+static void
+dnssdAddAlias(const void *key,         /* I - Key */
+              const void *value,       /* I - Value (domain) */
+             void       *context)      /* I - Unused */
+{
+  char valueStr[1024],                 /* Domain string */
+       hostname[1024];                 /* Complete hostname */
+
+
+  (void)context;
+
+  if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() &&
+      CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr),
+                         kCFStringEncodingUTF8))
+  {
+    snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDHostName, valueStr);
+    if (!DNSSDAlias)
+      DNSSDAlias = cupsArrayNew(NULL, NULL);
+
+    cupsdAddAlias(DNSSDAlias, hostname);
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s",
+                   hostname);
+  }
+  else
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Bad Back to My Mac domain in dynamic store!");
+}
+#  endif /* HAVE_COREFOUNDATION */
+
+
 /*
  * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
  */
@@ -2209,13 +2358,14 @@ dnssdBuildTxtRecord(
     cupsd_printer_t *p,                        /* I - Printer information */
     int             for_lpd)           /* I - 1 = LPD, 0 = IPP */
 {
-  int          i, j;                   /* Looping vars */
-  char         type_str[32],           /* Type to string buffer */
+  int          i;                      /* Looping var */
+  char         admin_hostname[256],    /* .local hostname for admin page */
+               adminurl_str[256],      /* URL for the admin page */
+               type_str[32],           /* Type to string buffer */
                state_str[32],          /* State to string buffer */
                rp_str[1024],           /* Queue name string buffer */
                air_str[1024],          /* auth-info-required string buffer */
                *keyvalue[32][2];       /* Table of key/value pairs */
-  ipp_attribute_t *air_attr;           /* auth-info-required attribute */
 
 
  /*
@@ -2239,115 +2389,86 @@ dnssdBuildTxtRecord(
             (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name);
 
   keyvalue[i  ][0] = "ty";
-  keyvalue[i++][1] = p->make_model;
+  keyvalue[i++][1] = p->make_model ? p->make_model : "Unknown";
 
-  if (p->location && *p->location != '\0')
-  {
-    keyvalue[i  ][0] = "note";
-    keyvalue[i++][1] = p->location;
-  }
+  snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName);
+  httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
+                   "http", NULL, admin_hostname, DNSSDPort, "/%s/%s",
+                  (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
+                  p->name);
+  keyvalue[i  ][0] = "adminurl";
+  keyvalue[i++][1] = adminurl_str;
+
+  keyvalue[i  ][0] = "note";
+  keyvalue[i++][1] = p->location ? p->location : "";
 
   keyvalue[i  ][0] = "priority";
   keyvalue[i++][1] = for_lpd ? "100" : "0";
 
   keyvalue[i  ][0] = "product";
-  keyvalue[i++][1] = p->product ? p->product : "Unknown";
+  keyvalue[i++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown";
 
-  snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE);
-  snprintf(state_str, sizeof(state_str), "%d", p->state);
+  keyvalue[i  ][0] = "pdl";
+  keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript";
 
-  keyvalue[i  ][0] = "printer-state";
-  keyvalue[i++][1] = state_str;
+  if (get_auth_info_required(p, air_str, sizeof(air_str)))
+  {
+    keyvalue[i  ][0] = "air";
+    keyvalue[i++][1] = air_str;
+  }
 
-  keyvalue[i  ][0] = "printer-type";
-  keyvalue[i++][1] = type_str;
+  keyvalue[i  ][0] = "UUID";
+  keyvalue[i++][1] = p->uuid + 9;
+
+#ifdef HAVE_SSL
+  keyvalue[i  ][0] = "TLS";
+  keyvalue[i++][1] = "1.2";
+#endif /* HAVE_SSL */
 
   keyvalue[i  ][0] = "Transparent";
-  keyvalue[i++][1] = "T";
+  keyvalue[i++][1] = "F";
 
   keyvalue[i  ][0] = "Binary";
-  keyvalue[i++][1] = "T";
+  keyvalue[i++][1] = "F";
 
-  if ((p->type & CUPS_PRINTER_FAX))
-  {
-    keyvalue[i  ][0] = "Fax";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Fax";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_FAX) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_COLOR))
-  {
-    keyvalue[i  ][0] = "Color";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Color";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_DUPLEX))
-  {
-    keyvalue[i  ][0] = "Duplex";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Duplex";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_STAPLE))
-  {
-    keyvalue[i  ][0] = "Staple";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Staple";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_COPIES))
-  {
-    keyvalue[i  ][0] = "Copies";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Copies";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_COLLATE))
-  {
-    keyvalue[i  ][0] = "Collate";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Collate";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_PUNCH))
-  {
-    keyvalue[i  ][0] = "Punch";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Punch";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_BIND))
-  {
-    keyvalue[i  ][0] = "Bind";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Bind";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F";
 
-  if ((p->type & CUPS_PRINTER_SORT))
-  {
-    keyvalue[i  ][0] = "Sort";
-    keyvalue[i++][1] = "T";
-  }
+  keyvalue[i  ][0] = "Sort";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F";
 
-  keyvalue[i  ][0] = "pdl";
-  keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript";
+  keyvalue[i  ][0] = "Scan";
+  keyvalue[i++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F";
 
-  if ((air_attr = ippFindAttribute(p->attrs, "auth-info-required",
-                                   IPP_TAG_KEYWORD)) != NULL &&
-      strcmp(air_attr->values[0].string.text, "none"))
-  {
-    char       *air = air_str;         /* Pointer into string */
-
-
-    for (j = 0; j < air_attr->num_values; j ++)
-    {
-      if (air >= (air_str + sizeof(air_str) - 2))
-        break;
-
-      if (j)
-        *air++ = ',';
+  snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE);
+  snprintf(state_str, sizeof(state_str), "%d", p->state);
 
-      strlcpy(air, air_attr->values[j].string.text,
-              sizeof(air_str) - (air - air_str));
-      air += strlen(air);
-    }
+  keyvalue[i  ][0] = "printer-state";
+  keyvalue[i++][1] = state_str;
 
-    keyvalue[i  ][0] = "air";
-    keyvalue[i++][1] = air_str;
-  }
+  keyvalue[i  ][0] = "printer-type";
+  keyvalue[i++][1] = type_str;
 
  /*
   * Then pack them into a proper txt record...
@@ -2447,6 +2568,9 @@ dnssdPackTxtRecord(int  *txt_len, /* O - TXT record length */
   * Calculate the buffer size
   */
 
+  if (count <= 0)
+    return (NULL);
+
   for (length = i = 0; i < count; i++)
     length += 1 + strlen(keyvalue[i][0]) + 
              (keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0);
@@ -2544,13 +2668,9 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
                        name[1024],     /* Service name */
                        *nameptr;       /* Pointer into name */
   int                  ipp_len,        /* IPP TXT record length */
-                       printer_len;    /* LPD TXT record length */
-  char                 resource[1024]; /* Resource path for printer */
+                       printer_len,    /* LPD TXT record length */
+                       printer_port;   /* LPD port number */
   const char           *regtype;       /* Registration type */
-  const char           *domain;        /* Registration domain */
-  cupsd_location_t     *location,      /* Printer location */
-                       *policy;        /* Operation policy for Print-Job */
-  unsigned             address[4];     /* INADDR_ANY address */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
@@ -2573,13 +2693,13 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
 
   if (p->info && strlen(p->info) > 0)
   {
-    if (DNSSDName)
-      snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDName);
+    if (DNSSDComputerName)
+      snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
     else
       strlcpy(name, p->info, sizeof(name));
   }
-  else if (DNSSDName)
-    snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDName);
+  else if (DNSSDComputerName)
+    snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
   else
     strlcpy(name, p->name, sizeof(name));
 
@@ -2596,26 +2716,6 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
     cupsArrayAdd(DNSSDPrinters, p);
   }
 
- /*
-  * If 'Allow printing from the Internet' is enabled (i.e. from any address)
-  * let dnssd decide on the domain, otherwise restrict it to ".local".
-  */
-
-  if (p->type & CUPS_PRINTER_CLASS)
-    snprintf(resource, sizeof(resource), "/classes/%s", p->name);
-  else
-    snprintf(resource, sizeof(resource), "/printers/%s", p->name);
-
-  address[0] = address[1] = address[2] = address[3] = 0;
-  location   = cupsdFindBest(resource, HTTP_POST);
-  policy     = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
-
-  if ((location && !cupsdCheckAccess(address, "", 0, location)) ||
-      (policy && !cupsdCheckAccess(address, "", 0, policy)))
-    domain = "local.";
-  else
-    domain = NULL;
-
  /*
   * Register IPP and (optionally) LPD...
   */
@@ -2659,16 +2759,14 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
   if (!p->ipp_ref)
   {
    /*
-    * Initial registration.  Use the _fax subtype for fax queues...
+    * Initial registration.  Use the _fax-ipp regtype for fax queues...
     */
 
-    regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" :
-                                             "_ipp._tcp,_cups";
+    regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" : DNSSDRegType;
 
     cupsdLogMessage(CUPSD_LOG_DEBUG, 
-                   "Registering DNS-SD printer %s with name \"%s\", "
-                   "type \"%s\", and domain \"%s\"", p->name, name, regtype,
-                   domain ? domain : "(null)");
+                   "Registering DNS-SD printer %s with name \"%s\" and "
+                   "type \"%s\"", p->name, name, regtype);
 
    /*
     * Register the queue, dropping characters as needed until we succeed...
@@ -2680,7 +2778,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
     {
       p->ipp_ref = DNSSDRef;
       if ((se = DNSServiceRegister(&p->ipp_ref, kDNSServiceFlagsShareConnection,
-                                   0, name, regtype, domain, NULL,
+                                   0, name, regtype, NULL, NULL,
                                   htons(DNSSDPort), ipp_len, ipp_txt,
                                   dnssdRegisterCallback,
                                   p)) == kDNSServiceErr_BadParam)
@@ -2718,76 +2816,82 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
 
   if (BrowseLocalProtocols & BROWSE_LPD)
   {
-    printer_len = 0;                   /* anti-compiler-warning-code */
-    printer_txt = dnssdBuildTxtRecord(&printer_len, p, 1);
-
-    if (p->printer_ref &&
-       (printer_len != p->printer_len ||
-        memcmp(printer_txt, p->printer_txt, printer_len)))
-    {
-     /*
-      * Update the existing registration...
-      */
-
-      /* A TTL of 0 means use record's original value (Radar 3176248) */
-      if ((se = DNSServiceUpdateRecord(p->printer_ref, NULL, 0, printer_len,
-                                      printer_txt,
-                                      0)) == kDNSServiceErr_NoError)
-      {
-       if (p->printer_txt)
-         free(p->printer_txt);
+    printer_len  = 0;                  /* anti-compiler-warning-code */
+    printer_port = 515;
+    printer_txt  = dnssdBuildTxtRecord(&printer_len, p, 1);
+  }
+  else
+  {
+    printer_len  = 0;
+    printer_port = 0;
+    printer_txt  = NULL;
+  }
 
-       p->printer_txt = printer_txt;
-       p->printer_len = printer_len;
-       printer_txt    = NULL;
-      }
-      else
-      {
-       /*
-       * Failed to update record, lets close this reference and move on...
-       */
+  if (p->printer_ref &&
+      (printer_len != p->printer_len ||
+       memcmp(printer_txt, p->printer_txt, printer_len)))
+  {
+   /*
+    * Update the existing registration...
+    */
 
-       cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unable to update LPD DNS-SD record for %s - %d",
-                       p->name, se);
+    /* A TTL of 0 means use record's original value (Radar 3176248) */
+    if ((se = DNSServiceUpdateRecord(p->printer_ref, NULL, 0, printer_len,
+                                    printer_txt,
+                                    0)) == kDNSServiceErr_NoError)
+    {
+      if (p->printer_txt)
+       free(p->printer_txt);
 
-       DNSServiceRefDeallocate(p->printer_ref);
-       p->printer_ref = NULL;
-      }
+      p->printer_txt = printer_txt;
+      p->printer_len = printer_len;
+      printer_txt    = NULL;
     }
-    
-    if (!p->printer_ref)
+    else
     {
      /*
-      * Initial registration...
+      * Failed to update record, lets close this reference and move on...
       */
 
-      cupsdLogMessage(CUPSD_LOG_DEBUG, 
-                     "Registering DNS-SD printer %s with name \"%s\", "
-                     "type \"_printer._tcp\", and domain \"%s\"", p->name,
-                     name, domain ? domain : "(null)");
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                     "Unable to update LPD DNS-SD record for %s - %d",
+                     p->name, se);
 
-      p->printer_ref = DNSSDRef;
-      if ((se = DNSServiceRegister(&p->printer_ref,
-                                   kDNSServiceFlagsShareConnection,
-                                  0, name, "_printer._tcp", domain, NULL,
-                                  htons(515), printer_len, printer_txt,
-                                  dnssdRegisterCallback,
-                                  p)) == kDNSServiceErr_NoError)
-      {
-       p->printer_txt = printer_txt;
-       p->printer_len = printer_len;
-       printer_txt    = NULL;
-      }
-      else
-       cupsdLogMessage(CUPSD_LOG_WARN,
-                       "DNS-SD LPD registration of \"%s\" failed: %d",
-                       p->name, se);
+      DNSServiceRefDeallocate(p->printer_ref);
+      p->printer_ref = NULL;
     }
+  }
+  
+  if (!p->printer_ref)
+  {
+   /*
+    * Initial registration...
+    */
 
-    if (printer_txt)
-      free(printer_txt);
+    cupsdLogMessage(CUPSD_LOG_DEBUG, 
+                   "Registering DNS-SD printer %s with name \"%s\" and "
+                   "type \"_printer._tcp\"", p->name, name);
+
+    p->printer_ref = DNSSDRef;
+    if ((se = DNSServiceRegister(&p->printer_ref,
+                                kDNSServiceFlagsShareConnection,
+                                0, name, "_printer._tcp", NULL, NULL,
+                                htons(printer_port), printer_len, printer_txt,
+                                dnssdRegisterCallback,
+                                p)) == kDNSServiceErr_NoError)
+    {
+      p->printer_txt = printer_txt;
+      p->printer_len = printer_len;
+      printer_txt    = NULL;
+    }
+    else
+      cupsdLogMessage(CUPSD_LOG_WARN,
+                     "DNS-SD LPD registration of \"%s\" failed: %d",
+                     p->name, se);
   }
+
+  if (printer_txt)
+    free(printer_txt);
 }
 
 
@@ -2859,6 +2963,85 @@ dnssdUpdate(void)
 #endif /* HAVE_DNSSD */
 
 
+/*
+ * 'get_auth_info_required()' - Get the auth-info-required value to advertise.
+ */
+
+static char *                          /* O - String or NULL if none */
+get_auth_info_required(
+    cupsd_printer_t *p,                        /* I - Printer */
+    char            *buffer,           /* I - Value buffer */
+    size_t          bufsize)           /* I - Size of value buffer */
+{
+  cupsd_location_t *auth;              /* Pointer to authentication element */
+  char         resource[1024];         /* Printer/class resource path */
+
+
+ /*
+  * If auth-info-required is set for this printer, return that...
+  */
+
+  if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
+  {
+    int                i;                      /* Looping var */
+    char       *bufptr;                /* Pointer into buffer */
+
+    for (i = 0, bufptr = buffer; i < p->num_auth_info_required; i ++)
+    {
+      if (bufptr >= (buffer + bufsize - 2))
+       break;
+
+      if (i)
+       *bufptr++ = ',';
+
+      strlcpy(bufptr, p->auth_info_required[i], bufsize - (bufptr - buffer));
+      bufptr += strlen(bufptr);
+    }
+
+    return (buffer);
+  }
+
+ /*
+  * Figure out the authentication data requirements to advertise...
+  */
+
+  if (p->type & CUPS_PRINTER_CLASS)
+    snprintf(resource, sizeof(resource), "/classes/%s", p->name);
+  else
+    snprintf(resource, sizeof(resource), "/printers/%s", p->name);
+
+  if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
+      auth->type == CUPSD_AUTH_NONE)
+    auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
+
+  if (auth)
+  {
+    int        auth_type;                      /* Authentication type */
+
+    if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
+      auth_type = DefaultAuthType;
+
+    switch (auth_type)
+    {
+      case CUPSD_AUTH_NONE :
+          return (NULL);
+
+      case CUPSD_AUTH_NEGOTIATE :
+         strlcpy(buffer, "negotiate", bufsize);
+         break;
+
+      default :
+         strlcpy(buffer, "username,password", bufsize);
+         break;
+    }
+
+    return (buffer);
+  }
+
+  return ("none");
+}
+
+
 #ifdef __APPLE__
 /*
  * 'get_hostconfig()' - Get an /etc/hostconfig service setting.
@@ -2991,7 +3174,8 @@ process_browse_data(
                                        /* Local make and model */
   cupsd_printer_t *p;                  /* Printer information */
   const char   *ipp_options,           /* ipp-options value */
-               *lease_duration;        /* lease-duration value */
+               *lease_duration,        /* lease-duration value */
+               *uuid;                  /* uuid value */
   int          is_class;               /* Is this queue a class? */
 
 
@@ -3080,6 +3264,7 @@ process_browse_data(
   hptr     = strchr(host, '.');
   sptr     = strchr(ServerName, '.');
   is_class = type & CUPS_PRINTER_CLASS;
+  uuid     = cupsGetOption("uuid", num_attrs, attrs);
 
   if (!ServerNameIsIP && sptr != NULL && hptr != NULL)
   {
@@ -3292,6 +3477,12 @@ process_browse_data(
     update  = 1;
   }
 
+  if (uuid && strcmp(p->uuid, uuid))
+  {
+    cupsdSetString(&p->uuid, uuid);
+    update = 1;
+  }
+
   if (location && (!p->location || strcmp(p->location, location)))
   {
     cupsdSetString(&p->location, location);
@@ -3619,8 +3810,9 @@ send_cups_browse(cupsd_printer_t *p)      /* I - Printer to send */
                        uri[1024],      /* Printer URI */
                        location[1024], /* printer-location */
                        info[1024],     /* printer-info */
-                       make_model[1024];
+                       make_model[1024],
                                        /* printer-make-and-model */
+                       air[1024];      /* auth-info-required */
   cupsd_netif_t                *iface;         /* Network interface */
 
 
@@ -3658,6 +3850,11 @@ send_cups_browse(cupsd_printer_t *p)     /* I - Printer to send */
   else
     strlcpy(make_model, "Local System V Printer", sizeof(make_model));
 
+  if (get_auth_info_required(p, packet, sizeof(packet)))
+    snprintf(air, sizeof(air), " auth-info-required=%s", packet);
+  else
+    air[0] = '\0';
+
  /*
   * Send a packet to each browse address...
   */
@@ -3694,9 +3891,10 @@ send_cups_browse(cupsd_printer_t *p)     /* I - Printer to send */
                           (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
                                                            "/printers/%s",
                           p->name);
-         snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+         snprintf(packet, sizeof(packet),
+                  "%x %x %s \"%s\" \"%s\" \"%s\" %s%s uuid=%s\n",
                   type, p->state, uri, location, info, make_model,
-                  p->browse_attrs ? p->browse_attrs : "");
+                  p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
 
          bytes = strlen(packet);
 
@@ -3735,9 +3933,10 @@ send_cups_browse(cupsd_printer_t *p)     /* I - Printer to send */
                           (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
                                                            "/printers/%s",
                           p->name);
-         snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+         snprintf(packet, sizeof(packet),
+                  "%x %x %s \"%s\" \"%s\" \"%s\" %s%s uuid=%s\n",
                   type, p->state, uri, location, info, make_model,
-                  p->browse_attrs ? p->browse_attrs : "");
+                  p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
 
          bytes = strlen(packet);
 
@@ -3760,9 +3959,10 @@ send_cups_browse(cupsd_printer_t *p)     /* I - Printer to send */
       * the default server name...
       */
 
-      snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+      snprintf(packet, sizeof(packet),
+               "%x %x %s \"%s\" \"%s\" \"%s\" %s%s uuid=%s\n",
                       type, p->state, p->uri, location, info, make_model,
-              p->browse_attrs ? p->browse_attrs : "");
+              p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
 
       bytes = strlen(packet);
       cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -3797,7 +3997,7 @@ send_cups_browse(cupsd_printer_t *p)      /* I - Printer to send */
  * 'ldap_search_rec()' - LDAP Search with reconnect
  */
 
-static int
+static int                             /* O - Return code */
 ldap_search_rec(LDAP        *ld,       /* I - LDAP handler */
                 char        *base,     /* I - Base dn */
                 int         scope,     /* I - LDAP search scope */
@@ -3807,6 +4007,7 @@ ldap_search_rec(LDAP        *ld,  /* I - LDAP handler */
                 LDAPMessage **res)     /* I - LDAP handler */
 {
   int  rc;                             /* Return code */
+  LDAP  *ldr;                          /* LDAP handler after reconnect */
 
 
 #  if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
@@ -3829,13 +4030,13 @@ ldap_search_rec(LDAP        *ld,        /* I - LDAP handler */
                     "We try the LDAP search once again after reconnecting to "
                    "the server");
     ldap_freeres(*res);
-    ldap_reconnect();
+    ldr = ldap_reconnect();
 
 #  if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-    rc = ldap_search_ext_s(ld, base, scope, filter, attrs, attrsonly, NULL,
+    rc = ldap_search_ext_s(ldr, base, scope, filter, attrs, attrsonly, NULL,
                            NULL, NULL, LDAP_NO_LIMIT, res);
 #  else
-    rc = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res);
+    rc = ldap_search_s(ldr, base, scope, filter, attrs, attrsonly, res);
 #  endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
   }
 
@@ -3866,11 +4067,9 @@ ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */
 
   rc = ldap_msgfree(entry);
   if (rc == -1)
-    cupsdLogMessage(CUPSD_LOG_WARN,
-                    "Can't free LDAPMessage!");
+    cupsdLogMessage(CUPSD_LOG_WARN, "Can't free LDAPMessage!");
   else if (rc == 0)
-    cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                    "Freeing LDAPMessage was unnecessary");
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "Freeing LDAPMessage was unnecessary");
 }
 
 
@@ -3878,7 +4077,7 @@ ldap_freeres(LDAPMessage *entry)  /* I - LDAP handler */
  * 'ldap_getval_char()' - Get first LDAP value and convert to string
  */
 
-static int
+static int                             /* O - Return code */
 ldap_getval_firststring(
     LDAP          *ld,                 /* I - LDAP handler */
     LDAPMessage   *entry,              /* I - LDAP message or search result */
@@ -3908,13 +4107,12 @@ ldap_getval_firststring(
   }
   else
   {
-
    /*
     * Check size and copy value into our string...
     */
 
     size = maxsize;
-    if (size < bval[0]->bv_len)
+    if (size < (bval[0]->bv_len + 1))
     {
       rc = -1;
       dn = ldap_get_dn(ld, entry);
@@ -3924,13 +4122,13 @@ ldap_getval_firststring(
       ldap_memfree(dn);
     }
     else
-      size = bval[0]->bv_len;
+      size = bval[0]->bv_len + 1;
 
     strlcpy(retval, bval[0]->bv_val, size);
     ldap_value_free_len(bval);
   }
 #  else
-  char                 **value;        /* LDAP value */
+  char **value;                        /* LDAP value */
 
  /*
   * Get value from LDAPMessage...
@@ -3940,8 +4138,7 @@ ldap_getval_firststring(
   {
     rc = -1;
     dn = ldap_get_dn(ld, entry);
-    cupsdLogMessage(CUPSD_LOG_WARN,
-                    "Failed to get LDAP value %s for %s!",
+    cupsdLogMessage(CUPSD_LOG_WARN, "Failed to get LDAP value %s for %s!",
                     attr, dn);
     ldap_memfree(dn);
   }
@@ -3971,6 +4168,7 @@ send_ldap_ou(char *ou,                    /* I - Servername/ou to register */
   LDAPMessage   *res,                   /* Search result token */
                *e;                     /* Current entry from search */
   int           rc;                     /* LDAP status */
+  int           rcmod;                  /* LDAP status for modifications */
   char          dn[1024],               /* DN of the organizational unit we are adding */
                 *desc[2],               /* Change records */
                 *ou_value[2];
@@ -3994,11 +4192,10 @@ send_ldap_ou(char *ou,                  /* I - Servername/ou to register */
   * Reconnect if LDAP Handle is invalid...
   */
 
-  if (! BrowseLDAPHandle)
+  if (!BrowseLDAPHandle)
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                    "send_ldap_ou: LDAP Handle is invalid. Try "
-                   "reconnecting...");
+                    "send_ldap_ou: LDAP Handle is invalid. Try reconnecting...");
     ldap_reconnect();
     return;
   }
@@ -4082,16 +4279,16 @@ send_ldap_ou(char *ou,                  /* I - Servername/ou to register */
       pmods[i] = NULL;
 
 #  if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-      if ((rc = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
-                                  NULL)) != LDAP_SUCCESS)
+      if ((rcmod = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
+                                     NULL)) != LDAP_SUCCESS)
 #  else
-      if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
+      if ((rcmod = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
 #  endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
       {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                         "LDAP modify for %s failed with status %d: %s",
-                        ou, rc, ldap_err2string(rc));
-        if ( LDAP_SERVER_DOWN == rc )
+                        ou, rcmod, ldap_err2string(rcmod));
+        if (rcmod == LDAP_SERVER_DOWN)
           ldap_reconnect();
       }
     }
@@ -4114,21 +4311,22 @@ send_ldap_ou(char *ou,                  /* I - Servername/ou to register */
     pmods[i] = NULL;
 
 #  if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-    if ((rc = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
-                             NULL)) != LDAP_SUCCESS)
+    if ((rcmod = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
+                                NULL)) != LDAP_SUCCESS)
 #  else
-    if ((rc = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
+    if ((rcmod = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
 #  endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "LDAP add for %s failed with status %d: %s",
-                      ou, rc, ldap_err2string(rc));
-      if ( LDAP_SERVER_DOWN == rc )
+                      ou, rcmod, ldap_err2string(rcmod));
+      if (rcmod == LDAP_SERVER_DOWN)
         ldap_reconnect();
     }
   }
 
-  ldap_freeres(res);
+  if (rc == LDAP_SUCCESS)
+    ldap_freeres(res);
 }
 
 
@@ -4153,6 +4351,7 @@ send_ldap_browse(cupsd_printer_t *p)      /* I - Printer to register */
                typestring[255],        /* String to hold printer-type */
                dn[1024];               /* DN of the printer we are adding */
   int          rc;                     /* LDAP status */
+  int          rcmod;                  /* LDAP status for modifications */
   char         old_uri[HTTP_MAX_URI],  /* Printer URI */
                old_location[1024],     /* Printer location */
                old_info[1024],         /* Printer information */
@@ -4336,16 +4535,16 @@ send_ldap_browse(cupsd_printer_t *p)    /* I - Printer to register */
       pmods[i] = NULL;
 
 #  if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-      if ((rc = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
-                                  NULL)) != LDAP_SUCCESS)
+      if ((rcmod = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
+                                     NULL)) != LDAP_SUCCESS)
 #  else
-      if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
+      if ((rcmod = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
 #  endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
       {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                         "LDAP modify for %s failed with status %d: %s",
-                        p->name, rc, ldap_err2string(rc));
-        if (rc == LDAP_SERVER_DOWN)
+                        p->name, rcmod, ldap_err2string(rcmod));
+        if (rcmod == LDAP_SERVER_DOWN)
           ldap_reconnect();
       }
     }
@@ -4370,21 +4569,22 @@ send_ldap_browse(cupsd_printer_t *p)    /* I - Printer to register */
     pmods[i] = NULL;
 
 #  if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-    if ((rc = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
-                             NULL)) != LDAP_SUCCESS)
+    if ((rcmod = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
+                                NULL)) != LDAP_SUCCESS)
 #  else
-    if ((rc = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
+    if ((rcmod = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
 #  endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "LDAP add for %s failed with status %d: %s",
-                      p->name, rc, ldap_err2string(rc));
-      if (rc == LDAP_SERVER_DOWN)
+                      p->name, rcmod, ldap_err2string(rcmod));
+      if (rcmod == LDAP_SERVER_DOWN)
         ldap_reconnect();
     }
   }
 
-  ldap_freeres(res);
+  if (rc == LDAP_SUCCESS)
+    ldap_freeres(res);
 }
 
 
@@ -4456,6 +4656,10 @@ ldap_dereg_printer(cupsd_printer_t *p)   /* I - Printer to deregister */
 }
 
 
+/*
+ * 'ldap_dereg_ou()' - Remove the organizational unit.
+ */
+
 static void
 ldap_dereg_ou(char *ou,                        /* I - Organizational unit (servername) */
               char *basedn)            /* I - Dase dn */
@@ -4514,7 +4718,6 @@ ldap_dereg_ou(char *ou,                   /* I - Organizational unit (servername) */
                         "LDAP delete for %s failed with status %d: %s",
                         ou, rc, ldap_err2string(rc));
     }
-
   }
 }
 #endif /* HAVE_LDAP */
@@ -5033,24 +5236,20 @@ update_cups_browse(void)
        case CUPSD_AUTH_ALLOW : /* Order Deny,Allow */
             auth = CUPSD_AUTH_ALLOW;
 
-            if (cupsdCheckAuth(address, srcname, len,
-                         BrowseACL->num_deny, BrowseACL->deny))
+            if (cupsdCheckAuth(address, srcname, len, BrowseACL->deny))
              auth = CUPSD_AUTH_DENY;
 
-            if (cupsdCheckAuth(address, srcname, len,
-                         BrowseACL->num_allow, BrowseACL->allow))
+            if (cupsdCheckAuth(address, srcname, len, BrowseACL->allow))
              auth = CUPSD_AUTH_ALLOW;
            break;
 
        case CUPSD_AUTH_DENY : /* Order Allow,Deny */
             auth = CUPSD_AUTH_DENY;
 
-            if (cupsdCheckAuth(address, srcname, len,
-                         BrowseACL->num_allow, BrowseACL->allow))
+            if (cupsdCheckAuth(address, srcname, len, BrowseACL->allow))
              auth = CUPSD_AUTH_ALLOW;
 
-            if (cupsdCheckAuth(address, srcname, len,
-                         BrowseACL->num_deny, BrowseACL->deny))
+            if (cupsdCheckAuth(address, srcname, len, BrowseACL->deny))
              auth = CUPSD_AUTH_DENY;
            break;
       }
@@ -5162,7 +5361,7 @@ update_cups_browse(void)
   */
 
   for (i = 0; i < NumRelays; i ++)
-    if (cupsdCheckAuth(address, srcname, len, 1, &(Relays[i].from)))
+    if (cupsdCheckAuth(address, srcname, len, Relays[i].from))
       if (sendto(BrowseSocket, packet, bytes, 0,
                  (struct sockaddr *)&(Relays[i].to),
                 httpAddrLength(&(Relays[i].to))) <= 0)
@@ -5273,7 +5472,7 @@ update_lpd(int onoff)                     /* - 1 = turn on, 0 = turn off */
     argv[4] = NULL;
 
     cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1,
-                      NULL, 0, &pid);
+                      NULL, NULL, &pid);
   }
 #endif /* __APPLE__ */
   else