auth/credentials: don't ignore "client use kerberos" and --use-kerberos for machine...
[samba.git] / source3 / printing / print_iprint.c
index 6193dbe2ca94cbc50f69428c6580789ec24bdece..2b2215eb8c3fc9ce5d01de880903dce7eb3420e8 100644 (file)
@@ -7,21 +7,22 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "includes.h"
 #include "printing.h"
+#include "printing/pcap.h"
+#include "lib/util/string_wrappers.h"
 
 #ifdef HAVE_IPRINT
 #include <cups/cups.h>
 #define NOVELL_SERVER_VERSION_STRING           "iprintserverversion="
 #define NOVELL_SERVER_VERSION_OES_SP1          33554432
 
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
+#define HAVE_CUPS_1_6 1
+#endif
+
+#ifndef HAVE_CUPS_1_6
+#define ippGetCount(attr)     attr->num_values
+#define ippGetGroupTag(attr)  attr->group_tag
+#define ippGetName(attr)      attr->name
+#define ippGetValueTag(attr)  attr->value_tag
+#define ippGetStatusCode(ipp) ipp->request.status.status_code
+#define ippGetBoolean(attr, element) attr->values[element].boolean
+#define ippGetInteger(attr, element) attr->values[element].integer
+#define ippGetString(attr, element, language) attr->values[element].string.text
+
+static ipp_attribute_t *
+ippFirstAttribute(ipp_t *ipp)
+{
+  if (!ipp)
+    return (NULL);
+  return (ipp->current = ipp->attrs);
+}
+
+static ipp_attribute_t *
+ippNextAttribute(ipp_t *ipp)
+{
+  if (!ipp || !ipp->current)
+    return (NULL);
+  return (ipp->current = ipp->current->next);
+}
+
+static int ippSetOperation(ipp_t *ipp, ipp_op_t op)
+{
+    ipp->request.op.operation_id = op;
+    return (1);
+}
+
+static int ippSetRequestId(ipp_t *ipp, int request_id)
+{
+    ipp->request.any.request_id = request_id;
+    return (1);
+}
+#endif
+
 /*
  * 'iprint_passwd_cb()' - The iPrint password callback...
  */
@@ -50,10 +94,14 @@ iprint_passwd_cb(const char *prompt)        /* I - Prompt */
 
 static const char *iprint_server(void)
 {
-       if ((lp_iprint_server() != NULL) && (strlen(lp_iprint_server()) > 0)) {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
+       const char *server = lp_iprint_server(talloc_tos(), lp_sub);
+
+       if ((server != NULL) && (strlen(server) > 0)) {
                DEBUG(10, ("iprint server explicitly set to %s\n",
-                          lp_iprint_server()));
-               return lp_iprint_server();
+                          server));
+               return server;
        }
 
        DEBUG(10, ("iprint server left to default %s\n", cupsServer()));
@@ -92,8 +140,8 @@ static int iprint_get_server_version(http_t *http, char* serviceUri)
 
        request = ippNew();
 
-       request->request.op.operation_id = OPERATION_NOVELL_MGMT;
-       request->request.op.request_id   = 1;
+       ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_MGMT);
+       ippSetRequestId(request, 1);
 
        language = cupsLangDefault();
 
@@ -114,12 +162,12 @@ static int iprint_get_server_version(http_t *http, char* serviceUri)
        */
 
        if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) ||
-           (response->request.status.status_code >= IPP_OK_CONFLICT))
+           (ippGetStatusCode(response) >= IPP_OK_CONFLICT))
                goto out;
 
        if (((attr = ippFindAttribute(response, "server-version",
                                      IPP_TAG_STRING)) != NULL)) {
-               if ((ver = strstr(attr->values[0].string.text,
+               if ((ver = strstr(ippGetString(attr, 0, NULL),
                                   NOVELL_SERVER_VERSION_STRING)) != NULL) {
                        ver += strlen(NOVELL_SERVER_VERSION_STRING);
                       /*
@@ -135,7 +183,7 @@ static int iprint_get_server_version(http_t *http, char* serviceUri)
                                serverVersion = 0;
                }
 
-               if ((os = strstr(attr->values[0].string.text,
+               if ((os = strstr(ippGetString(attr, 0, NULL),
                                   NOVELL_SERVER_SYSNAME)) != NULL) {
                        os += strlen(NOVELL_SERVER_SYSNAME);
                        if ((temp = strchr(os,'<')) != NULL)
@@ -161,18 +209,19 @@ static int iprint_get_server_version(http_t *http, char* serviceUri)
 
 static int iprint_cache_add_printer(http_t *http,
                                   int reqId,
-                                  char* url)
+                                  const char *url,
+                                  struct pcap_cache **pcache)
 {
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        ipp_attribute_t *attr;                  /* Current attribute */
        cups_lang_t     *language = NULL;       /* Default language */
-       char            *name,                  /* printer-name attribute */
-                       *info,                  /* printer-info attribute */
-                       smb_enabled,            /* smb-enabled attribute */
+       const char      *name,                  /* printer-name attribute */
+                       *info;                  /* printer-info attribute */
+       char            smb_enabled,            /* smb-enabled attribute */
                        secure;                 /* security-enabled attrib. */
 
-       char            *httpPath;      /* path portion of the printer-uri */
+       const char      *httpPath;      /* path portion of the printer-uri */
 
        static const char *pattrs[] =   /* Requested printer attributes */
                        {
@@ -180,12 +229,12 @@ static int iprint_cache_add_printer(http_t *http,
                          "security-enabled",
                          "printer-info",
                          "smb-enabled"
-                       };       
+                       };
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
-       request->request.op.request_id   = reqId;
+       ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
+       ippSetRequestId(request, reqId);
 
        language = cupsLangDefault();
 
@@ -220,7 +269,7 @@ static int iprint_cache_add_printer(http_t *http,
               /*
                * Ignore printers that cannot be queried without credentials
                */
-               if (lastErr == IPP_FORBIDDEN || 
+               if (lastErr == IPP_FORBIDDEN ||
                    lastErr == IPP_NOT_AUTHENTICATED ||
                    lastErr == IPP_NOT_AUTHORIZED)
                        goto out;
@@ -230,13 +279,13 @@ static int iprint_cache_add_printer(http_t *http,
                goto out;
        }
 
-       for (attr = response->attrs; attr != NULL;) {
+       for (attr = ippFirstAttribute(response); attr != NULL;) {
               /*
                * Skip leading attributes until we hit a printer...
                */
 
-               while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
-                       attr = attr->next;
+               while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+                       attr = ippNextAttribute(response);
 
                if (attr == NULL)
                        break;
@@ -250,15 +299,15 @@ static int iprint_cache_add_printer(http_t *http,
                smb_enabled= 1;
                secure     = 0;
 
-               while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
-                       if (strcmp(attr->name, "printer-name") == 0 &&
-                           attr->value_tag == IPP_TAG_NAME)
-                               name = attr->values[0].string.text;
+               while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) {
+                       if (strcmp(ippGetName(attr), "printer-name") == 0 &&
+                           ippGetValueTag(attr) == IPP_TAG_NAME)
+                               name = ippGetString(attr, 0, NULL);
 
-                       if (strcmp(attr->name, "printer-info") == 0 &&
-                           (attr->value_tag == IPP_TAG_TEXT ||
-                           attr->value_tag == IPP_TAG_TEXTLANG))
-                               info = attr->values[0].string.text;
+                       if (strcmp(ippGetName(attr), "printer-info") == 0 &&
+                           (ippGetValueTag(attr) == IPP_TAG_TEXT ||
+                           ippGetValueTag(attr) == IPP_TAG_TEXTLANG))
+                               info = ippGetString(attr, 0, NULL);
 
                       /*
                        * If the smb-enabled attribute is present and the
@@ -266,11 +315,11 @@ static int iprint_cache_add_printer(http_t *http,
                        * If the attribute is not present, assume that the
                        * printer should show up
                        */
-                       if (!strcmp(attr->name, "smb-enabled") &&
-                           ((attr->value_tag == IPP_TAG_INTEGER &&
-                           !attr->values[0].integer) ||
-                           (attr->value_tag == IPP_TAG_BOOLEAN &&
-                           !attr->values[0].boolean)))
+                       if (!strcmp(ippGetName(attr), "smb-enabled") &&
+                           ((ippGetValueTag(attr) == IPP_TAG_INTEGER &&
+                           !ippGetInteger(attr, 0)) ||
+                           (ippGetValueTag(attr) == IPP_TAG_BOOLEAN &&
+                           !ippGetBoolean(attr, 0))))
                                smb_enabled = 0;
 
                       /*
@@ -279,14 +328,14 @@ static int iprint_cache_add_printer(http_t *http,
                        * If the attribute is not present, assume that the
                        * printer should show up
                        */
-                       if (!strcmp(attr->name, "security-enabled") &&
-                           ((attr->value_tag == IPP_TAG_INTEGER &&
-                           attr->values[0].integer) ||
-                           (attr->value_tag == IPP_TAG_BOOLEAN &&
-                           attr->values[0].boolean)))
+                       if (!strcmp(ippGetName(attr), "security-enabled") &&
+                           ((ippGetValueTag(attr) == IPP_TAG_INTEGER &&
+                           ippGetInteger(attr, 0)) ||
+                           (ippGetValueTag(attr) == IPP_TAG_BOOLEAN &&
+                           ippGetBoolean(attr, 0))))
                                secure = 1;
 
-                       attr = attr->next;
+                       attr = ippNextAttribute(response);
                }
 
               /*
@@ -296,8 +345,8 @@ static int iprint_cache_add_printer(http_t *http,
                * disabled for the printer
                */
 
-               if (name != NULL && !secure && smb_enabled) 
-                       pcap_cache_add(name, info);
+               if (name != NULL && !secure && smb_enabled)
+                       pcap_cache_add_specific(pcache, name, info, NULL);
        }
 
  out:
@@ -306,7 +355,7 @@ static int iprint_cache_add_printer(http_t *http,
        return(0);
 }
 
-BOOL iprint_cache_reload(void)
+bool iprint_cache_reload(struct pcap_cache **_pcache)
 {
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
@@ -314,7 +363,8 @@ BOOL iprint_cache_reload(void)
        ipp_attribute_t *attr;                  /* Current attribute */
        cups_lang_t     *language = NULL;       /* Default language */
        int             i;
-       BOOL ret = False;
+       bool ret = false;
+       struct pcap_cache *pcache = NULL;
 
        DEBUG(5, ("reloading iprint printcap cache\n"));
 
@@ -328,8 +378,20 @@ BOOL iprint_cache_reload(void)
        * Try to connect to the server...
        */
 
-       if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
-               DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
+#ifdef HAVE_HTTPCONNECT2
+       http = httpConnect2(iprint_server(),
+                           ippPort(),
+                           NULL,
+                           AF_UNSPEC,
+                           HTTP_ENCRYPTION_NEVER,
+                           1, /* blocking */
+                           30 * 1000, /* timeout */
+                           NULL);
+#else
+       http = httpConnect(iprint_server(), ippPort());
+#endif
+       if (http == NULL) {
+               DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
                         iprint_server(), strerror(errno)));
                goto out;
        }
@@ -343,8 +405,8 @@ BOOL iprint_cache_reload(void)
 
        request = ippNew();
 
-       request->request.op.operation_id = OPERATION_NOVELL_LIST_PRINTERS;
-       request->request.op.request_id   = 1;
+       ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS);
+       ippSetRequestId(request, 1);
 
        language = cupsLangDefault();
 
@@ -367,13 +429,13 @@ BOOL iprint_cache_reload(void)
                goto out;
        }
 
-       for (attr = response->attrs; attr != NULL;) {
+       for (attr = ippFirstAttribute(response); attr != NULL;) {
               /*
                * Skip leading attributes until we hit a printer...
                */
 
-               while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
-                       attr = attr->next;
+               while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+                       attr = ippNextAttribute(response);
 
                if (attr == NULL)
                        break;
@@ -382,28 +444,30 @@ BOOL iprint_cache_reload(void)
                * Pull the needed attributes from this printer...
                */
 
-               while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+               while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER)
                {
-                       if (strcmp(attr->name, "printer-name") == 0 &&
-                           (attr->value_tag == IPP_TAG_URI ||
-                            attr->value_tag == IPP_TAG_NAME ||
-                            attr->value_tag == IPP_TAG_TEXT ||
-                            attr->value_tag == IPP_TAG_NAMELANG ||
-                            attr->value_tag == IPP_TAG_TEXTLANG))
+                       if (strcmp(ippGetName(attr), "printer-name") == 0 &&
+                           (ippGetValueTag(attr) == IPP_TAG_URI ||
+                            ippGetValueTag(attr) == IPP_TAG_NAME ||
+                            ippGetValueTag(attr) == IPP_TAG_TEXT ||
+                            ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
+                            ippGetValueTag(attr) == IPP_TAG_TEXTLANG))
                        {
-                               for (i = 0; i<attr->num_values; i++)
+                               for (i = 0; i<ippGetCount(attr); i++)
                                {
-                                       char *url = attr->values[i].string.text;
+                                       const char *url = ippGetString(attr, i, NULL);
                                        if (!url || !strlen(url))
                                                continue;
-                                       iprint_cache_add_printer(http, i+2, url);
+                                       iprint_cache_add_printer(http, i+2, url,
+                                                                &pcache);
                                }
                        }
-                       attr = attr->next;
+                       attr = ippNextAttribute(response);
                }
        }
 
-       ret = True;
+       ret = true;
+       *_pcache = pcache;
 
  out:
        if (response)
@@ -446,8 +510,20 @@ static int iprint_job_delete(const char *sharename, const char *lprm_command, st
        * Try to connect to the server...
        */
 
-       if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
-               DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
+#ifdef HAVE_HTTPCONNECT2
+       http = httpConnect2(iprint_server(),
+                           ippPort(),
+                           NULL,
+                           AF_UNSPEC,
+                           HTTP_ENCRYPTION_NEVER,
+                           1, /* blocking */
+                           30 * 1000, /* timeout */
+                           NULL);
+#else
+       http = httpConnect(iprint_server(), ippPort());
+#endif
+       if (http == NULL) {
+               DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
                         iprint_server(), strerror(errno)));
                goto out;
        }
@@ -465,8 +541,8 @@ static int iprint_job_delete(const char *sharename, const char *lprm_command, st
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_CANCEL_JOB;
-       request->request.op.request_id   = 1;
+       ippSetOperation(request, IPP_CANCEL_JOB);
+       ippSetRequestId(request, 1);
 
        language = cupsLangDefault();
 
@@ -492,7 +568,7 @@ static int iprint_job_delete(const char *sharename, const char *lprm_command, st
        slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", sharename);
 
        if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
-               if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+               if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
                        DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
                                ippErrorString(cupsLastError())));
                } else {
@@ -530,6 +606,8 @@ static int iprint_job_pause(int snum, struct printjob *pjob)
        cups_lang_t     *language = NULL;       /* Default language */
        char            uri[HTTP_MAX_URI];      /* printer-uri attribute */
        char            httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
 
 
        DEBUG(5,("iprint_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
@@ -544,8 +622,20 @@ static int iprint_job_pause(int snum, struct printjob *pjob)
        * Try to connect to the server...
        */
 
-       if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
-               DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
+#ifdef HAVE_HTTPCONNECT2
+       http = httpConnect2(iprint_server(),
+                           ippPort(),
+                           NULL,
+                           AF_UNSPEC,
+                           HTTP_ENCRYPTION_NEVER,
+                           1, /* blocking */
+                           30 * 1000, /* timeout */
+                           NULL);
+#else
+       http = httpConnect(iprint_server(), ippPort());
+#endif
+       if (http == NULL) {
+               DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
                         iprint_server(), strerror(errno)));
                goto out;
        }
@@ -563,8 +653,8 @@ static int iprint_job_pause(int snum, struct printjob *pjob)
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_HOLD_JOB;
-       request->request.op.request_id   = 1;
+       ippSetOperation(request, IPP_HOLD_JOB);
+       ippSetRequestId(request, 1);
 
        language = cupsLangDefault();
 
@@ -574,7 +664,8 @@ static int iprint_job_pause(int snum, struct printjob *pjob)
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
 
-       slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
+       slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
+                lp_printername(talloc_tos(), lp_sub, snum));
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
 
@@ -587,10 +678,11 @@ static int iprint_job_pause(int snum, struct printjob *pjob)
        * Do the request and get back a response...
        */
 
-       slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
+       slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
+                lp_printername(talloc_tos(), lp_sub, snum));
 
        if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
-               if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+               if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
                        DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
                                ippErrorString(cupsLastError())));
                } else {
@@ -628,6 +720,8 @@ static int iprint_job_resume(int snum, struct printjob *pjob)
        cups_lang_t     *language = NULL;       /* Default language */
        char            uri[HTTP_MAX_URI];      /* printer-uri attribute */
        char            httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
 
 
        DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
@@ -642,8 +736,20 @@ static int iprint_job_resume(int snum, struct printjob *pjob)
        * Try to connect to the server...
        */
 
-       if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
-               DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
+#ifdef HAVE_HTTPCONNECT2
+       http = httpConnect2(iprint_server(),
+                           ippPort(),
+                           NULL,
+                           AF_UNSPEC,
+                           HTTP_ENCRYPTION_NEVER,
+                           1, /* blocking */
+                           30 * 1000, /* timeout */
+                           NULL);
+#else
+       http = httpConnect(iprint_server(), ippPort());
+#endif
+       if (http == NULL) {
+               DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
                         iprint_server(), strerror(errno)));
                goto out;
        }
@@ -661,8 +767,8 @@ static int iprint_job_resume(int snum, struct printjob *pjob)
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_RELEASE_JOB;
-       request->request.op.request_id   = 1;
+       ippSetOperation(request, IPP_RELEASE_JOB);
+       ippSetRequestId(request, 1);
 
        language = cupsLangDefault();
 
@@ -672,7 +778,8 @@ static int iprint_job_resume(int snum, struct printjob *pjob)
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
 
-       slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
+       slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
+                lp_printername(talloc_tos(), lp_sub, snum));
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
 
@@ -685,10 +792,11 @@ static int iprint_job_resume(int snum, struct printjob *pjob)
        * Do the request and get back a response...
        */
 
-       slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
+       slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
+                lp_printername(talloc_tos(), lp_sub, snum));
 
        if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
-               if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+               if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
                        DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
                                ippErrorString(cupsLastError())));
                } else {
@@ -717,7 +825,9 @@ static int iprint_job_resume(int snum, struct printjob *pjob)
  * 'iprint_job_submit()' - Submit a job for printing.
  */
 
-static int iprint_job_submit(int snum, struct printjob *pjob)
+static int iprint_job_submit(int snum, struct printjob *pjob,
+                            enum printing_types printing_type,
+                            char *lpq_cmd)
 {
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
@@ -726,7 +836,8 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
        ipp_attribute_t *attr;          /* Current attribute */
        cups_lang_t     *language = NULL;       /* Default language */
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-       char            *clientname = NULL;     /* hostname of client for job-originating-host attribute */
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
 
        DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
 
@@ -740,8 +851,20 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
        * Try to connect to the server...
        */
 
-       if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
-               DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
+#ifdef HAVE_HTTPCONNECT2
+       http = httpConnect2(iprint_server(),
+                           ippPort(),
+                           NULL,
+                           AF_UNSPEC,
+                           HTTP_ENCRYPTION_NEVER,
+                           1, /* blocking */
+                           30 * 1000, /* timeout */
+                           NULL);
+#else
+       http = httpConnect(iprint_server(), ippPort());
+#endif
+       if (http == NULL) {
+               DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
                         iprint_server(), strerror(errno)));
                goto out;
        }
@@ -759,8 +882,8 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_PRINT_JOB;
-       request->request.op.request_id   = 1;
+       ippSetOperation(request, IPP_PRINT_JOB);
+       ippSetRequestId(request, 1);
 
        language = cupsLangDefault();
 
@@ -770,7 +893,8 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
 
-       slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
+       slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
+                lp_printername(talloc_tos(), lp_sub, snum));
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
                     "printer-uri", NULL, uri);
@@ -778,14 +902,9 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
                     NULL, pjob->user);
 
-       clientname = client_name();
-       if (strcmp(clientname, "UNKNOWN") == 0) {
-               clientname = client_addr();
-       }
-
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                     "job-originating-host-name", NULL,
-                    clientname);
+                    pjob->clientmachine);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
                     pjob->jobname);
@@ -794,17 +913,19 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
        * Do the request and get back a response...
        */
 
-       slprintf(uri, sizeof(uri) - 1, "/ipp/%s", PRINTERNAME(snum));
+       slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(talloc_tos(), lp_sub, snum));
 
        if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
-               if (response->request.status.status_code >= IPP_OK_CONFLICT) {
-                       DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
+               if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
+                       DEBUG(0,("Unable to print file to %s - %s\n",
+                                lp_printername(talloc_tos(), lp_sub, snum),
                                 ippErrorString(cupsLastError())));
                } else {
                        ret = 0;
                }
        } else {
-               DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
+               DEBUG(0,("Unable to print file to `%s' - %s\n",
+                        lp_printername(talloc_tos(), lp_sub, snum),
                         ippErrorString(cupsLastError())));
        }
 
@@ -815,9 +936,9 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
        if ( ret == 0 ) {
 
                attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER);
-               if (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+               if (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB)
                {
-                       pjob->sysjob = attr->values[0].integer;
+                       pjob->sysjob = ippGetInteger(attr, 0);
                }
        }
 
@@ -841,7 +962,7 @@ static int iprint_job_submit(int snum, struct printjob *pjob)
 static int iprint_queue_get(const char *sharename,
                            enum printing_types printing_type,
                            char *lpq_command,
-                           print_queue_struct **q, 
+                           print_queue_struct **q,
                            print_status_struct *status)
 {
        fstring         printername;
@@ -864,7 +985,6 @@ static int iprint_queue_get(const char *sharename,
        int             job_id;         /* job-id attribute */
        int             job_k_octets;   /* job-k-octets attribute */
        time_t          job_time;       /* time-at-creation attribute */
-       time_t          printer_current_time = 0;       /* printer's current time */
        time_t          printer_up_time = 0;    /* printer's uptime */
        ipp_jstate_t    job_status;     /* job-status attribute */
        int             job_priority;   /* job-priority attribute */
@@ -888,10 +1008,10 @@ static int iprint_queue_get(const char *sharename,
 
        *q = NULL;
 
-       /* HACK ALERT!!!  The porblem with support the 'printer name' 
-          option is that we key the tdb off the sharename.  So we will 
-          overload the lpq_command string to pass in the printername 
-          (which is basically what we do for non-cups printers ... using 
+       /* HACK ALERT!!!  The problem with support the 'printer name'
+          option is that we key the tdb off the sharename.  So we will
+          overload the lpq_command string to pass in the printername
+          (which is basically what we do for non-cups printers ... using
           the lpq_command to get the queue listing). */
 
        fstrcpy( printername, lpq_command );
@@ -908,8 +1028,20 @@ static int iprint_queue_get(const char *sharename,
        * Try to connect to the server...
        */
 
-       if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
-               DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
+#ifdef HAVE_HTTPCONNECT2
+       http = httpConnect2(iprint_server(),
+                           ippPort(),
+                           NULL,
+                           AF_UNSPEC,
+                           HTTP_ENCRYPTION_NEVER,
+                           1, /* blocking */
+                           30 * 1000, /* timeout */
+                           NULL);
+#else
+       http = httpConnect(iprint_server(), ippPort());
+#endif
+       if (http == NULL) {
+               DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
                         iprint_server(), strerror(errno)));
                goto out;
        }
@@ -924,7 +1056,7 @@ static int iprint_queue_get(const char *sharename,
        /*
        * For Linux iPrint servers from OES SP1 on, the iPrint server
        * uses Unix time for job start times unless it detects the iPrint
-       * client in an http User-Agent header.  (This was done to accomodate
+       * client in an http User-Agent header.  (This was done to accommodate
        * CUPS broken behavior.  According to RFC 2911, section 4.3.14, job
        * start times are supposed to be relative to how long the printer has
        * been up.)  Since libcups doesn't allow us to set that header before
@@ -937,8 +1069,8 @@ static int iprint_queue_get(const char *sharename,
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
-       request->request.op.request_id   = 2;
+       ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
+       ippSetRequestId(request, 2);
 
        language = cupsLangDefault();
 
@@ -969,9 +1101,9 @@ static int iprint_queue_get(const char *sharename,
                goto out;
        }
 
-       if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+       if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
                DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
-                        ippErrorString(response->request.status.status_code)));
+                        ippErrorString(ippGetStatusCode(response))));
                *q = queue;
                goto out;
        }
@@ -981,7 +1113,7 @@ static int iprint_queue_get(const char *sharename,
        */
 
        if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
-               if (attr->values[0].integer == IPP_PRINTER_STOPPED)
+               if (ippGetInteger(attr, 0) == IPP_PRINTER_STOPPED)
                        status->status = LPSTAT_STOPPED;
                else
                        status->status = LPSTAT_OK;
@@ -989,15 +1121,11 @@ static int iprint_queue_get(const char *sharename,
 
        if ((attr = ippFindAttribute(response, "printer-state-message",
                                     IPP_TAG_TEXT)) != NULL)
-               fstrcpy(status->message, attr->values[0].string.text);
-
-       if ((attr = ippFindAttribute(response, "printer-current-time",
-                                    IPP_TAG_DATE)) != NULL)
-               printer_current_time = ippDateToTime(attr->values[0].date);
+               fstrcpy(status->message, ippGetString(attr, 0, NULL));
 
        if ((attr = ippFindAttribute(response, "printer-up-time",
                                     IPP_TAG_INTEGER)) != NULL)
-               printer_up_time = attr->values[0].integer;
+               printer_up_time = ippGetInteger(attr, 0);
 
        ippDelete(response);
        response = NULL;
@@ -1014,8 +1142,8 @@ static int iprint_queue_get(const char *sharename,
 
        request = ippNew();
 
-       request->request.op.operation_id = IPP_GET_JOBS;
-       request->request.op.request_id   = 3;
+       ippSetOperation(request, IPP_GET_JOBS);
+       ippSetRequestId(request, 3);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
                     "attributes-charset", NULL, "utf-8");
@@ -1043,9 +1171,9 @@ static int iprint_queue_get(const char *sharename,
                goto out;
        }
 
-       if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+       if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
                DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
-                        ippErrorString(response->request.status.status_code)));
+                        ippErrorString(ippGetStatusCode(response))));
                goto out;
        }
 
@@ -1057,13 +1185,13 @@ static int iprint_queue_get(const char *sharename,
        qalloc = 0;
        queue  = NULL;
 
-       for (attr = response->attrs; attr != NULL; attr = attr->next) {
+       for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) {
               /*
                * Skip leading attributes until we hit a job...
                */
 
-               while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
-                       attr = attr->next;
+               while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_JOB)
+                       attr = ippNextAttribute(response);
 
                if (attr == NULL)
                        break;
@@ -1074,16 +1202,13 @@ static int iprint_queue_get(const char *sharename,
                if (qcount >= qalloc) {
                        qalloc += 16;
 
-                       temp = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
+                       queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
 
-                       if (temp == NULL) {
-                               DEBUG(0,("iprint_queue_get: Not enough memory!"));
+                       if (queue == NULL) {
+                               DEBUG(0,("iprint_queue_get: Not enough memory!\n"));
                                qcount = 0;
-                               SAFE_FREE(queue);
                                goto out;
                        }
-
-                       queue = temp;
                }
 
                temp = queue + qcount;
@@ -1101,30 +1226,30 @@ static int iprint_queue_get(const char *sharename,
                user_name    = NULL;
                job_name     = NULL;
 
-               while (attr != NULL && attr->group_tag == IPP_TAG_JOB) {
-                       if (attr->name == NULL) {
-                               attr = attr->next;
+               while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) {
+                       if (ippGetName(attr) == NULL) {
+                               attr = ippNextAttribute(response);
                                break;
                        }
 
-                       if (strcmp(attr->name, "job-id") == 0 &&
-                           attr->value_tag == IPP_TAG_INTEGER)
-                               job_id = attr->values[0].integer;
+                       if (strcmp(ippGetName(attr), "job-id") == 0 &&
+                           ippGetValueTag(attr) == IPP_TAG_INTEGER)
+                               job_id = ippGetInteger(attr, 0);
 
-                       if (strcmp(attr->name, "job-k-octets") == 0 &&
-                           attr->value_tag == IPP_TAG_INTEGER)
-                               job_k_octets = attr->values[0].integer;
+                       if (strcmp(ippGetName(attr), "job-k-octets") == 0 &&
+                           ippGetValueTag(attr) == IPP_TAG_INTEGER)
+                               job_k_octets = ippGetInteger(attr, 0);
 
-                       if (strcmp(attr->name, "job-priority") == 0 &&
-                           attr->value_tag == IPP_TAG_INTEGER)
-                               job_priority = attr->values[0].integer;
+                       if (strcmp(ippGetName(attr), "job-priority") == 0 &&
+                           ippGetValueTag(attr) == IPP_TAG_INTEGER)
+                               job_priority = ippGetInteger(attr, 0);
 
-                       if (strcmp(attr->name, "job-state") == 0 &&
-                           attr->value_tag == IPP_TAG_ENUM)
-                               job_status = (ipp_jstate_t)(attr->values[0].integer);
+                       if (strcmp(ippGetName(attr), "job-state") == 0 &&
+                           ippGetValueTag(attr) == IPP_TAG_ENUM)
+                               job_status = (ipp_jstate_t)ippGetInteger(attr, 0);
 
-                       if (strcmp(attr->name, "time-at-creation") == 0 &&
-                           attr->value_tag == IPP_TAG_INTEGER)
+                       if (strcmp(ippGetName(attr), "time-at-creation") == 0 &&
+                           ippGetValueTag(attr) == IPP_TAG_INTEGER)
                        {
                               /*
                                * If jobs times are in Unix time, the accuracy of the job
@@ -1134,22 +1259,22 @@ static int iprint_queue_get(const char *sharename,
                                */
 
                                if (jobUseUnixTime)
-                                       job_time = attr->values[0].integer; 
+                                       job_time = ippGetInteger(attr, 0);
                                else
-                                       job_time = time(NULL) - printer_up_time + attr->values[0].integer;
+                                       job_time = time(NULL) - printer_up_time + ippGetInteger(attr, 0);
                        }
 
-                       if (strcmp(attr->name, "job-name") == 0 &&
-                           (attr->value_tag == IPP_TAG_NAMELANG ||
-                            attr->value_tag == IPP_TAG_NAME))
-                               job_name = attr->values[0].string.text;
+                       if (strcmp(ippGetName(attr), "job-name") == 0 &&
+                           (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
+                            ippGetValueTag(attr) == IPP_TAG_NAME))
+                               job_name = ippGetString(attr, 0, NULL);
 
-                       if (strcmp(attr->name, "job-originating-user-name") == 0 &&
-                           (attr->value_tag == IPP_TAG_NAMELANG ||
-                            attr->value_tag == IPP_TAG_NAME))
-                               user_name = attr->values[0].string.text;
+                       if (strcmp(ippGetName(attr), "job-originating-user-name") == 0 &&
+                           (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
+                            ippGetValueTag(attr) == IPP_TAG_NAME))
+                               user_name = ippGetString(attr, 0, NULL);
 
-                       attr = attr->next;
+                       attr = ippNextAttribute(response);
                }
 
               /*
@@ -1163,7 +1288,7 @@ static int iprint_queue_get(const char *sharename,
                                continue;
                }
 
-               temp->job      = job_id;
+               temp->sysjob   = job_id;
                temp->size     = job_k_octets * 1024;
                temp->status   = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
                                 job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
@@ -1206,7 +1331,7 @@ static int iprint_queue_get(const char *sharename,
 
 static int iprint_queue_pause(int snum)
 {
-       return(-1); //Not supported without credentials
+       return(-1); /* Not supported without credentials */
 }
 
 
@@ -1216,7 +1341,7 @@ static int iprint_queue_pause(int snum)
 
 static int iprint_queue_resume(int snum)
 {
-       return(-1); //Not supported without credentials
+       return(-1); /* Not supported without credentials */
 }
 
 /*******************************************************************
@@ -1237,5 +1362,6 @@ struct printif    iprint_printif =
 
 #else
  /* this keeps fussy compilers happy */
+ void print_iprint_dummy(void);
  void print_iprint_dummy(void) {}
 #endif /* HAVE_IPRINT */