]> 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 f8d882e3a54f08de3c1d54715b29d5c751e96cf3..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
@@ -120,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[],
@@ -461,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)
@@ -634,7 +642,7 @@ cupsdLoadRemoteCache(void)
       if (value)
       {
         p->deny_users = 0;
-        cupsdAddPrinterUser(p, value);
+        cupsdAddString(&(p->users), value);
       }
       else
        cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -645,7 +653,7 @@ cupsdLoadRemoteCache(void)
       if (value)
       {
         p->deny_users = 1;
-        cupsdAddPrinterUser(p, value);
+        cupsdAddString(&(p->users), value);
       }
       else
        cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -728,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 */
@@ -799,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);
 
@@ -829,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;
@@ -1357,7 +1369,7 @@ 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 */
@@ -1365,7 +1377,7 @@ ldap_reconnect(void)
 
  /*
   * 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...");
@@ -1379,6 +1391,8 @@ ldap_reconnect(void)
 
     BrowseLDAPHandle = TempBrowseLDAPHandle;
   }
+
+  return (BrowseLDAPHandle);
 }
 
 
@@ -1911,13 +1925,13 @@ cupsdUpdateDNSSDName(void)
 {
   DNSServiceErrorType error;           /* Error from service creation */
   char         webif[1024];            /* Web interface share name */
-#ifdef HAVE_COREFOUNDATION_H
+#  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 */
-#endif /* HAVE_COREFOUNDATION_H */
+#  endif /* HAVE_SYSTEMCONFIGURATION */
 
 
  /*
@@ -1933,7 +1947,7 @@ cupsdUpdateDNSSDName(void)
   * Get the computer name as a c-string...
   */
 
-#ifdef HAVE_COREFOUNDATION_H
+#  ifdef HAVE_SYSTEMCONFIGURATION
   sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
 
   if (sc)
@@ -2024,7 +2038,7 @@ cupsdUpdateDNSSDName(void)
     CFRelease(sc);
   }
   else
-#endif /* HAVE_COREFOUNDATION_H */
+#  endif /* HAVE_SYSTEMCONFIGURATION */
   {
     cupsdSetString(&DNSSDComputerName, ServerName);
     cupsdSetString(&DNSSDHostName, ServerName);
@@ -2345,7 +2359,9 @@ dnssdBuildTxtRecord(
     int             for_lpd)           /* I - 1 = LPD, 0 = IPP */
 {
   int          i;                      /* Looping var */
-  char         type_str[32],           /* Type to string buffer */
+  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 */
@@ -2375,95 +2391,84 @@ dnssdBuildTxtRecord(
   keyvalue[i  ][0] = "ty";
   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 (get_auth_info_required(p, air_str, sizeof(air_str)))
-  {
-    keyvalue[i  ][0] = "air";
-    keyvalue[i++][1] = air_str;
-  }
+  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] = "printer-state";
+  keyvalue[i++][1] = state_str;
+
+  keyvalue[i  ][0] = "printer-type";
+  keyvalue[i++][1] = type_str;
 
  /*
   * Then pack them into a proper txt record...
@@ -2563,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);
@@ -2660,7 +2668,8 @@ 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 */
+                       printer_len,    /* LPD TXT record length */
+                       printer_port;   /* LPD port number */
   const char           *regtype;       /* Registration type */
 
 
@@ -2750,11 +2759,10 @@ 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\" and "
@@ -2808,75 +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\" and "
-                     "type \"_printer._tcp\"", p->name, name);
+      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", NULL, 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);
 }
 
 
@@ -3023,7 +3038,7 @@ get_auth_info_required(
     return (buffer);
   }
 
-  return (NULL);
+  return ("none");
 }
 
 
@@ -3159,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? */
 
 
@@ -3248,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)
   {
@@ -3460,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);
@@ -3868,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%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 : "", air);
+                  p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
 
          bytes = strlen(packet);
 
@@ -3910,9 +3934,9 @@ send_cups_browse(cupsd_printer_t *p)      /* I - Printer to send */
                                                            "/printers/%s",
                           p->name);
          snprintf(packet, sizeof(packet),
-                  "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n",
+                  "%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 : "", air);
+                  p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
 
          bytes = strlen(packet);
 
@@ -3935,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%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 : "", air);
+              p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
 
       bytes = strlen(packet);
       cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -3982,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
@@ -4004,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 */
   }
 
@@ -4086,7 +4112,7 @@ ldap_getval_firststring(
     */
 
     size = maxsize;
-    if (size < bval[0]->bv_len)
+    if (size < (bval[0]->bv_len + 1))
     {
       rc = -1;
       dn = ldap_get_dn(ld, entry);
@@ -4096,7 +4122,7 @@ 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);
@@ -4142,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];
@@ -4252,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();
       }
     }
@@ -4284,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);
 }
 
 
@@ -4323,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 */
@@ -4506,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();
       }
     }
@@ -4540,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);
 }
 
 
@@ -5206,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;
       }
@@ -5335,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)