Index: modules/printbackends/cups/gtkcupsutils.c
===================================================================
--- modules/printbackends/cups/gtkcupsutils.c	(revision 18272)
+++ modules/printbackends/cups/gtkcupsutils.c	(working copy)
@@ -41,10 +41,12 @@
 static void _post_write_request (GtkCupsRequest *request);
 static void _post_write_data    (GtkCupsRequest *request);
 static void _post_check         (GtkCupsRequest *request);
+static void _post_auth          (GtkCupsRequest *request);
 static void _post_read_response (GtkCupsRequest *request);
 
 static void _get_send           (GtkCupsRequest *request);
 static void _get_check          (GtkCupsRequest *request);
+static void _get_auth           (GtkCupsRequest *request);
 static void _get_read_data      (GtkCupsRequest *request);
 
 struct _GtkCupsResult
@@ -71,6 +73,7 @@
   _post_write_request,
   _post_write_data,
   _post_check,
+  _post_auth,
   _post_read_response
 };
 
@@ -78,6 +81,7 @@
   _connect,
   _get_send,
   _get_check,
+  _get_auth,
   _get_read_data
 };
 
@@ -207,6 +211,7 @@
 
   g_free (request->server);
   g_free (request->resource);
+  g_free (request->password);
 
   gtk_cups_result_free (request->result);
 
@@ -790,6 +795,65 @@
     }
 }
 
+static void
+_post_auth (GtkCupsRequest *request)
+{
+  if (request->has_password)
+    {
+      if (request->password == NULL)
+        {
+          request->state = GTK_CUPS_POST_DONE;
+          request->poll_state = GTK_CUPS_HTTP_IDLE;
+
+          gtk_cups_result_set_error (request->result, 
+                                     GTK_CUPS_ERROR_AUTH,
+                                     0,
+                                     1,
+                                     "Canceled by user");
+        }
+      else
+        request->state = GTK_CUPS_POST_CHECK;
+    }
+}
+
+static void
+_get_auth (GtkCupsRequest *request)
+{
+  if (request->has_password)
+    {
+      if (request->password == NULL)
+        {
+          request->state = GTK_CUPS_GET_DONE;
+          request->poll_state = GTK_CUPS_HTTP_IDLE;
+
+          gtk_cups_result_set_error (request->result, 
+                                     GTK_CUPS_ERROR_AUTH,
+                                     0,
+                                     1,
+                                     "Canceled by user");
+        }
+      else
+        request->state = GTK_CUPS_GET_CHECK;
+    }
+}
+
+/* Very ugly hack: cups has a stupid synchronous password callback 
+ * that doesn't even take the request or user data parameters, so 
+ * we have to use a static variable to pass the password to it.
+ * Not threadsafe !
+ * The callback sets cups_password to NULL to signal that the 
+ * password has been used.
+ */
+static char *cups_password;
+
+static char *
+passwordCB (const char *prompt)
+{
+  char *pwd = cups_password;
+  cups_password = NULL;
+  return pwd;
+}
+
 static void 
 _post_check (GtkCupsRequest *request)
 {
@@ -808,18 +872,49 @@
     }
   else if (http_status == HTTP_UNAUTHORIZED)
     {
-      /* TODO: callout for auth */
-      g_warning ("NOT IMPLEMENTED: We need to prompt for authorization");
-      request->state = GTK_CUPS_POST_DONE;
-      request->poll_state = GTK_CUPS_HTTP_IDLE;
+      httpFlush (request->http);
+       
+      if (!request->has_password)
+        {
+          /* move to AUTH state to let the backend 
+           * ask for a password
+           */ 
+          request->state = GTK_CUPS_POST_AUTH;
+          request->need_password = TRUE;
+          return;
+        }
+
+      cups_password = request->password;
+      cupsSetPasswordCB (passwordCB);
+
+      if (cupsDoAuthentication (request->http, "POST", request->resource) ||
+          httpReconnect (request->http))
+        {
+          /* if the password has been used, reset has_password
+           * so that we ask for a new one next time around
+           */ 
+          if (cups_password == NULL)
+            request->has_password = FALSE;
+
+          request->state = GTK_CUPS_POST_DONE;
+          request->poll_state = GTK_CUPS_HTTP_IDLE;
       
-      /* TODO: create a not implemented error code */
-      gtk_cups_result_set_error (request->result, 
-                                 GTK_CUPS_ERROR_GENERAL,
-                                 0,
-                                 0,
-                                 "Can't prompt for authorization");
-      return;
+          gtk_cups_result_set_error (request->result, 
+                                     GTK_CUPS_ERROR_AUTH,
+                                     0,
+                                     0,
+                                     "Not authorized");
+          return;
+        }
+
+      /* if the password has been used, reset has_password
+       * so that we ask for a new one next time around
+       */ 
+      if (cups_password == NULL)
+        request->has_password = FALSE;
+
+      request->state = GTK_CUPS_POST_CONNECT;
+      request->poll_state = GTK_CUPS_HTTP_WRITE;
     }
   else if (http_status == HTTP_ERROR)
     {
@@ -835,6 +930,7 @@
         }
       else
         {
+ error:
           request->state = GTK_CUPS_POST_DONE;
           request->poll_state = GTK_CUPS_HTTP_IDLE;
      
@@ -847,10 +943,11 @@
           return;
         }
     }
-/* TODO: detect ssl in configure.ac */
-#if HAVE_SSL
   else if (http_status == HTTP_UPGRADE_REQUIRED)
     {
+      cupsSetEncryption (HTTP_ENCRYPT_REQUIRED);
+      request->state = GTK_CUPS_POST_CONNECT;
+
       /* Flush any error message... */
       httpFlush (request->http);
 
@@ -863,7 +960,6 @@
       request->attempts++;
       goto again;
     }
-#endif 
   else if (http_status != HTTP_OK)
     {
       int http_errno;
@@ -996,6 +1092,9 @@
       return;    
     }
         
+  if (httpCheck (request->http))
+    request->last_status = httpUpdate (request->http);
+
   request->attempts = 0;
 
   request->state = GTK_CUPS_GET_CHECK;
@@ -1022,23 +1121,57 @@
     }
   else if (http_status == HTTP_UNAUTHORIZED)
     {
-      /* TODO: callout for auth */
-      g_warning ("NOT IMPLEMENTED: We need to prompt for authorization in a non blocking manner");
-      request->state = GTK_CUPS_GET_DONE;
-      request->poll_state = GTK_CUPS_HTTP_IDLE;
+      httpFlush (request->http);
 
-      /* TODO: should add a status or error code for not implemented */ 
-      gtk_cups_result_set_error (request->result, 
-                                 GTK_CUPS_ERROR_GENERAL,
-                                 0,
-                                 0,
-                                 "Can't prompt for authorization");
+      if (!request->has_password) 
+        {
+          /* move to AUTH state to let the backend
+           * ask for a password
+           */
+          request->state = GTK_CUPS_GET_AUTH;
+          request->need_password = TRUE;
+          return;
+        }
+
+      cups_password = request->password;
+      cupsSetPasswordCB (passwordCB);
+
+      if (cupsDoAuthentication (request->http, "GET", request->resource) ||
+          httpReconnect (request->http))
+        {
+          /* if the password has been used, reset has_password
+           * so that we ask for a new one next time around
+           */
+          if (cups_password == NULL)
+            request->has_password = FALSE;
+
+          request->state = GTK_CUPS_GET_DONE;
+          request->poll_state = GTK_CUPS_HTTP_IDLE;
+
+          gtk_cups_result_set_error (request->result, 
+                                     GTK_CUPS_ERROR_AUTH,
+                                     0,
+                                     0,
+                                     "Not authorized");
+          return;
+        }
+
+      /* if the password has been used, reset has_password
+       * so that we ask for a new one next time around 
+       */
+      if (cups_password == NULL)
+        request->has_password = FALSE;
+ 
+      request->state = GTK_CUPS_GET_SEND;
+      request->last_status = HTTP_CONTINUE;
+
       return;
     }
-/* TODO: detect ssl in configure.ac */
-#if HAVE_SSL
   else if (http_status == HTTP_UPGRADE_REQUIRED)
     {
+      cupsSetEncryption (HTTP_ENCRYPT_REQUIRED);
+      request->state = GTK_CUPS_GET_CONNECT;
+
       /* Flush any error message... */
       httpFlush (request->http);
 
@@ -1051,7 +1184,6 @@
       request->attempts++;
       goto again;
     }
-#endif
   else if (http_status != HTTP_OK)
     {
       int http_errno;
@@ -1096,7 +1228,6 @@
     http_status = httpUpdate (request->http);
 
   request->last_status = http_status;
-
 }
 
 static void 
Index: modules/printbackends/cups/gtkprintbackendcups.c
===================================================================
--- modules/printbackends/cups/gtkprintbackendcups.c	(revision 18272)
+++ modules/printbackends/cups/gtkprintbackendcups.c	(working copy)
@@ -106,6 +106,9 @@
   guint list_printers_poll;
   guint list_printers_pending : 1;
   guint got_default_printer   : 1;
+
+  GList *requests;
+  GHashTable *auth;
 };
 
 static GObjectClass *backend_parent_class;
@@ -161,6 +164,10 @@
 								    gdouble                            height,
 								    GIOChannel                        *cache_io);
 
+static void                 gtk_print_backend_cups_set_password    (GtkPrintBackend *backend, 
+                                                                    const gchar *hostname,
+                                                                    const gchar *username,
+                                                                    const gchar *password);
 
 static void
 gtk_print_backend_cups_register_type (GTypeModule *module)
@@ -255,6 +262,8 @@
   backend_class->printer_list_papers = cups_printer_list_papers;
   backend_class->printer_get_hard_margins = cups_printer_get_hard_margins;
   backend_class->printer_get_capabilities = cups_printer_get_capabilities;
+
+  backend_class->set_password = gtk_print_backend_cups_set_password;
 }
 
 static cairo_status_t
@@ -455,10 +464,13 @@
 static void
 gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
 {
-  backend_cups->list_printers_poll = FALSE;  
+  backend_cups->list_printers_poll = 0;
   backend_cups->got_default_printer = FALSE;  
   backend_cups->list_printers_pending = FALSE;
 
+  backend_cups->requests = NULL;
+  backend_cups->auth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
   cups_request_default_printer (backend_cups);
 }
 
@@ -475,6 +487,8 @@
   g_free (backend_cups->default_printer);
   backend_cups->default_printer = NULL;
   
+  g_hash_table_destroy (backend_cups->auth);
+  
   backend_parent_class->finalize (object);
 }
 
@@ -495,8 +509,75 @@
   backend_parent_class->dispose (object);
 }
 
+static void
+gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
+                                     const gchar     *hostname,
+                                     const gchar     *username, 
+                                     const gchar     *password)
+{
+  GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (backend);
+  GList *l;
+  const char *dispatch_hostname;
+  gchar *key;
+  
+  key = g_strconcat (username, "@", hostname, NULL);
+  g_hash_table_insert (cups_backend->auth, key, g_strdup (password));
 
+  GTK_NOTE (PRINTING,
+            g_print ("CUPS backend: storing password for %s\n", key));
+
+  for (l = cups_backend->requests; l; l = l->next)
+    {
+      GtkPrintCupsDispatchWatch *dispatch = l->data;
+      
+      dispatch_hostname = dispatch->request->http->hostname;
+      if (dispatch_hostname[0] == '/')
+        dispatch_hostname = "localhost";
+
+      if (strcmp (hostname, dispatch_hostname) == 0) 
+        {
+          g_free (dispatch->request->password);
+          dispatch->request->password = g_strdup (password);
+          dispatch->request->has_password = TRUE;
+        }
+    }
+}
+
 static gboolean
+request_password (gpointer data)
+{
+  const gchar *hostname;
+  const gchar *username;
+  gchar *password;
+  gchar *key;
+  gboolean handled;
+  GtkPrintCupsDispatchWatch *dispatch = data;
+
+  hostname = dispatch->request->http->hostname;
+  if (hostname[0] == '/')
+    hostname = "localhost";
+  username = cupsUser ();
+  key = g_strconcat (username, "@", hostname, NULL);
+  password = g_hash_table_lookup (dispatch->backend->auth, key);
+
+  if (password)
+    {
+      GTK_NOTE (PRINTING,
+                g_print ("CUPS backend: using stored password for %s\n", key));
+      g_free (dispatch->request->password);
+      dispatch->request->password = g_strdup (password);
+      dispatch->request->has_password = TRUE;
+    }
+  else
+    g_signal_emit_by_name (dispatch->backend, "request-password", 
+                           hostname, username, &handled);
+  
+  g_free (key);
+
+  return FALSE;
+}
+
+static gboolean
 cups_dispatch_watch_check (GSource *source)
 {
   GtkPrintCupsDispatchWatch *dispatch;
@@ -546,6 +627,13 @@
       dispatch->data_poll = NULL;
     }
   
+  if (dispatch->request->need_password)
+    {
+      dispatch->request->need_password = FALSE;
+      g_idle_add (request_password, dispatch);
+      result = FALSE;
+    }
+
   return result;
 }
 
@@ -575,7 +663,7 @@
   GtkCupsResult *result;
   
   g_assert (callback != NULL);
-
+  
   ep_callback = (GtkPrintCupsResponseCallbackFunc) callback;
   
   dispatch = (GtkPrintCupsDispatchWatch *) source;
@@ -604,12 +692,32 @@
 cups_dispatch_watch_finalize (GSource *source)
 {
   GtkPrintCupsDispatchWatch *dispatch;
+  GtkCupsResult *result;
 
   GTK_NOTE (PRINTING,
             g_print ("CUPS Backend: %s <source %p>\n", G_STRFUNC, source));
 
   dispatch = (GtkPrintCupsDispatchWatch *) source;
 
+  result = gtk_cups_request_get_result (dispatch->request);
+  if (gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_AUTH)
+    {
+      const gchar *username;
+      const gchar *hostname;
+      gchar *key;
+    
+      hostname = dispatch->request->http->hostname;
+      if (hostname[0] == '/')
+        hostname = "localhost";
+      username = cupsUser ();
+
+      key = g_strconcat (username, "@", hostname, NULL);
+      GTK_NOTE (PRINTING,
+                g_print ("CUPS backend: removing stored password for %s\n", key));
+      g_hash_table_remove (dispatch->backend->auth, key);
+      g_free (key);
+    }
+
   gtk_cups_request_free (dispatch->request);
 
   if (dispatch->backend)
@@ -623,6 +731,9 @@
        * of print backends. See _gtk_print_backend_create for the
        * disabling.
        */
+
+      dispatch->backend->requests = g_list_remove (dispatch->backend->requests, dispatch);
+
       g_object_unref (dispatch->backend);
       dispatch->backend = NULL;
     }
@@ -637,7 +748,6 @@
   cups_dispatch_watch_finalize
 };
 
-
 static void
 cups_request_execute (GtkPrintBackendCups              *print_backend,
                       GtkCupsRequest                   *request,
@@ -657,6 +767,8 @@
   dispatch->backend = g_object_ref (print_backend);
   dispatch->data_poll = NULL;
 
+  print_backend->requests = g_list_prepend (print_backend->requests, dispatch);
+
   g_source_set_callback ((GSource *) dispatch, (GSourceFunc) callback, user_data, notify);
 
   g_source_attach ((GSource *) dispatch, NULL);
@@ -988,9 +1100,20 @@
   if (gtk_cups_result_is_error (result))
     {
       GTK_NOTE (PRINTING, 
-                g_warning ("CUPS Backend: Error getting printer list: %s", 
-        	           gtk_cups_result_get_error_string (result)));
+                g_warning ("CUPS Backend: Error getting printer list: %s %d %d", 
+        	           gtk_cups_result_get_error_string (result),
+                           gtk_cups_result_get_error_type (result),
+                           gtk_cups_result_get_error_code (result)));
 
+      if (gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_AUTH &&
+          gtk_cups_result_get_error_code (result) == 1)
+        {
+          /* Canceled by user, stop popping up more password dialogs */
+          if (cups_backend->list_printers_poll > 0)
+            g_source_remove (cups_backend->list_printers_poll);
+          cups_backend->list_printers_poll = 0;
+        }
+
       goto done;
     }
   
@@ -1299,6 +1422,9 @@
           success = TRUE;
         } 
         
+      g_print ("get ppd: error, %d %d\n", 
+               gtk_cups_result_get_error_type (result),
+               gtk_cups_result_get_error_code (result));
       g_signal_emit_by_name (printer, "details-acquired", success);
       goto done;
     }
@@ -1333,6 +1459,7 @@
 
   error = NULL;
 
+  g_print ("cups_request_ppd\n");
   GTK_NOTE (PRINTING,
             g_print ("CUPS Backend: %s\n", G_STRFUNC));
 
@@ -1389,9 +1516,6 @@
   GTK_NOTE (PRINTING,
             g_print ("CUPS Backend: Requesting resource %s to be written to temp file %s\n", resource, ppd_filename));
 
-  g_free (resource);
-  g_free (ppd_filename);
-
   cups_printer->reading_ppd = TRUE;
 
   print_backend = gtk_printer_get_backend (printer);
@@ -1401,6 +1525,9 @@
                         (GtkPrintCupsResponseCallbackFunc) cups_request_ppd_cb,
                         data,
                         (GDestroyNotify)get_ppd_data_free);
+
+  g_free (resource);
+  g_free (ppd_filename);
 }
 
 
@@ -1412,6 +1539,21 @@
   ipp_t *response;
   ipp_attribute_t *attr;
 
+  
+  if (gtk_cups_result_is_error (result))
+    {
+      if (gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_AUTH &&
+          gtk_cups_result_get_error_code (result) == 1)
+        {
+          /* Canceled by user, stop popping up more password dialogs */
+          if (print_backend->list_printers_poll > 0)
+            g_source_remove (print_backend->list_printers_poll);
+          print_backend->list_printers_poll = 0;
+        }
+
+      return;
+    }
+
   response = gtk_cups_result_get_response (result);
   
   if ((attr = ippFindAttribute (response, "printer-name", IPP_TAG_NAME)) != NULL)
Index: modules/printbackends/cups/gtkcupsutils.h
===================================================================
--- modules/printbackends/cups/gtkcupsutils.h	(revision 18272)
+++ modules/printbackends/cups/gtkcupsutils.h	(working copy)
@@ -36,6 +36,7 @@
   GTK_CUPS_ERROR_HTTP,
   GTK_CUPS_ERROR_IPP,
   GTK_CUPS_ERROR_IO,
+  GTK_CUPS_ERROR_AUTH,
   GTK_CUPS_ERROR_GENERAL
 } GtkCupsErrorType;
 
@@ -77,7 +78,11 @@
   gint state;
   GtkCupsPollState poll_state;
 
-  gint own_http : 1; 
+  gchar *password;
+
+  gint own_http : 1;
+  gint need_password : 1;
+  gint has_password : 1;
 };
 
 #define GTK_CUPS_REQUEST_START 0
@@ -91,6 +96,7 @@
   GTK_CUPS_POST_WRITE_REQUEST,
   GTK_CUPS_POST_WRITE_DATA,
   GTK_CUPS_POST_CHECK,
+  GTK_CUPS_POST_AUTH,
   GTK_CUPS_POST_READ_RESPONSE,
   GTK_CUPS_POST_DONE = GTK_CUPS_REQUEST_DONE
 };
@@ -101,6 +107,7 @@
   GTK_CUPS_GET_CONNECT = GTK_CUPS_REQUEST_START,
   GTK_CUPS_GET_SEND,
   GTK_CUPS_GET_CHECK,
+  GTK_CUPS_GET_AUTH,
   GTK_CUPS_GET_READ_DATA,
   GTK_CUPS_GET_DONE = GTK_CUPS_REQUEST_DONE
 };
Index: gtk/gtkmarshalers.list
===================================================================
--- gtk/gtkmarshalers.list	(revision 18272)
+++ gtk/gtkmarshalers.list	(working copy)
@@ -46,6 +46,7 @@
 BOOLEAN:NONE
 BOOLEAN:BOOLEAN,BOOLEAN,BOOLEAN
 BOOLEAN:STRING
+BOOLEAN:STRING,STRING
 ENUM:ENUM
 ENUM:VOID
 INT:POINTER
Index: gtk/gtkprintbackend.c
===================================================================
--- gtk/gtkprintbackend.c	(revision 18272)
+++ gtk/gtkprintbackend.c	(working copy)
@@ -25,6 +25,7 @@
 
 #include "gtkintl.h"
 #include "gtkmodules.h"
+#include "gtkmarshalers.h"
 #include "gtkprivate.h"
 #include "gtkprintbackend.h"
 #include "gtkprinter-private.h"
@@ -48,6 +49,7 @@
   PRINTER_ADDED,
   PRINTER_REMOVED,
   PRINTER_STATUS_CHANGED,
+  REQUEST_PASSWORD,
   LAST_SIGNAL
 };
 
@@ -293,7 +295,15 @@
 							       gdouble             *right);
 static GList *              fallback_printer_list_papers      (GtkPrinter          *printer);
 static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter          *printer);
-  
+static gboolean             request_password                  (GtkPrintBackend     *backend,
+                                                               const gchar         *hostname,
+                                                               const gchar         *username);
+static void                 fallback_set_password             (GtkPrintBackend     *backend,
+                                                               const gchar         *hostname,
+                                                               const gchar         *username,
+                                                               const gchar         *password);
+                           
+
 static void
 gtk_print_backend_class_init (GtkPrintBackendClass *class)
 {
@@ -309,6 +319,8 @@
   class->printer_get_hard_margins = fallback_printer_get_hard_margins;
   class->printer_list_papers = fallback_printer_list_papers;
   class->printer_get_capabilities = fallback_printer_get_capabilities;
+  class->request_password = request_password;
+  class->set_password = fallback_set_password;
   
   g_type_class_add_private (class, sizeof (GtkPrintBackendPrivate));
   
@@ -352,6 +364,14 @@
 		  NULL, NULL,
 		  g_cclosure_marshal_VOID__OBJECT,
 		  G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
+  signals[REQUEST_PASSWORD] =
+    g_signal_new (I_("request-password"),
+		  G_TYPE_FROM_CLASS (class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GtkPrintBackendClass, request_password),
+		  _gtk_boolean_handled_accumulator, NULL,
+		  _gtk_marshal_BOOLEAN__STRING_STRING,
+		  G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_STRING);
 }
 
 static void
@@ -561,6 +581,36 @@
 						       dnotify);
 }
 
+void 
+gtk_print_backend_set_password (GtkPrintBackend *backend,
+                                const gchar     *hostname,
+                                const gchar     *username,
+                                const gchar     *password)
+{
+  g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
+
+  GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, hostname, username, password);
+}
+
+void 
+fallback_set_password (GtkPrintBackend *backend,
+                       const gchar     *hostname,
+                       const gchar     *username,
+                       const gchar     *password)
+{
+}
+
+gboolean
+request_password (GtkPrintBackend *backend,
+                  const gchar     *hostname,
+                  const gchar     *username)
+{
+  /* set an invalid password */
+  gtk_print_backend_set_password (backend, hostname, username, NULL);
+
+  return TRUE;
+}
+
 void
 gtk_print_backend_destroy (GtkPrintBackend *print_backend)
 {
Index: gtk/gtkprintbackend.h
===================================================================
--- gtk/gtkprintbackend.h	(revision 18272)
+++ gtk/gtkprintbackend.h	(working copy)
@@ -116,14 +116,22 @@
   void                  (*printer_status_changed)            (GtkPrintBackend     *backend,
 							      GtkPrinter          *printer);
 
+  gboolean              (*request_password)                  (GtkPrintBackend     *backend,
+                                                              const gchar         *hostname,
+                                                              const gchar         *username);
+
+  /* not a signal */
+  void                  (*set_password)                      (GtkPrintBackend     *backend,
+                                                              const gchar         *hostname,
+                                                              const gchar         *username,
+                                                              const gchar         *password);
+             
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);
   void (*_gtk_reserved5) (void);
-  void (*_gtk_reserved6) (void);
-  void (*_gtk_reserved7) (void);
 };
 
 GType   gtk_print_backend_get_type       (void) G_GNUC_CONST;
@@ -141,6 +149,11 @@
 GList *     gtk_print_backend_load_modules         (void);
 void        gtk_print_backend_destroy              (GtkPrintBackend         *print_backend);
 
+void        gtk_print_backend_set_password         (GtkPrintBackend         *backend, 
+                                                    const gchar             *hostname,
+                                                    const gchar             *username,
+                                                    const gchar             *password);
+
 /* Backend-only functions for GtkPrintBackend */
 
 void        gtk_print_backend_add_printer          (GtkPrintBackend         *print_backend,
@@ -149,7 +162,6 @@
 						    GtkPrinter              *printer);
 void        gtk_print_backend_set_list_done        (GtkPrintBackend         *backend);
 
-
 /* Backend-only functions for GtkPrinter */
 
 GtkPrinter *gtk_printer_new               (const char      *name,
Index: gtk/gtkprintunixdialog.c
===================================================================
--- gtk/gtkprintunixdialog.c	(revision 18272)
+++ gtk/gtkprintunixdialog.c	(working copy)
@@ -477,6 +477,53 @@
   gtk_tree_path_free (path);
 }
 
+static gboolean
+request_password_callback (GtkPrintBackend *backend,
+                           const gchar     *hostname,
+                           const gchar     *username,
+                           gpointer         data)
+{
+  GtkPrintUnixDialog *parent = data;
+  GtkWidget *dialog, *box, *label, *prompt, *entry;
+  gchar *text;
+  const gchar *password;
+  gint response;
+  dialog = gtk_dialog_new_with_buttons (_("Password"), (GtkWindow *)parent, 0, 
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                        GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                        NULL);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+  box = gtk_hbox_new (FALSE, 0); 
+  text = g_strdup_printf (_("Please enter the password for %s on %s"), username, hostname);
+  label = gtk_label_new (text);
+  gtk_misc_set_padding (GTK_MISC (label), 12, 0);
+  g_free (text);
+  prompt = gtk_label_new (_("Password:"));
+  entry = gtk_entry_new ();
+  gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
+  gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+   
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, FALSE, FALSE, 12);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, FALSE, FALSE, 12);
+  gtk_box_pack_start (GTK_BOX (box), prompt, FALSE, FALSE, 12);
+  gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 12);
+  gtk_widget_show_all (dialog);
+
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  if (response == GTK_RESPONSE_OK)
+    password = gtk_entry_get_text (GTK_ENTRY (entry));
+  else
+    password = NULL;
+
+  gtk_print_backend_set_password (backend, hostname, username, password);
+
+  gtk_widget_destroy (dialog);
+
+  return TRUE;
+}
+ 
 static void
 printer_list_initialize (GtkPrintUnixDialog *dialog,
 			 GtkPrintBackend    *print_backend)
@@ -501,6 +548,10 @@
 			   (GCallback) printer_status_cb, 
 			   G_OBJECT (dialog), 0);
 
+  g_signal_connect_object (print_backend, "request-password", 
+                           (GCallback) request_password_callback, 
+                           G_OBJECT (dialog), 0);
+
   list = gtk_print_backend_get_printer_list (print_backend);
 
   node = list;
@@ -523,7 +574,10 @@
     priv->print_backends = gtk_print_backend_load_modules ();
 
   for (node = priv->print_backends; node != NULL; node = node->next)
-    printer_list_initialize (dialog, GTK_PRINT_BACKEND (node->data));
+    {
+      GtkPrintBackend *backend = node->data;
+      printer_list_initialize (dialog, backend);
+    }
 }
 
 static void
