/*
* "$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
* 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
* 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.
* 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__ */
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[],
#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);
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;
/*
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)
if (value)
{
p->deny_users = 0;
- cupsdAddPrinterUser(p, value);
+ cupsdAddString(&(p->users), value);
}
else
cupsdLogMessage(CUPSD_LOG_ERROR,
if (value)
{
p->deny_users = 1;
- cupsdAddPrinterUser(p, value);
+ cupsdAddString(&(p->users), value);
}
else
cupsdLogMessage(CUPSD_LOG_ERROR,
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
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 */
cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire);
+ cupsFilePrintf(fp, "UUID %s\n", printer->uuid);
+
if (printer->info)
cupsFilePutConf(fp, "Info", printer->info);
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;
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 ++;
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)
* '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);
* '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...
*/
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,
"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...
* 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);
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;
}
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;
*/
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 */
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);
}
* '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);
}
*/
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...
# 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",
* 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
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);
}
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",
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);
/*
{
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 */
/*
* enabled...
*/
+
if (!DNSSDPort)
return;
* 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...
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));
#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.
*/
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 */
/*
(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...
* 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);
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,
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));
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...
*/
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...
{
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)
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);
}
#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.
/* 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? */
hptr = strchr(host, '.');
sptr = strchr(ServerName, '.');
is_class = type & CUPS_PRINTER_CLASS;
+ uuid = cupsGetOption("uuid", num_attrs, attrs);
if (!ServerNameIsIP && sptr != NULL && hptr != NULL)
{
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);
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 */
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...
*/
(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);
(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);
* 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,
* '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 */
LDAPMessage **res) /* I - LDAP handler */
{
int rc; /* Return code */
+ LDAP *ldr; /* LDAP handler after reconnect */
# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
"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 */
}
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");
}
* '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 */
}
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);
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...
{
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);
}
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];
* 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;
}
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();
}
}
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);
}
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 */
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();
}
}
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);
}
}
+/*
+ * 'ldap_dereg_ou()' - Remove the organizational unit.
+ */
+
static void
ldap_dereg_ou(char *ou, /* I - Organizational unit (servername) */
char *basedn) /* I - Dase dn */
"LDAP delete for %s failed with status %d: %s",
ou, rc, ldap_err2string(rc));
}
-
}
}
#endif /* HAVE_LDAP */
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;
}
*/
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)
argv[4] = NULL;
cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1,
- NULL, 0, &pid);
+ NULL, NULL, &pid);
}
#endif /* __APPLE__ */
else