Index: config-scripts/cups-gssapi.m4
===================================================================
--- config-scripts/cups-gssapi.m4	(revision 6044)
+++ config-scripts/cups-gssapi.m4	(working copy)
@@ -82,7 +82,30 @@
 	fi
 fi
 
+dnl Default GSS service name...
+AC_ARG_WITH(gssservicename, [  --with-gssservicename         set default gss service name],
+	default_gssservicename="$withval",
+	default_gssservicename="default")
+
+if test x$default_gssservicename != xno; then
+	if test "x$default_gssservicename" = "xdefault"; then
+		case $uname in
+			Darwin*)
+				CUPS_DEFAULT_GSSSERVICENAME="IPP"
+				;;
+			*)
+				CUPS_DEFAULT_GSSSERVICENAME="HTTP"
+				;;
+		esac
+	else
+		CUPS_DEFAULT_GSSSERVICENAME="$default_gssservicename"
+	fi
+else
+	CUPS_DEFAULT_GSSSERVICENAME=""
+fi
+
 AC_SUBST(LIBGSSAPI)
+AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GSSSERVICENAME, "$CUPS_DEFAULT_GSSSERVICENAME")
 
 dnl
 dnl End of "$Id$".
Index: cups/http.c
===================================================================
--- cups/http.c	(revision 6044)
+++ cups/http.c	(working copy)
@@ -272,6 +272,17 @@
   close(http->fd);
 #endif /* WIN32 */
 
+#ifdef HAVE_GSSAPI
+  OM_uint32	minor_status,	/* Minor status code */
+		major_status;	/* Major status code */
+
+  if (http->gssctx != GSS_C_NO_CONTEXT)
+    major_status = gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
+
+  if (http->gssname != GSS_C_NO_NAME)
+    major_status = gss_release_name(&minor_status, &http->gssname);
+#endif /* HAVE_GSSAPI */
+
   httpClearFields(http);
 
   if (http->authstring && http->authstring != http->_authstring)
@@ -350,6 +361,11 @@
   http->activity = time(NULL);
   http->fd       = -1;
 
+#ifdef HAVE_GSSAPI
+  http->gssctx = GSS_C_NO_CONTEXT;
+  http->gssname = GSS_C_NO_NAME;
+#endif /* HAVE_GSSAPI */
+
  /*
   * Set the encryption status...
   */
@@ -2270,6 +2286,20 @@
   httpGetLength2(http);
   httpClearFields(http);
 
+ /*
+  * The kerberos authentication string can only be used once...
+  */
+
+  if (http->authstring && !strncmp(http->authstring, "Negotiate", 9))
+  {
+    http->_authstring[0] = '\0';
+
+    if (http->authstring != http->_authstring)
+      free(http->authstring);
+  
+    http->authstring = http->_authstring;
+  }
+
   return (0);
 }
 
@@ -2504,6 +2534,7 @@
   */
 
   memcpy(&myhttp, http, sizeof(myhttp));
+  myhttp.field_authorization = NULL;
 
  /*
   * Send an OPTIONS request to the server, requiring SSL or TLS
Index: cups/http-support.c
===================================================================
--- cups/http-support.c	(revision 6044)
+++ cups/http-support.c	(working copy)
@@ -595,8 +595,14 @@
 
     if (outptr < outend)
       *outptr ++ = base64[(in[0] & 255) >> 2];
+
     if (outptr < outend)
-      *outptr ++ = base64[(((in[0] & 255) << 4) | ((in[1] & 255) >> 4)) & 63];
+    {
+      if (inlen > 1)
+        *outptr ++ = base64[(((in[0] & 255) << 4) | ((in[1] & 255) >> 4)) & 63];
+      else
+        *outptr ++ = base64[((in[0] & 255) << 4) & 63];
+    }
 
     in ++;
     inlen --;
@@ -610,7 +616,12 @@
     }
 
     if (outptr < outend)
-      *outptr ++ = base64[(((in[0] & 255) << 2) | ((in[1] & 255) >> 6)) & 63];
+    {
+      if (inlen > 1)
+        *outptr ++ = base64[(((in[0] & 255) << 2) | ((in[1] & 255) >> 6)) & 63];
+      else
+        *outptr ++ = base64[((in[0] & 255) << 2) & 63];
+    }
 
     in ++;
     inlen --;
Index: cups/auth.c
===================================================================
--- cups/auth.c	(revision 6044)
+++ cups/auth.c	(working copy)
@@ -168,9 +168,52 @@
 					/* Output token */
 			input_token = GSS_C_EMPTY_BUFFER;
 					/* Input token */
+    char		*gss_service_name;
+					/* GSS service name */
+    const char		*authorization;
+					/* Pointer into Authorization string */
 
 
-    http->gssname = cups_get_gss_creds(http, "HTTP");
+    if (http->gssname == GSS_C_NO_NAME)
+    {
+      if ((gss_service_name = getenv("CUPS_GSSSERVICENAME")) == NULL)
+	gss_service_name = CUPS_DEFAULT_GSSSERVICENAME;
+      else
+	DEBUG_puts("cupsDoAuthentication: GSS service name set via environment");
+
+      http->gssname = cups_get_gss_creds(http, gss_service_name);
+    }
+
+   /*
+    * Find the start of the Kerberos input token...
+    */
+
+    authorization = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
+
+    authorization += 9;
+    while (*authorization && isspace(*authorization & 255))
+      authorization ++;
+
+    if (*authorization)
+    {
+     /*
+      * For SPNEGO, this is where we'll feed the server's authorization data
+      * back into gss via input_token...
+      */
+    }
+    else
+    {
+      if (http->gssctx != GSS_C_NO_CONTEXT)
+      {
+	major_status = gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
+	http->gssctx = GSS_C_NO_CONTEXT;
+      }
+    }
+
     major_status  = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
 					 &http->gssctx,
 					 http->gssname, http->gssmech,
@@ -179,6 +222,9 @@
 					 &input_token, &http->gssmech,
 					 &output_token, NULL, NULL);
 
+    if (input_token.value)
+      free(input_token.value);
+
     if (GSS_ERROR(major_status))
     {
 #  ifdef DEBUG
@@ -193,12 +239,17 @@
       DEBUG_gss_printf(major_status, minor_status, "Continuation needed!");
 #  endif /* DEBUG */
 
-    httpEncode64_2(encode, sizeof(encode), output_token.value,
-                   output_token.length);
+    if (output_token.length)
+    {
+      httpEncode64_2(encode, sizeof(encode), output_token.value,
+		     output_token.length);
 
-    http->authstring = malloc(strlen(encode) + 20);
-    sprintf(http->authstring, "Negotiate %s", encode); /* Safe because allocated */
+      http->authstring = malloc(strlen(encode) + 11);
+      sprintf(http->authstring, "Negotiate %s", encode); /* Safe because allocated */
 
+      major_status = gss_release_buffer(&minor_status, &output_token);
+    }
+
    /*
     * Copy back what we can to _authstring for backwards compatibility...
     */
@@ -310,18 +361,12 @@
 	   httpGetHostname(http, fqdn, sizeof(fqdn)));
 
   token.value  = buf;
-  token.length = strlen(buf) + 1;
+  token.length = strlen(buf);
   server_name  = GSS_C_NO_NAME;
   major_status = gss_import_name(&minor_status, &token,
 	 			 GSS_C_NT_HOSTBASED_SERVICE,
 				 &server_name);
 
- /*
-  * Clear the service token after we are done to avoid exposing information...
-  */
-
-  memset(&token, 0, sizeof(token));
-
   if (GSS_ERROR(major_status))
   {
 #  ifdef DEBUG
Index: config.h.in
===================================================================
--- config.h.in	(revision 6044)
+++ config.h.in	(working copy)
@@ -466,6 +466,13 @@
 #undef HAVE_HEIMDAL
 
 
+/*
+ * Default GSS service name...
+ */
+
+#define CUPS_DEFAULT_GSSSERVICENAME	""
+
+
 #endif /* !_CUPS_CONFIG_H_ */
 
 /*
Index: cgi-bin/Makefile
===================================================================
--- cgi-bin/Makefile	(revision 6044)
+++ cgi-bin/Makefile	(working copy)
@@ -139,7 +139,7 @@
 testcgi:	testcgi.o ../Makedefs libcgi.a ../cups/libcups.a
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o $@ testcgi.o libcgi.a ../cups/libcups.a \
-		$(COMMONLIBS) $(SSLLIBS) $(LIBZ)
+		$(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
 
 
 #
@@ -149,7 +149,7 @@
 testhi:	testhi.o ../Makedefs libcgi.a ../cups/libcups.a
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o $@ testhi.o libcgi.a ../cups/libcups.a \
-		$(COMMONLIBS) $(SSLLIBS) $(LIBZ)
+		$(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
 
 
 #
@@ -159,7 +159,7 @@
 testtemplate:	testtemplate.o ../Makedefs libcgi.a ../cups/libcups.a
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o $@ testtemplate.o libcgi.a ../cups/libcups.a \
-		$(COMMONLIBS) $(SSLLIBS) $(LIBZ)
+		$(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
 
 
 #
Index: scheduler/conf.c
===================================================================
--- scheduler/conf.c	(revision 6044)
+++ scheduler/conf.c	(working copy)
@@ -117,8 +117,10 @@
   { "FilterLimit",		&FilterLimit,		CUPSD_VARTYPE_INTEGER },
   { "FilterNice",		&FilterNice,		CUPSD_VARTYPE_INTEGER },
   { "FontPath",			&FontPath,		CUPSD_VARTYPE_STRING },
-  { "HideImplicitMembers",	&HideImplicitMembers,	CUPSD_VARTYPE_BOOLEAN },
-  { "ImplicitClasses",		&ImplicitClasses,	CUPSD_VARTYPE_BOOLEAN },
+#ifdef HAVE_GSSAPI
+  { "GSSServiceName",		&GSSServiceName,	CUPSD_VARTYPE_STRING },
+#endif /* HAVE_GSSAPI */
+ { "ImplicitClasses",		&ImplicitClasses,	CUPSD_VARTYPE_BOOLEAN },
   { "ImplicitAnyClasses",	&ImplicitAnyClasses,	CUPSD_VARTYPE_BOOLEAN },
   { "JobRetryLimit",		&JobRetryLimit,		CUPSD_VARTYPE_INTEGER },
   { "JobRetryInterval",		&JobRetryInterval,	CUPSD_VARTYPE_INTEGER },
@@ -288,6 +290,9 @@
   cupsdSetString(&RemoteRoot, "remroot");
   cupsdSetString(&ServerHeader, "CUPS/1.2");
   cupsdSetString(&StateDir, CUPS_STATEDIR);
+#ifdef HAVE_GSSAPI
+  cupsdSetString(&GSSServiceName, CUPS_DEFAULT_GSSSERVICENAME);
+#endif /* HAVE_GSSAPI */
 
   if (!strcmp(CUPS_DEFAULT_PRINTCAP, "/etc/printers.conf"))
     PrintcapFormat = PRINTCAP_SOLARIS;
@@ -1706,7 +1711,8 @@
 	loc->level = AUTH_USER;
     }
 #ifdef HAVE_GSSAPI
-    else if (!strcasecmp(value, "kerberos"))
+    else if (!strcasecmp(value, "kerberos") ||
+	     !strcasecmp(value, "gssapi"))
     {
       loc->type = AUTH_KERBEROS;
 
Index: scheduler/ipp.c
===================================================================
--- scheduler/ipp.c	(revision 6044)
+++ scheduler/ipp.c	(working copy)
@@ -7581,6 +7581,7 @@
   OM_uint32	major_status,		/* Major status code */
 		minor_status;		/* Minor status code */
 
+  return;
 
  /*
   * Setup a cached context for the job filters to use...
Index: scheduler/conf.h
===================================================================
--- scheduler/conf.h	(revision 6044)
+++ scheduler/conf.h	(working copy)
@@ -112,6 +112,8 @@
 			*Classification		VALUE(NULL);
 					/* Classification of system */
 #ifdef HAVE_GSSAPI
+VAR char		*GSSServiceName		VALUE(NULL);
+					/* GSS service name */
 VAR char		*Krb5Keytab		VALUE(NULL);
 					/* Kerberos Keytab */
 #endif /* HAVE_GSSAPI */
Index: scheduler/Makefile
===================================================================
--- scheduler/Makefile	(revision 6044)
+++ scheduler/Makefile	(working copy)
@@ -261,7 +261,7 @@
 testlpd:	testlpd.o ../cups/libcups.a cups-lpd
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o testlpd testlpd.o ../cups/libcups.a \
-		$(COMMONLIBS) $(LIBZ) $(SSLLIBS)
+		$(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(LIBGSSAPI)
 
 
 #
@@ -271,7 +271,7 @@
 testmime:	testmime.o libmime.a ../cups/libcups.a
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o $@ testmime.o libmime.a ../cups/libcups.a \
-		$(COMMONLIBS) $(LIBZ) $(SSLLIBS)
+		$(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(LIBGSSAPI)
 
 
 #
@@ -281,7 +281,7 @@
 testspeed:	testspeed.o ../cups/libcups.a
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o testspeed testspeed.o ../cups/libcups.a \
-		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+		$(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(LIBGSSAPI)
 
 
 #
@@ -291,7 +291,7 @@
 testsub:	testsub.o ../cups/libcups.a
 	echo Linking $@...
 	$(CC) $(LDFLAGS) -o testsub testsub.o ../cups/libcups.a \
-		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+		$(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(LIBGSSAPI)
 
 
 #
Index: scheduler/auth.c
===================================================================
--- scheduler/auth.c	(revision 6044)
+++ scheduler/auth.c	(working copy)
@@ -783,7 +783,7 @@
     */
 
     authorization += 9;
-    while (*authorization && isspace(*authorization & 255))
+    while (isspace(*authorization & 255))
       authorization ++;
 
     if (!*authorization)
@@ -797,7 +797,7 @@
     * Get the server credentials...
     */
 
-    if ((server_creds = get_gss_creds("HTTP")) == NULL)
+    if ((server_creds = get_gss_creds(GSSServiceName)) == NULL)
     {
       con->no_negotiate = 1;
       return;	
@@ -836,6 +836,10 @@
       cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
                          "cupsdAuthorize: Error accepting GSSAPI security "
 			 "context");
+
+      if (context != GSS_C_NO_CONTEXT)
+	gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
+
       con->no_negotiate = 1;
       return;
     }
@@ -848,19 +852,22 @@
     {
       major_status = gss_display_name(&minor_status, client_name, 
 				      &output_token, NULL);
-      gss_release_name(&minor_status, &client_name);
 
       if (GSS_ERROR(major_status))
       {
 	cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
                            "cupsdAuthorize: Error getting username");
+	gss_release_name(&minor_status, &client_name);
+	gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
 	con->no_negotiate = 1;
 	return;
       }
 
+      gss_release_name(&minor_status, &client_name);
       strlcpy(username, output_token.value, sizeof(username));
 
       gss_release_buffer(&minor_status, &output_token);
+      gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
     }
     else
       gss_release_name(&minor_status, &client_name);
@@ -1736,9 +1743,11 @@
   * See if encryption is required...
   */
 
-  if (best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls &&
+  if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls &&
       strcasecmp(con->http.hostname, "localhost") &&
-      best->satisfy == AUTH_SATISFY_ALL)
+      best->satisfy == AUTH_SATISFY_ALL) &&
+      !(best->type == AUTH_KERBEROS || 
+        (best->type == AUTH_NONE && DefaultAuthType == AUTH_KERBEROS)))
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsAuthorized: Need upgrade to TLS...");
@@ -2128,7 +2137,7 @@
 	   httpGetHostname(NULL, fqdn, sizeof(fqdn)));
 
   token.value  = buf;
-  token.length = strlen(buf) + 1;
+  token.length = strlen(buf);
   server_name  = GSS_C_NO_NAME;
   major_status = gss_import_name(&minor_status, &token,
 	 			 GSS_C_NT_HOSTBASED_SERVICE,
Index: scheduler/main.c
===================================================================
--- scheduler/main.c	(revision 6044)
+++ scheduler/main.c	(working copy)
@@ -357,8 +357,8 @@
 
   getrlimit(RLIMIT_NOFILE, &limit);
 
-  if (limit.rlim_max > CUPS_MAX_FDS)
-    MaxFDs = CUPS_MAX_FDS;
+  if (limit.rlim_max > FD_SETSIZE)
+    MaxFDs = FD_SETSIZE;
   else
     MaxFDs = limit.rlim_max;
 
