diff -rubwBEN 3.4/configure.ac 3.4-mm/configure.ac
--- 3.4/configure.ac	2013-09-10 23:09:23.110467000 +0100
+++ 3.4-mm/configure.ac	2013-09-21 21:20:13.189998613 +0100
@@ -1907,6 +1907,10 @@
     AC_DEFINE(HAVE_KRB5_GET_ERROR_MESSAGE,1,
       [Define to 1 if you have krb5_get_error_message]),)
   AC_CHECK_DECLS(krb5_kt_free_entry,,,[#include <krb5.h>])
+  AC_CHECK_TYPE(krb5_pac,
+    AC_DEFINE(HAVE_KRB5_PAC,1,
+      [Define to 1 if you have krb5_pac]),,
+      [#include <krb5.h>])
   AC_CHECK_LIB(krb5,krb5_kt_free_entry,
     AC_DEFINE(HAVE_KRB5_KT_FREE_ENTRY,1,
       [Define to 1 if you have krb5_kt_free_entry]),)
@@ -1925,6 +1929,33 @@
   AC_CHECK_LIB(krb5,profile_release,
     AC_DEFINE(HAVE_PROFILE_RELEASE,1,
       [Define to 1 if you have profile_release]),)
+  AC_CHECK_LIB(krb5,krb5_get_renewed_creds,
+    AC_DEFINE(HAVE_KRB5_GET_RENEWED_CREDS,1,
+      [Define to 1 if you have krb5_get_renewed_creds]),)
+  AC_CHECK_LIB(krb5,krb5_principal_get_realm,
+    AC_DEFINE(HAVE_KRB5_PRINCIPAL_GET_REALM,1,
+      [Define to 1 if you have krb5_principal_get_realm]),)
+  AC_CHECK_LIB(krb5, krb5_get_init_creds_opt_alloc,
+    AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC,1,
+      [Define to 1 if you have krb5_get_init_creds_opt_alloc]),)
+  AC_MSG_CHECKING([for krb5_get_init_creds_free requires krb5_context])
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+	#include <krb5.h>
+    ]],[[krb5_context context;
+	 krb5_get_init_creds_opt *options;
+	 krb5_get_init_creds_opt_free(context, options)]])],[
+	AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_FREE_CONTEXT,1,
+		  [Define to 1 if you krb5_get_init_creds_free requires krb5_context])
+	AC_MSG_RESULT(yes)
+    ],[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)])
+
+
+  AC_CHECK_FUNCS(gss_map_name_to_any,
+    AC_DEFINE(HAVE_GSS_MAP_ANY_TO_ANY,1,
+      [Define to 1 if you have gss_map_name_to_any]),)
+  AC_CHECK_FUNCS(gsskrb5_extract_authz_data_from_sec_context,
+    AC_DEFINE(HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT,1,
+      [Define to 1 if you have gsskrb5_extract_authz_data_from_sec_context]),)
 
   SQUID_CHECK_KRB5_CONTEXT_MEMORY_CACHE
   SQUID_DEFINE_BOOL(HAVE_KRB5_MEMORY_CACHE,$squid_cv_memory_cache,
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc	2013-09-22 00:47:09.658819098 +0100
@@ -65,7 +65,7 @@
 
 void clean_gd(struct gdstruct *gdsp);
 void clean_nd(struct ndstruct *ndsp);
-void clean_ls(struct ndstruct *lssp);
+void clean_ls(struct lsstruct *lssp);
 
 void
 clean_gd(struct gdstruct *gdsp)
@@ -78,22 +78,12 @@
             pp = p;
             p = p->next;
         }
-        if (p->group) {
-            xfree(p->group);
-            p->group = NULL;
-        }
-        if (p->domain) {
-            xfree(p->domain);
-            p->domain = NULL;
-        }
-        if (pp && pp->next) {
-            xfree(pp->next);
-            pp->next = NULL;
-        }
-        if (p == gdsp) {
-            xfree(gdsp);
-            gdsp = NULL;
-        }
+        safe_free(p->group);
+        safe_free(p->domain);
+	if (pp)
+            safe_free(pp->next);
+	if (p == gdsp)
+            safe_free(gdsp);
         p = gdsp;
     }
 }
@@ -109,22 +99,12 @@
             pp = p;
             p = p->next;
         }
-        if (p->netbios) {
-            xfree(p->netbios);
-            p->netbios = NULL;
-        }
-        if (p->domain) {
-            xfree(p->domain);
-            p->domain = NULL;
-        }
-        if (pp && pp->next) {
-            xfree(pp->next);
-            pp->next = NULL;
-        }
-        if (p == ndsp) {
-            xfree(ndsp);
-            ndsp = NULL;
-        }
+        safe_free(p->netbios);
+        safe_free(p->domain);
+	if (pp)
+            safe_free(pp->next);
+	if (p == ndsp)
+            safe_free(ndsp);
         p = ndsp;
     }
 }
@@ -140,22 +120,12 @@
             pp = p;
             p = p->next;
         }
-        if (p->lserver) {
-            xfree(p->lserver);
-            p->lserver = NULL;
-        }
-        if (p->domain) {
-            xfree(p->domain);
-            p->domain = NULL;
-        }
-        if (pp && pp->next) {
-            xfree(pp->next);
-            pp->next = NULL;
-        }
-        if (p == lssp) {
-            xfree(lssp);
-            lssp = NULL;
-        }
+        safe_free(p->lserver);
+        safe_free(p->domain);
+	if (pp)
+            safe_free(pp->next);
+	if (p == lssp)
+            safe_free(lssp);
         p = lssp;
     }
 }
@@ -163,50 +133,17 @@
 void
 clean_args(struct main_args *margs)
 {
-    if (margs->glist) {
-        xfree(margs->glist);
-        margs->glist = NULL;
-    }
-    if (margs->ulist) {
-        xfree(margs->ulist);
-        margs->ulist = NULL;
-    }
-    if (margs->tlist) {
-        xfree(margs->tlist);
-        margs->tlist = NULL;
-    }
-    if (margs->nlist) {
-        xfree(margs->nlist);
-        margs->nlist = NULL;
-    }
-    if (margs->llist) {
-        xfree(margs->llist);
-        margs->llist = NULL;
-    }
-    if (margs->luser) {
-        xfree(margs->luser);
-        margs->luser = NULL;
-    }
-    if (margs->lpass) {
-        xfree(margs->lpass);
-        margs->lpass = NULL;
-    }
-    if (margs->lbind) {
-        xfree(margs->lbind);
-        margs->lbind = NULL;
-    }
-    if (margs->lurl) {
-        xfree(margs->lurl);
-        margs->lurl = NULL;
-    }
-    if (margs->ssl) {
-        xfree(margs->ssl);
-        margs->ssl = NULL;
-    }
-    if (margs->ddomain) {
-        xfree(margs->ddomain);
-        margs->ddomain = NULL;
-    }
+    safe_free(margs->glist);
+    safe_free(margs->ulist);
+    safe_free(margs->tlist);
+    safe_free(margs->nlist);
+    safe_free(margs->llist);
+    safe_free(margs->luser);
+    safe_free(margs->lpass);
+    safe_free(margs->lbind);
+    safe_free(margs->lurl);
+    safe_free(margs->ssl);
+    safe_free(margs->ddomain);
     if (margs->groups) {
         clean_gd(margs->groups);
         margs->groups = NULL;
@@ -413,8 +350,8 @@
                 log((char *) "%s| %s: INFO: Got User: %s Netbios Name: %s\n", LogTime(), PROGRAM, up, np);
             domain = get_netbios_name(&margs, netbios);
             user = nuser;
-            xfree(up);
-            xfree(np);
+	    safe_free(up);
+            safe_free(np);
         } else if (domain) {
             strup(domain);
             *domain = '\0';
@@ -436,8 +373,8 @@
         else
             log((char *) "%s| %s: INFO: Got User: %s Domain: %s\n", LogTime(), PROGRAM, up, domain ? dp : "NULL");
 
-        xfree(up);
-        xfree(dp);
+	safe_free(up);
+        safe_free(dp);
         if (!strcmp(user, "QQ") && domain && !strcmp(domain, "QQ")) {
             clean_args(&margs);
             exit(-1);
@@ -477,7 +414,7 @@
 strup(char *s)
 {
     while (*s) {
-        *s = toupper((unsigned char) *s);
+        *s = (char)toupper((unsigned char) *s);
         ++s;
     }
 }
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_group.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_group.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_group.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_group.cc	2013-09-22 01:01:05.906874358 +0100
@@ -31,6 +31,7 @@
 #include "support.h"
 
 struct gdstruct *init_gd(void);
+void free_gd(struct gdstruct *gdsp);
 
 struct gdstruct *
 init_gd(void) {
@@ -59,7 +60,8 @@
 char *
 utf8dup(struct main_args *margs)
 {
-    int c = 0, s;
+    size_t c = 0;
+    unsigned char s;
     size_t n;
     char *src;
     unsigned char *p, *dupp;
@@ -79,7 +81,7 @@
                 *p = 194;
                 ++p;
                 *p = s;
-            } else if (s > 191 && s < 256) {
+            } else if (s > 191) {
                 *p = 195;
                 ++p;
                 *p = s - 64;
@@ -121,7 +123,7 @@
         return NULL;
 
     char *upd = strrchr(up, '@');
-    size_t a = (upd ? (upd - up) : strlen(up) );
+    size_t a = (upd ? (size_t)(upd - up) : strlen(up) );
 
     char *ul = (char *) xmalloc(strlen(up)+1);
     size_t n = 0;
@@ -174,17 +176,17 @@
         if (iUTF2) {
             if (iUTF2 == 0xC2 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF2 = 0;
-                ul[nl - 1] = ichar;
+                ul[nl - 1] = (char)ichar;
             } else if (iUTF2 == 0xC3 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF2 = 0;
-                ul[nl - 1] = ichar + 64;
+                ul[nl - 1] = (char)(ichar + 64);
             } else if (iUTF2 > 0xC3 && iUTF2 < 0xE0 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF2 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else {
                 iUTF2 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ul[nl + 1] = '\0';
                 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
                 xfree(ul);
@@ -193,27 +195,27 @@
         } else if (iUTF3) {
             if (iUTF3 == 0xE0 && ichar > 0x9F && ichar < 0xC0) {
                 iUTF3 = 1;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 > 0xE0 && iUTF3 < 0xED && ichar > 0x7F && ichar < 0xC0) {
                 iUTF3 = 2;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 == 0xED && ichar > 0x7F && ichar < 0xA0) {
                 iUTF3 = 3;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 > 0xED && iUTF3 < 0xF0 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF3 = 4;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 > 0 && iUTF3 < 5 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF3 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else {
                 iUTF3 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ul[nl + 1] = '\0';
                 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
                 xfree(ul);
@@ -222,26 +224,26 @@
         } else if (iUTF4) {
             if (iUTF4 == 0xF0 && ichar > 0x8F && ichar < 0xC0) {
                 iUTF4 = 1;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF4 > 0xF0 && iUTF3 < 0xF4 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF4 = 2;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF4 == 0xF4 && ichar > 0x7F && ichar < 0x90) {
                 iUTF4 = 3;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF4 > 0 && iUTF4 < 5 && ichar > 0x7F && ichar < 0xC0) {
                 if (iUTF4 == 4)
                     iUTF4 = 0;
                 else
                     iUTF4 = 4;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else {
                 iUTF4 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ul[nl + 1] = '\0';
                 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
                 xfree(ul);
@@ -249,25 +251,25 @@
             }
         } else if (ichar < 0x80) {
             /* UTF1 */
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else if (ichar > 0xC1 && ichar < 0xE0) {
             /* UTF2 (Latin) */
             iUTF2 = ichar;
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else if (ichar > 0xDF && ichar < 0xF0) {
             /* UTF3 */
             iUTF3 = ichar;
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else if (ichar > 0xEF && ichar < 0xF5) {
             /* UTF4 */
             iUTF4 = ichar;
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else {
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ul[nl + 1] = '\0';
             debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
             xfree(ul);
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support.h 3.4-mm/helpers/external_acl/kerberos_ldap_group/support.h
--- 3.4/helpers/external_acl/kerberos_ldap_group/support.h	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support.h	2013-09-22 12:42:55.834656998 +0100
@@ -156,13 +156,13 @@
 int create_ls(struct main_args *margs);
 
 #ifdef HAVE_KRB5
-int krb5_create_cache(struct main_args *margs, char *domain);
+int krb5_create_cache(char *domain);
 void krb5_cleanup(void);
 #endif
 
-int get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *domain);
-int get_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *name);
-int free_hostname_list(struct hstruct **hlist, int nhosts);
+size_t get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, size_t nhosts, char *domain);
+size_t get_hostname_list(struct hstruct **hlist, size_t nhosts, char *name);
+size_t free_hostname_list(struct hstruct **hlist, size_t nhosts);
 
 #if defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H) || defined(HAVE_SASL_DARWIN)
 int tool_sasl_bind(LDAP * ld, char *binddn, char *ssl);
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_krb5.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_krb5.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_krb5.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_krb5.cc	2013-09-22 13:53:30.148936803 +0100
@@ -33,7 +33,9 @@
     krb5_context context;
     char *mem_cache_env;
     krb5_ccache cc;
-} kparam;
+};
+
+static struct kstruct kparam;
 
 #define KT_PATH_MAX 256
 
@@ -50,23 +52,20 @@
  * create Kerberos memory cache
  */
 int
-krb5_create_cache(struct main_args *margs, char *domain)
+krb5_create_cache(char *domain)
 {
 
     krb5_keytab keytab = 0;
     krb5_keytab_entry entry;
     krb5_kt_cursor cursor;
     krb5_creds *creds = NULL;
-    krb5_creds *tgt_creds = NULL;
     krb5_principal *principal_list = NULL;
     krb5_principal principal = NULL;
     char *service;
     char *keytab_name = NULL, *principal_name = NULL, *mem_cache = NULL;
     char buf[KT_PATH_MAX], *p;
-    int nprinc = 0;
-    int i;
+    size_t j,nprinc = 0;
     int retval = 0;
-    int found = 0;
     krb5_error_code code = 0;
 
     kparam.context = NULL;
@@ -112,6 +111,7 @@
 
     nprinc = 0;
     while ((code = krb5_kt_next_entry(kparam.context, keytab, &entry, &cursor)) == 0) {
+        int found = 0;
 
         principal_list = (krb5_principal *) xrealloc(principal_list, sizeof(krb5_principal) * (nprinc + 1));
         krb5_copy_principal(kparam.context, entry.principal, &principal_list[nprinc++]);
@@ -182,12 +182,14 @@
      * if no principal name found in keytab for domain use the prinipal name which can get a TGT
      */
     if (!principal_name) {
+        size_t i;
         debug((char *) "%s| %s: DEBUG: Did not find a principal in keytab for domain %s.\n", LogTime(), PROGRAM, domain);
         debug((char *) "%s| %s: DEBUG: Try to get principal of trusted domain.\n", LogTime(), PROGRAM);
-        creds = (krb5_creds *) xmalloc(sizeof(*creds));
-        memset(creds, 0, sizeof(*creds));
 
         for (i = 0; i < nprinc; ++i) {
+            krb5_creds *tgt_creds = NULL;
+            creds = (krb5_creds *) xmalloc(sizeof(*creds));
+            memset(creds, 0, sizeof(*creds));
             /*
              * get credentials
              */
@@ -205,7 +207,6 @@
             snprintf(service, strlen("krbtgt") + 2 * strlen(domain) + 3, "krbtgt/%s@%s", domain, domain);
             creds->client = principal_list[i];
             code = krb5_parse_name(kparam.context, service, &creds->server);
-            if (service)
                 xfree(service);
             code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0);
 #endif
@@ -233,7 +234,6 @@
             snprintf(service, strlen("krbtgt") + strlen(domain) + strlen(krb5_princ_realm(kparam.context, principal_list[i])->data) + 3, "krbtgt/%s@%s", domain, krb5_princ_realm(kparam.context, principal_list[i])->data);
 #endif
             code = krb5_parse_name(kparam.context, service, &creds->server);
-            if (service)
                 xfree(service);
             if (code) {
                 error((char *) "%s| %s: ERROR: Error while initialising TGT credentials : %s\n", LogTime(), PROGRAM, error_message(code));
@@ -245,19 +245,22 @@
                 goto loop_end;
             } else {
                 debug((char *) "%s| %s: DEBUG: Found trusted principal name: %s\n", LogTime(), PROGRAM, principal_name);
-                found = 1;
                 break;
             }
 
 loop_end:
-            if (principal_name)
-                xfree(principal_name);
-            principal_name = NULL;
-        }
-
-        if (tgt_creds)
+            safe_free(principal_name);
+	    if (tgt_creds) {
             krb5_free_creds(kparam.context, tgt_creds);
         tgt_creds = NULL;
+	    }
+	    if (creds)
+		krb5_free_creds(kparam.context, creds);
+            creds = NULL;
+
+        }
+
+        safe_free(principal_name);
         if (creds)
             krb5_free_creds(kparam.context, creds);
         creds = NULL;
@@ -287,7 +290,6 @@
         snprintf(service, strlen("krbtgt") + 2 * strlen(domain) + 3, "krbtgt/%s@%s", domain, domain);
         creds->client = principal;
         code = krb5_parse_name(kparam.context, service, &creds->server);
-        if (service)
             xfree(service);
         code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0);
 #endif
@@ -316,19 +318,15 @@
 cleanup:
     if (keytab)
         krb5_kt_close(kparam.context, keytab);
-    if (keytab_name)
         xfree(keytab_name);
-    if (principal_name)
         xfree(principal_name);
-    if (mem_cache)
         xfree(mem_cache);
     if (principal)
         krb5_free_principal(kparam.context, principal);
-    for (i = 0; i < nprinc; ++i) {
-        if (principal_list[i])
-            krb5_free_principal(kparam.context, principal_list[i]);
+    for (j = 0; j < nprinc; ++j) {
+        if (principal_list[j])
+            krb5_free_principal(kparam.context, principal_list[j]);
     }
-    if (principal_list)
         xfree(principal_list);
     if (creds)
         krb5_free_creds(kparam.context, creds);
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_ldap.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_ldap.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_ldap.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_ldap.cc	2013-09-22 13:42:10.642891901 +0100
@@ -35,7 +35,7 @@
 char *convert_domain_to_bind_path(char *domain);
 char *escape_filter(char *filter);
 int check_AD(struct main_args *margs, LDAP * ld);
-int ldap_set_defaults(struct main_args *margs, LDAP * ld);
+int ldap_set_defaults(LDAP * ld);
 int ldap_set_ssl_defaults(struct main_args *margs);
 LDAP *tool_ldap_open(struct main_args *margs, char *host, int port, char *ssl);
 
@@ -51,7 +51,7 @@
 #define FILTER_AD "(samaccountname=%s)"
 #define ATTRIBUTE_AD "memberof"
 
-int get_attributes(struct main_args *margs, LDAP * ld, LDAPMessage * res, const char *attribute /* IN */ , char ***out_val /* OUT (caller frees) */ );
+size_t get_attributes(LDAP * ld, LDAPMessage * res, const char *attribute /* IN */ , char ***out_val /* OUT (caller frees) */ );
 int search_group_tree(struct main_args *margs, LDAP * ld, char *bindp, char *ldap_group, char *group, int depth);
 
 #if defined(HAVE_SUN_LDAP_SDK) || defined(HAVE_MOZILLA_LDAP_SDK)
@@ -210,7 +210,7 @@
 convert_domain_to_bind_path(char *domain)
 {
     char *dp, *bindp = NULL, *bp = NULL;
-    int i = 0;
+    size_t i = 0;
 
     if (!domain)
         return NULL;
@@ -243,8 +243,8 @@
 char *
 escape_filter(char *filter)
 {
-    int i;
     char *ldap_filter_esc, *ldf;
+    size_t i;
 
     i = 0;
     for (ldap_filter_esc = filter; *ldap_filter_esc; ++ldap_filter_esc) {
@@ -278,7 +278,7 @@
     *ldf = '\0';
 
     return ldap_filter_esc;
-};
+}
 
 int
 check_AD(struct main_args *margs, LDAP * ld)
@@ -286,8 +286,8 @@
     LDAPMessage *res;
     char **attr_value = NULL;
     struct timeval searchtime;
-    int max_attr = 0;
-    int j, rc = 0;
+    size_t max_attr = 0;
+    int rc = 0;
 
 #define FILTER_SCHEMA "(objectclass=*)"
 #define ATTRIBUTE_SCHEMA "schemaNamingContext"
@@ -301,7 +301,7 @@
                            NULL, NULL, &searchtime, 0, &res);
 
     if (rc == LDAP_SUCCESS)
-        max_attr = get_attributes(margs, ld, res, ATTRIBUTE_SCHEMA, &attr_value);
+        max_attr = get_attributes(ld, res, ATTRIBUTE_SCHEMA, &attr_value);
 
     if (max_attr == 1) {
         ldap_msgfree(res);
@@ -318,11 +318,11 @@
      * Cleanup
      */
     if (attr_value) {
+        size_t j;
         for (j = 0; j < max_attr; ++j) {
             xfree(attr_value[j]);
         }
-        xfree(attr_value);
-        attr_value = NULL;
+        safe_free(attr_value);
     }
     ldap_msgfree(res);
     return rc;
@@ -332,11 +332,11 @@
 {
     LDAPMessage *res = NULL;
     char **attr_value = NULL;
-    int max_attr = 0;
+    size_t max_attr = 0;
     char *filter = NULL;
     char *search_exp = NULL;
-    int j, rc = 0, retval = 0;
-    char *av = NULL, *avp = NULL;
+    size_t j;
+    int rc = 0, retval = 0;
     int ldepth;
     char *ldap_filter_esc = NULL;
     struct timeval searchtime;
@@ -378,9 +378,9 @@
     debug((char *) "%s| %s: DEBUG: Found %d ldap entr%s\n", LogTime(), PROGRAM, ldap_count_entries(ld, res), ldap_count_entries(ld, res) > 1 || ldap_count_entries(ld, res) == 0 ? "ies" : "y");
 
     if (margs->AD)
-        max_attr = get_attributes(margs, ld, res, ATTRIBUTE_AD, &attr_value);
+        max_attr = get_attributes(ld, res, ATTRIBUTE_AD, &attr_value);
     else
-        max_attr = get_attributes(margs, ld, res, ATTRIBUTE, &attr_value);
+        max_attr = get_attributes(ld, res, ATTRIBUTE, &attr_value);
 
     /*
      * Compare group names
@@ -388,10 +388,12 @@
     retval = 0;
     ldepth = depth + 1;
     for (j = 0; j < max_attr; ++j) {
+        char *av = NULL;
 
         /* Compare first CN= value assuming it is the same as the group name itself */
         av = attr_value[j];
         if (!strncasecmp("CN=", av, 3)) {
+            char *avp = NULL;
             av += 3;
             if ((avp = strchr(av, ','))) {
                 *avp = '\0';
@@ -399,17 +401,17 @@
         }
         if (debug_enabled) {
             int n;
-            debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, j + 1, av);
+            debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, j + 1, av);
             for (n = 0; av[n] != '\0'; ++n)
                 fprintf(stderr, "%02x", (unsigned char) av[n]);
             fprintf(stderr, "\n");
         }
         if (!strcasecmp(group, av)) {
             retval = 1;
-            debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
+            debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
             break;
         } else
-            debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
+            debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
         /*
          * Do recursive group search
          */
@@ -418,13 +420,14 @@
         if (search_group_tree(margs, ld, bindp, av, group, ldepth)) {
             retval = 1;
             if (!strncasecmp("CN=", av, 3)) {
+                char *avp = NULL;
                 av += 3;
                 if ((avp = strchr(av, ','))) {
                     *avp = '\0';
                 }
             }
             if (debug_enabled)
-                debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" is member of group named \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
+                debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" is member of group named \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
             else
                 break;
 
@@ -438,8 +441,7 @@
         for (j = 0; j < max_attr; ++j) {
             xfree(attr_value[j]);
         }
-        xfree(attr_value);
-        attr_value = NULL;
+        safe_free(attr_value);
     }
     ldap_msgfree(res);
 
@@ -447,7 +449,7 @@
 }
 
 int
-ldap_set_defaults(struct main_args *margs, LDAP * ld)
+ldap_set_defaults(LDAP * ld)
 {
     int val, rc = 0;
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
@@ -484,14 +486,14 @@
 #endif
 #ifdef HAVE_OPENLDAP
     int val;
-    char *ssl_cacertfile = NULL;
-    int free_path;
 #elif defined(HAVE_LDAPSSL_CLIENT_INIT)
     char *ssl_certdbpath = NULL;
 #endif
 
 #ifdef HAVE_OPENLDAP
     if (!margs->rc_allow) {
+        char *ssl_cacertfile = NULL;
+        int free_path;
         debug((char *) "%s| %s: DEBUG: Enable server certificate check for ldap server.\n", LogTime(), PROGRAM);
         val = LDAP_OPT_X_TLS_DEMAND;
         rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &val);
@@ -509,7 +511,6 @@
         rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ssl_cacertfile);
         if (ssl_cacertfile && free_path) {
             xfree(ssl_cacertfile);
-            ssl_cacertfile = NULL;
         }
         if (rc != LDAP_OPT_SUCCESS) {
             error((char *) "%s| %s: ERROR: Error while setting LDAP_OPT_X_TLS_CACERTFILE for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
@@ -543,10 +544,7 @@
         rc = ldapssl_advclientauth_init(ssl_certdbpath, NULL, 0, NULL, NULL, 0, NULL, 0);
         debug((char *) "%s| %s: DEBUG: Disable server certificate check for ldap server.\n", LogTime(), PROGRAM);
     }
-    if (ssl_certdbpath) {
         xfree(ssl_certdbpath);
-        ssl_certdbpath = NULL;
-    }
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error while setting SSL for ldap server: %s\n", LogTime(), PROGRAM, ldapssl_err2string(rc));
         return rc;
@@ -557,13 +555,13 @@
     return LDAP_SUCCESS;
 }
 
-int
-get_attributes(struct main_args *margs, LDAP * ld, LDAPMessage * res, const char *attribute, char ***ret_value)
+size_t
+get_attributes(LDAP * ld, LDAPMessage * res, const char *attribute, char ***ret_value)
 {
 
     LDAPMessage *msg;
     char **attr_value = NULL;
-    int max_attr = 0;
+    size_t max_attr = 0;
 
     attr_value = *ret_value;
     /*
@@ -588,15 +586,15 @@
                     if ((values = ldap_get_values_len(ld, msg, attr)) != NULL) {
                         for (il = 0; values[il] != NULL; ++il) {
 
-                            attr_value = (char **) xrealloc(attr_value, (il + 1) * sizeof(char *));
+                            attr_value = (char **) xrealloc(attr_value, (max_attr + 1) * sizeof(char *));
                             if (!attr_value)
                                 break;
 
-                            attr_value[il] = (char *) xmalloc(values[il]->bv_len + 1);
-                            memcpy(attr_value[il], values[il]->bv_val, values[il]->bv_len);
-                            attr_value[il][values[il]->bv_len] = 0;
+                            attr_value[max_attr] = (char *) xmalloc(values[il]->bv_len + 1);
+                            memcpy(attr_value[max_attr], values[il]->bv_val, values[il]->bv_len);
+                            attr_value[max_attr][values[il]->bv_len] = 0;
+                            max_attr++;
                         }
-                        max_attr = il;
                     }
                     ber_bvecfree(values);
                 }
@@ -615,7 +613,7 @@
         }
     }
 
-    debug((char *) "%s| %s: DEBUG: %d ldap entr%s found with attribute : %s\n", LogTime(), PROGRAM, max_attr, max_attr > 1 || max_attr == 0 ? "ies" : "y", attribute);
+    debug((char *) "%s| %s: DEBUG: %ld ldap entr%s found with attribute : %s\n", LogTime(), PROGRAM, max_attr, max_attr > 1 || max_attr == 0 ? "ies" : "y", attribute);
 
     *ret_value = attr_value;
     return max_attr;
@@ -661,13 +659,13 @@
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error while parsing url: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
         xfree(ldapuri);
-        xfree(url);
+        ldap_free_urldesc(url);
         return NULL;
     }
 #else
 #error "No URL parsing function"
 #endif
-    safe_free(url);
+    ldap_free_urldesc(url);
     rc = ldap_initialize(&ld, ldapuri);
     xfree(ldapuri);
     if (rc != LDAP_SUCCESS) {
@@ -679,7 +677,7 @@
 #else
     ld = ldap_init(host, port);
 #endif
-    rc = ldap_set_defaults(margs, ld);
+    rc = ldap_set_defaults(ld);
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
         ldap_unbind(ld);
@@ -726,13 +724,13 @@
             if (rc != LDAP_SUCCESS) {
                 error((char *) "%s| %s: ERROR: Error while parsing url: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
                 xfree(ldapuri);
-                xfree(url);
+                ldap_free_urldesc(url);
                 return NULL;
             }
 #else
 #error "No URL parsing function"
 #endif
-            safe_free(url);
+            ldap_free_urldesc(url);
             rc = ldap_initialize(&ld, ldapuri);
             xfree(ldapuri);
             if (rc != LDAP_SUCCESS) {
@@ -741,7 +739,7 @@
                 ld = NULL;
                 return NULL;
             }
-            rc = ldap_set_defaults(margs, ld);
+            rc = ldap_set_defaults(ld);
             if (rc != LDAP_SUCCESS) {
                 error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
                 ldap_unbind(ld);
@@ -757,7 +755,7 @@
             ld = NULL;
             return NULL;
         }
-        rc = ldap_set_defaults(margs, ld);
+        rc = ldap_set_defaults(ld);
         if (rc != LDAP_SUCCESS) {
             error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
             ldap_unbind(ld);
@@ -787,18 +785,12 @@
     char *filter = NULL;
     char *search_exp;
     struct timeval searchtime;
-    int i, j, rc = 0, kc = 1;
+    int rc = 0, kc = 1;
     int retval;
     char **attr_value = NULL;
-    char *av = NULL, *avp = NULL;
-    int max_attr = 0;
+    size_t max_attr = 0;
     struct hstruct *hlist = NULL;
-    int nhosts = 0;
-    char *hostname;
-    char *host;
-    int port;
-    char *ssl = NULL;
-    char *p;
+    size_t nhosts = 0;
     char *ldap_filter_esc = NULL;
 
     searchtime.tv_sec = SEARCH_TIMEOUT;
@@ -810,7 +802,7 @@
         debug((char *) "%s| %s: DEBUG: Setup Kerberos credential cache\n", LogTime(), PROGRAM);
 
 #ifdef HAVE_KRB5
-        kc = krb5_create_cache(margs, domain);
+        kc = krb5_create_cache(domain);
         if (kc) {
             error((char *) "%s| %s: ERROR: Error during setup of Kerberos credential cache\n", LogTime(), PROGRAM);
         }
@@ -839,6 +831,7 @@
     debug((char *) "%s| %s: DEBUG: Initialise ldap connection\n", LogTime(), PROGRAM);
 
     if (domain && !kc) {
+        size_t i;
         if (margs->ssl) {
             debug((char *) "%s| %s: DEBUG: Enable SSL to ldap servers\n", LogTime(), PROGRAM);
         }
@@ -848,7 +841,7 @@
          */
         nhosts = get_ldap_hostname_list(margs, &hlist, 0, domain);
         for (i = 0; i < nhosts; ++i) {
-            port = 389;
+            int port = 389;
             if (hlist[i].port != -1)
                 port = hlist[i].port;
             debug((char *) "%s| %s: DEBUG: Setting up connection to ldap server %s:%d\n", LogTime(), PROGRAM, hlist[i].host, port);
@@ -893,6 +886,12 @@
         bindp = convert_domain_to_bind_path(domain);
     }
     if ((!domain || !ld) && margs->lurl && strstr(margs->lurl, "://")) {
+        char *hostname;
+        char *host;
+        int port;
+        char *ssl = NULL;
+        char *p;
+        size_t i;
         /*
          * If username does not contain a domain and a url was given then try it
          */
@@ -912,8 +911,8 @@
             ++p;
             port = atoi(p);
         }
-        nhosts = get_hostname_list(margs, &hlist, 0, host);
-        safe_free(host);
+        nhosts = get_hostname_list(&hlist, 0, host);
+        xfree(host);
         for (i = 0; i < nhosts; ++i) {
 
             ld = tool_ldap_open(margs, hlist[i].host, port, ssl);
@@ -995,22 +994,25 @@
     debug((char *) "%s| %s: DEBUG: Found %d ldap entr%s\n", LogTime(), PROGRAM, ldap_count_entries(ld, res), ldap_count_entries(ld, res) > 1 || ldap_count_entries(ld, res) == 0 ? "ies" : "y");
 
     if (ldap_count_entries(ld, res) != 0) {
+        size_t k;
 
         if (margs->AD)
-            max_attr = get_attributes(margs, ld, res, ATTRIBUTE_AD, &attr_value);
+            max_attr = get_attributes(ld, res, ATTRIBUTE_AD, &attr_value);
         else {
-            max_attr = get_attributes(margs, ld, res, ATTRIBUTE, &attr_value);
+            max_attr = get_attributes(ld, res, ATTRIBUTE, &attr_value);
         }
 
         /*
          * Compare group names
          */
         retval = 0;
-        for (j = 0; j < max_attr; ++j) {
+        for (k = 0; k < max_attr; ++k) {
+            char *av = NULL;
 
             /* Compare first CN= value assuming it is the same as the group name itself */
-            av = attr_value[j];
+            av = attr_value[k];
             if (!strncasecmp("CN=", av, 3)) {
+                char *avp = NULL;
                 av += 3;
                 if ((avp = strchr(av, ','))) {
                     *avp = '\0';
@@ -1018,7 +1020,7 @@
             }
             if (debug_enabled) {
                 int n;
-                debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, j + 1, av);
+                debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, k + 1, av);
                 for (n = 0; av[n] != '\0'; ++n)
                     fprintf(stderr, "%02x", (unsigned char) av[n]);
                 fprintf(stderr, "\n");
@@ -1026,32 +1028,35 @@
             if (!strcasecmp(group, av)) {
                 retval = 1;
                 if (debug_enabled)
-                    debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
+                    debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, k + 1, av, group);
                 else
                     break;
             } else
-                debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
+                debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, k + 1, av, group);
         }
         /*
          * Do recursive group search for AD only since posixgroups can not contain other groups
          */
         if (!retval && margs->AD) {
+	    size_t j;
             if (debug_enabled && max_attr > 0) {
                 debug((char *) "%s| %s: DEBUG: Perform recursive group search\n", LogTime(), PROGRAM);
             }
             for (j = 0; j < max_attr; ++j) {
+                char *av = NULL;
 
                 av = attr_value[j];
                 if (search_group_tree(margs, ld, bindp, av, group, 1)) {
                     retval = 1;
                     if (!strncasecmp("CN=", av, 3)) {
+                        char *avp = NULL;
                         av += 3;
                         if ((avp = strchr(av, ','))) {
                             *avp = '\0';
                         }
                     }
                     if (debug_enabled)
-                        debug((char *) "%s| %s: DEBUG: Entry %d group \"%s\" is (in)direct member of group \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
+                        debug((char *) "%s| %s: DEBUG: Entry %ld group \"%s\" is (in)direct member of group \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group);
                     else
                         break;
                 }
@@ -1061,11 +1066,11 @@
          * Cleanup
          */
         if (attr_value) {
+	    size_t j;
             for (j = 0; j < max_attr; ++j) {
                 xfree(attr_value[j]);
             }
-            xfree(attr_value);
-            attr_value = NULL;
+            safe_free(attr_value);
         }
         ldap_msgfree(res);
     } else if (ldap_count_entries(ld, res) == 0 && margs->AD) {
@@ -1101,11 +1106,11 @@
 
         debug((char *) "%s| %s: DEBUG: Found %d ldap entr%s\n", LogTime(), PROGRAM, ldap_count_entries(ld, res), ldap_count_entries(ld, res) > 1 || ldap_count_entries(ld, res) == 0 ? "ies" : "y");
 
-        max_attr = get_attributes(margs, ld, res, ATTRIBUTE_GID, &attr_value);
+        max_attr = get_attributes(ld, res, ATTRIBUTE_GID, &attr_value);
 
         if (max_attr == 1) {
             char **attr_value_2 = NULL;
-            int max_attr_2 = 0;
+            size_t max_attr_2 = 0;
 
             ldap_msgfree(res);
             filter = (char *) FILTER_GID;
@@ -1123,7 +1128,7 @@
                                    NULL, NULL, &searchtime, 0, &res);
             xfree(search_exp);
 
-            max_attr_2 = get_attributes(margs, ld, res, ATTRIBUTE, &attr_value_2);
+            max_attr_2 = get_attributes(ld, res, ATTRIBUTE, &attr_value_2);
             /*
              * Compare group names
              */
@@ -1129,9 +1134,8 @@
              */
             retval = 0;
             if (max_attr_2 == 1) {
-
                 /* Compare first CN= value assuming it is the same as the group name itself */
-                av = attr_value_2[0];
+                char *av = attr_value_2[0];
                 if (!strcasecmp(group, av)) {
                     retval = 1;
                     debug((char *) "%s| %s: DEBUG: \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, av, group);
@@ -1143,11 +1147,11 @@
              * Cleanup
              */
             if (attr_value_2) {
+		size_t j;
                 for (j = 0; j < max_attr_2; ++j) {
                     xfree(attr_value_2[j]);
                 }
-                xfree(attr_value_2);
-                attr_value_2 = NULL;
+                safe_free(attr_value_2);
             }
             ldap_msgfree(res);
 
@@ -1161,11 +1165,11 @@
          * Cleanup
          */
         if (attr_value) {
+	    size_t j;
             for (j = 0; j < max_attr; ++j) {
                 xfree(attr_value[j]);
             }
-            xfree(attr_value);
-            attr_value = NULL;
+            safe_free(attr_value);
         }
     }
     rc = ldap_unbind(ld);
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_log.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_log.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_log.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_log.cc	2013-09-22 12:56:14.502709775 +0100
@@ -34,13 +34,13 @@
 const char *
 LogTime()
 {
-    struct tm *tm;
-    struct timeval now;
     static time_t last_t = 0;
+    struct timeval now;
     static char buf[128];
 
     gettimeofday(&now, NULL);
     if (now.tv_sec != last_t) {
+        struct tm *tm;
         time_t tmp = now.tv_sec;
         tm = localtime(&tmp);
         strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_lserver.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_lserver.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_lserver.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_lserver.cc	2013-09-22 01:34:06.390005229 +0100
@@ -29,6 +29,7 @@
 
 #include "support.h"
 struct lsstruct *init_ls(void);
+void free_ls(struct lsstruct *lssp);
 
 struct lsstruct *
 init_ls(void) {
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_netbios.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_netbios.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_netbios.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_netbios.cc	2013-09-22 01:01:46.521877042 +0100
@@ -30,6 +30,7 @@
 #include "support.h"
 
 struct ndstruct *init_nd(void);
+void free_nd(struct ndstruct *ndsp);
 
 struct ndstruct *
 init_nd(void) {
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_resolv.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_resolv.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_resolv.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_resolv.cc	2013-09-22 13:11:12.079769087 +0100
@@ -95,10 +95,10 @@
 sort(struct hstruct *array, int nitems, int (*cmp) (struct hstruct *, struct hstruct *), int begin, int end)
 {
     if (end > begin) {
-        int pivot = begin;
         int l = begin + 1;
         int r = end;
         while (l < r) {
+            int pivot = begin;
             if (cmp(&array[l], &array[pivot]) <= 0) {
                 l += 1;
             } else {
@@ -116,7 +116,7 @@
 static void
 msort(struct hstruct *array, size_t nitems, int (*cmp) (struct hstruct *, struct hstruct *))
 {
-    sort(array, nitems, cmp, 0, nitems - 1);
+    sort(array, (int)nitems, cmp, 0, (int)(nitems - 1));
 }
 
 static int
@@ -145,33 +145,25 @@
     return 0;
 }
 
-int
-free_hostname_list(struct hstruct **hlist, int nhosts)
+size_t
+free_hostname_list(struct hstruct **hlist, size_t nhosts)
 {
     struct hstruct *hp = NULL;
-    int i;
+    size_t i;
 
     hp = *hlist;
     for (i = 0; i < nhosts; ++i) {
-        if (hp[i].host)
             xfree(hp[i].host);
-        hp[i].host = NULL;
     }
 
-    if (hp)
-        xfree(hp);
-    hp = NULL;
+    safe_free(hp);
     *hlist = hp;
     return 0;
 }
 
-int
-get_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *name)
+size_t
+get_hostname_list(struct hstruct **hlist, size_t nhosts, char *name)
 {
-    /*
-     * char host[sysconf(_SC_HOST_NAME_MAX)];
-     */
-    char host[1024];
     struct addrinfo *hres = NULL, *hres_list;
     int rc, count;
     struct hstruct *hp = NULL;
@@ -194,6 +186,10 @@
     hres_list = hres;
     count = 0;
     while (hres_list) {
+        /*
+         * char host[sysconf(_SC_HOST_NAME_MAX)];
+         */
+        char host[1024];
         rc = getnameinfo(hres_list->ai_addr, hres_list->ai_addrlen, host, sizeof(host), NULL, 0, 0);
         if (rc != 0) {
             error((char *) "%s| %s: ERROR: Error while resolving ip address with getnameinfo: %s\n", LogTime(), PROGRAM, gai_strerror(rc));
@@ -219,24 +215,21 @@
     return (nhosts);
 }
 
-int
-get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nh, char *domain)
+size_t
+get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, size_t nh, char *domain)
 {
 
     /*
      * char name[sysconf(_SC_HOST_NAME_MAX)];
      */
     char name[1024];
-    char host[NS_MAXDNAME];
     char *service = NULL;
     struct hstruct *hp = NULL;
     struct lsstruct *ls = NULL;
-    int nhosts = 0;
+    size_t nhosts = 0;
     int size;
-    int type, rdlength;
-    int priority, weight, port;
     int len, olen;
-    int i, j, k;
+    size_t i, j, k;
     u_char *buffer = NULL;
     u_char *p;
 
@@ -305,7 +298,7 @@
     }
     if (len > PACKETSZ_MULT * NS_PACKETSZ) {
         olen = len;
-        buffer = (u_char *) xrealloc(buffer, len);
+        buffer = (u_char *) xrealloc(buffer, (size_t)len);
         if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, len)) < 0) {
             error((char *) "%s| %s: ERROR: Error while resolving service record %s with res_search\n", LogTime(), PROGRAM, service);
             nsError(h_errno, service);
@@ -322,7 +315,7 @@
         error((char *) "%s| %s: ERROR: Message to small: %d < header size\n", LogTime(), PROGRAM, len);
         goto finalise;
     }
-    if ((size = dn_expand(buffer, buffer + len, p, name, sysconf(_SC_HOST_NAME_MAX))) < 0) {
+    if ((size = dn_expand(buffer, buffer + len, p, name, sizeof(name))) < 0) {
         error((char *) "%s| %s: ERROR: Error while expanding query name with dn_expand:  %s\n", LogTime(), PROGRAM, strerror(errno));
         goto finalise;
     }
@@ -333,7 +326,8 @@
         goto finalise;
     }
     while (p < buffer + len) {
-        if ((size = dn_expand(buffer, buffer + len, p, name, sysconf(_SC_HOST_NAME_MAX))) < 0) {
+        int type, rdlength;
+        if ((size = dn_expand(buffer, buffer + len, p, name, sizeof(name))) < 0) {
             error((char *) "%s| %s: ERROR: Error while expanding answer name with dn_expand:  %s\n", LogTime(), PROGRAM, strerror(errno));
             goto finalise;
         }
@@ -351,6 +345,8 @@
         NS_GET16(rdlength, p);	/* RR data length (16bit) */
 
         if (type == ns_t_srv) {	/* SRV record */
+            int priority, weight, port;
+            char host[NS_MAXDNAME];
             if (p > buffer + len) {
                 error((char *) "%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name + RR type,class,ttl + RR data length\n", LogTime(), PROGRAM, len);
                 goto finalise;
@@ -400,7 +396,7 @@
     }
 
 finalise:
-    nhosts = get_hostname_list(margs, &hp, nh, domain);
+    nhosts = get_hostname_list(&hp, nh, domain);
 
     debug("%s| %s: DEBUG: Adding %s to list\n", LogTime(), PROGRAM, domain);
 
@@ -435,7 +431,7 @@
     }
 
     /* Sort by Priority / Weight */
-    msort(hp, nhosts, compare_hosts);
+    msort(hp, (size_t)nhosts, compare_hosts);
 
     if (debug_enabled) {
         debug((char *) "%s| %s: DEBUG: Sorted ldap server names for domain %s:\n", LogTime(), PROGRAM, domain);
@@ -443,9 +439,7 @@
             debug((char *) "%s| %s: DEBUG: Host: %s Port: %d Priority: %d Weight: %d\n", LogTime(), PROGRAM, hp[i].host, hp[i].port, hp[i].priority, hp[i].weight);
         }
     }
-    if (buffer)
         xfree(buffer);
-    if (service)
         xfree(service);
     *hlist = hp;
     return (nhosts);
diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_sasl.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_sasl.cc
--- 3.4/helpers/external_acl/kerberos_ldap_group/support_sasl.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_sasl.cc	2013-09-21 21:22:39.146008258 +0100
@@ -196,17 +196,11 @@
 {
     lutilSASLdefaults *defs = (lutilSASLdefaults *) defaults;
 
-    if (defs->mech)
         xfree(defs->mech);
-    if (defs->realm)
         xfree(defs->realm);
-    if (defs->authcid)
         xfree(defs->authcid);
-    if (defs->passwd)
         xfree(defs->passwd);
-    if (defs->authzid)
         xfree(defs->authzid);
-    if (defs->resps)
         xfree(defs->resps);
 
     xfree(defs);
diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/Makefile.am 3.4-mm/helpers/negotiate_auth/kerberos/Makefile.am
--- 3.4/helpers/negotiate_auth/kerberos/Makefile.am	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/negotiate_auth/kerberos/Makefile.am	2013-09-21 21:21:03.306001925 +0100
@@ -7,7 +7,7 @@
 
 AM_CPPFLAGS = $(INCLUDES) -I$(srcdir)
 
-negotiate_kerberos_auth_SOURCES = negotiate_kerberos_auth.cc
+negotiate_kerberos_auth_SOURCES = negotiate_kerberos_auth.cc negotiate_kerberos_pac.cc
 negotiate_kerberos_auth_LDFLAGS = 
 negotiate_kerberos_auth_LDADD = \
 	$(top_builddir)/lib/libmiscencoding.la \
diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc
--- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc	2013-09-22 00:39:08.281787289 +0100
@@ -36,79 +36,7 @@
 
 #if HAVE_GSSAPI
 
-#if HAVE_STRING_H
-#include <string.h>
-#endif
-#if HAVE_STDOI_H
-#include <stdio.h>
-#endif
-#if HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_TIME_H
-#include <time.h>
-#endif
-
-#include "util.h"
-#include "base64.h"
-
-#if HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif HAVE_GSSAPI_H
-#include <gssapi.h>
-#endif
-
-#if !HAVE_HEIMDAL_KERBEROS
-#if HAVE_GSSAPI_GSSAPI_KRB5_H
-#include <gssapi/gssapi_krb5.h>
-#endif
-#if HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-#if HAVE_GSSAPI_GSSAPI_EXT_H
-#include <gssapi/gssapi_ext.h>
-#endif
-#endif
-
-#ifndef gss_nt_service_name
-#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
-#endif
-
-#define PROGRAM "negotiate_kerberos_auth"
-
-#ifndef MAX_AUTHTOKEN_LEN
-#define MAX_AUTHTOKEN_LEN   65535
-#endif
-#ifndef SQUID_KERB_AUTH_VERSION
-#define SQUID_KERB_AUTH_VERSION "3.0.4sq"
-#endif
-
-int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
-                  const char *function, int log);
-char *gethost_name(void);
-static const char *LogTime(void);
-
-static const unsigned char ntlmProtocol[] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0};
-
-static const char *
-LogTime()
-{
-    struct tm *tm;
-    struct timeval now;
-    static time_t last_t = 0;
-    static char buf[128];
-
-    gettimeofday(&now, NULL);
-    if (now.tv_sec != last_t) {
-        tm = localtime((time_t *) & now.tv_sec);
-        strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
-        last_t = now.tv_sec;
-    }
-    return buf;
-}
+#include "negotiate_kerberos.h"
 
 char *
 gethost_name(void)
@@ -155,7 +83,7 @@
 
 int
 check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
-              const char *function, int log)
+              const char *function, int log, int sout)
 {
     if (GSS_ERROR(major_status)) {
         OM_uint32 maj_stat, min_stat;
@@ -198,6 +126,7 @@
             gss_release_buffer(&min_stat, &status_string);
         } while (msg_ctx);
         debug((char *) "%s| %s: ERROR: %s failed: %s\n", LogTime(), PROGRAM, function, buf);
+	if (sout)
         fprintf(stdout, "BH %s failed: %s\n", function, buf);
         if (log)
             fprintf(stderr, "%s| %s: INFO: User not authenticated\n", LogTime(),
@@ -213,7 +142,20 @@
     char buf[MAX_AUTHTOKEN_LEN];
     char *c, *p;
     char *user = NULL;
-    int length = 0;
+    char *rfc_user = NULL;
+#if HAVE_PAC_SUPPORT
+    char ad_groups[MAX_PAC_GROUP_SIZE];
+    char *ag=NULL;
+    krb5_context context = NULL;
+    krb5_error_code ret;
+    krb5_pac pac;
+#if HAVE_HEIMDAL_KERBEROS
+    gss_buffer_desc data_set = GSS_C_EMPTY_BUFFER;
+#else
+    gss_buffer_desc type_id = GSS_C_EMPTY_BUFFER;
+#endif
+#endif
+    long length = 0;
     static int err = 0;
     int opt, log = 0, norealm = 0;
     OM_uint32 ret_flags = 0, spnego_flag = 0;
@@ -284,6 +226,7 @@
         snprintf((char *) service.value, strlen(service_name) + strlen(host_name) + 2,
                  "%s@%s", service_name, host_name);
         service.length = strlen((char *) service.value);
+        xfree(host_name);
     }
 
     while (1) {
@@ -312,7 +255,7 @@
             err = 0;
             continue;
         }
-        debug((char *) "%s| %s: DEBUG: Got '%s' from squid (length: %d).\n", LogTime(), PROGRAM, buf, length);
+        debug((char *) "%s| %s: DEBUG: Got '%s' from squid (length: %ld).\n", LogTime(), PROGRAM, buf, length);
 
         if (buf[0] == '\0') {
             debug((char *) "%s| %s: ERROR: Invalid request\n", LogTime(), PROGRAM);
@@ -338,23 +281,14 @@
             if (kerberosToken) {
                 /* Allocated by parseNegTokenInit, but no matching free function exists.. */
                 if (!spnego_flag)
-                    xfree((char *) kerberosToken);
-                kerberosToken = NULL;
+                    xfree(kerberosToken);
             }
             if (spnego_flag) {
                 /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
                 if (spnegoToken)
-                    xfree((char *) spnegoToken);
-                spnegoToken = NULL;
+                    xfree(spnegoToken);
             }
-            if (token) {
                 xfree(token);
-                token = NULL;
-            }
-            if (host_name) {
-                xfree(host_name);
-                host_name = NULL;
-            }
             fprintf(stdout, "BH quit command\n");
             exit(0);
         }
@@ -373,12 +307,12 @@
             fprintf(stdout, "BH Invalid negotiate request\n");
             continue;
         }
-        input_token.length = base64_decode_len(buf+3);
+        input_token.length = (size_t)base64_decode_len(buf+3);
         debug((char *) "%s| %s: DEBUG: Decode '%s' (decoded length: %d).\n",
               LogTime(), PROGRAM, buf + 3, (int) input_token.length);
         input_token.value = xmalloc(input_token.length);
 
-        input_token.length = base64_decode((char *) input_token.value, input_token.length, buf+3);
+        input_token.length = (size_t)base64_decode((char *) input_token.value, (unsigned int)input_token.length, buf+3);
 
         if ((input_token.length >= sizeof ntlmProtocol + 1) &&
                 (!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
@@ -399,19 +333,20 @@
             } else {
                 server_name = GSS_C_NO_NAME;
                 major_status = GSS_S_COMPLETE;
+                minor_status = 0;
             }
         } else {
             major_status = gss_import_name(&minor_status, &service,
                                            gss_nt_service_name, &server_name);
         }
 
-        if (check_gss_err(major_status, minor_status, "gss_import_name()", log))
+        if (check_gss_err(major_status, minor_status, "gss_import_name()", log, 1))
             goto cleanup;
 
         major_status =
             gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
                              GSS_C_NO_OID_SET, GSS_C_ACCEPT, &server_creds, NULL, NULL);
-        if (check_gss_err(major_status, minor_status, "gss_acquire_cred()", log))
+        if (check_gss_err(major_status, minor_status, "gss_acquire_cred()", log, 1))
             goto cleanup;
 
         major_status = gss_accept_sec_context(&minor_status,
@@ -424,16 +359,16 @@
         if (output_token.length) {
             spnegoToken = (const unsigned char *) output_token.value;
             spnegoTokenLength = output_token.length;
-            token = (char *) xmalloc(base64_encode_len(spnegoTokenLength));
+            token = (char *) xmalloc((size_t)base64_encode_len((int)spnegoTokenLength));
             if (token == NULL) {
                 debug((char *) "%s| %s: ERROR: Not enough memory\n", LogTime(), PROGRAM);
                 fprintf(stdout, "BH Not enough memory\n");
                 goto cleanup;
             }
-            base64_encode_str(token, base64_encode_len(spnegoTokenLength),
-                              (const char *) spnegoToken, spnegoTokenLength);
+            base64_encode_str(token, base64_encode_len((int)spnegoTokenLength),
+                              (const char *) spnegoToken, (int)spnegoTokenLength);
 
-            if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log))
+            if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log, 1))
                 goto cleanup;
             if (major_status & GSS_S_CONTINUE_NEEDED) {
                 debug((char *) "%s| %s: INFO: continuation needed\n", LogTime(), PROGRAM);
@@ -445,7 +380,7 @@
                 gss_display_name(&minor_status, client_name, &output_token,
                                  NULL);
 
-            if (check_gss_err(major_status, minor_status, "gss_display_name()", log))
+            if (check_gss_err(major_status, minor_status, "gss_display_name()", log, 1))
                 goto cleanup;
             user = (char *) xmalloc(output_token.length + 1);
             if (user == NULL) {
@@ -458,14 +393,49 @@
             if (norealm && (p = strchr(user, '@')) != NULL) {
                 *p = '\0';
             }
+
+#if HAVE_PAC_SUPPORT
+	    ret = krb5_init_context(&context);
+	    if (!check_k5_err(context, "krb5_init_context", ret)) {
+#if HAVE_HEIMDAL_KERBEROS
+#define ADWIN2KPAC 128
+		major_status = gsskrb5_extract_authz_data_from_sec_context(&minor_status, 
+				gss_context, ADWIN2KPAC, &data_set);
+		if (!check_gss_err(major_status, minor_status, 
+				"gsskrb5_extract_authz_data_from_sec_context()", log, 0)) {
+		    ret = krb5_pac_parse(context, data_set.value, data_set.length, &pac);
+		    gss_release_buffer(&minor_status, &data_set);
+		    if (!check_k5_err(context, "krb5_pac_parse", ret)) {
+			ag = get_ad_groups((char *)&ad_groups, context, pac);
+			krb5_pac_free(context, pac);
+		    }
+		    krb5_free_context(context);
+		}
+#else
+		type_id.value = (void *)"mspac";
+		type_id.length = strlen((char *)type_id.value);
+#define KRB5PACLOGONINFO        1 
+		major_status = gss_map_name_to_any(&minor_status, client_name, KRB5PACLOGONINFO, &type_id, (gss_any_t *)&pac);
+		if (!check_gss_err(major_status, minor_status, "gss_map_name_to_any()", log, 0)) {
+		    ag = get_ad_groups((char *)&ad_groups,context, pac);
+		}
+		(void)gss_release_any_name_mapping(&minor_status, client_name, &type_id, (gss_any_t *)&pac);
+		krb5_free_context(context);
+#endif
+	    }
+	    if (ag) {
+		debug((char *) "%s| %s: DEBUG: Groups %s\n", LogTime(), PROGRAM, ag);
+	    }
+#endif
             fprintf(stdout, "AF %s %s\n", token, user);
-            debug((char *) "%s| %s: DEBUG: AF %s %s\n", LogTime(), PROGRAM, token, rfc1738_escape(user));
+	    rfc_user = rfc1738_escape(user);
+            debug((char *) "%s| %s: DEBUG: AF %s %s\n", LogTime(), PROGRAM, token, rfc_user);
             if (log)
                 fprintf(stderr, "%s| %s: INFO: User %s authenticated\n", LogTime(),
                         PROGRAM, rfc1738_escape(user));
             goto cleanup;
         } else {
-            if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log))
+            if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log, 1))
                 goto cleanup;
             if (major_status & GSS_S_CONTINUE_NEEDED) {
                 debug((char *) "%s| %s: INFO: continuation needed\n", LogTime(), PROGRAM);
@@ -477,7 +447,7 @@
                 gss_display_name(&minor_status, client_name, &output_token,
                                  NULL);
 
-            if (check_gss_err(major_status, minor_status, "gss_display_name()", log))
+            if (check_gss_err(major_status, minor_status, "gss_display_name()", log, 1))
                 goto cleanup;
             /*
              *  Return dummy token AA. May need an extra return tag then AF
@@ -511,23 +481,15 @@
         if (kerberosToken) {
             /* Allocated by parseNegTokenInit, but no matching free function exists.. */
             if (!spnego_flag)
-                xfree((char *) kerberosToken);
-            kerberosToken = NULL;
+                safe_free(kerberosToken);
         }
         if (spnego_flag) {
             /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
             if (spnegoToken)
-                xfree((char *) spnegoToken);
-            spnegoToken = NULL;
-        }
-        if (token) {
-            xfree(token);
-            token = NULL;
-        }
-        if (user) {
-            xfree(user);
-            user = NULL;
+                safe_free(spnegoToken);
         }
+        safe_free(token);
+        safe_free(user);
         continue;
     }
 }
diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc
--- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc	2013-09-22 00:39:15.520787767 +0100
@@ -196,9 +196,9 @@
         goto cleanup;
 
     if (output_token.length) {
-        token = (char *) xmalloc(base64_encode_len(output_token.length));
-        base64_encode_str(token, base64_encode_len(output_token.length),
-                          (const char *) output_token.value, output_token.length);
+        token = (char *) xmalloc((size_t)base64_encode_len((int)output_token.length));
+        base64_encode_str(token, base64_encode_len((int)output_token.length),
+                          (const char *) output_token.value, (int)output_token.length);
     }
 cleanup:
     gss_delete_sec_context(&minor_status, &gss_context, NULL);
diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos.h 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos.h
--- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos.h	1970-01-01 01:00:00.000000000 +0100
+++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos.h	2013-09-22 00:38:53.197786292 +0100
@@ -0,0 +1,156 @@
+/*
+ * -----------------------------------------------------------------------------
+ *
+ * Author: Markus Moeller (markus_moeller at compuserve.com)
+ *
+ * Copyright (C) 2013 Markus Moeller. All rights reserved.
+ *
+ *   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
+ *   (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., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *   As a special exemption, M Moeller gives permission to link this program
+ *   with MIT, Heimdal or other GSS/Kerberos libraries, and distribute
+ *   the resulting executable, without including the source code for
+ *   the Libraries in the source distribution.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include "util.h"
+#include "base64.h"
+
+#if HAVE_KRB5_H
+#if HAVE_BROKEN_SOLARIS_KRB5_H
+#warn "Warning! You have a broken Solaris <krb5.h> system header"
+#warn "http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6837512"
+#if defined(__cplusplus)
+#define KRB5INT_BEGIN_DECLS     extern "C" {
+#define KRB5INT_END_DECLS
+KRB5INT_BEGIN_DECLS
+#endif
+#endif /* HAVE_BROKEN_SOLARIS_KRB5_H */
+#if HAVE_BROKEN_HEIMDAL_KRB5_H
+extern "C" {
+#include <krb5.h>
+}
+#else
+#include <krb5.h>
+#endif
+#endif /* HAVE_KRB5_H */
+
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif
+
+#if !HAVE_HEIMDAL_KERBEROS
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif
+#if HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif
+#if HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif
+#else
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif
+#endif
+
+#ifndef gss_nt_service_name
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#endif
+
+#define PROGRAM "negotiate_kerberos_auth"
+
+#ifndef MAX_AUTHTOKEN_LEN
+#define MAX_AUTHTOKEN_LEN   65535
+#endif
+#ifndef SQUID_KERB_AUTH_VERSION
+#define SQUID_KERB_AUTH_VERSION "3.0.4sq"
+#endif
+
+char *gethost_name(void);
+
+static const char *LogTime(void);
+
+static const unsigned char ntlmProtocol[] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0};
+
+static const char *
+LogTime()
+{
+    struct tm *tm;
+    struct timeval now;
+    static time_t last_t = 0;
+    static char buf[128];
+
+    gettimeofday(&now, NULL);
+    if (now.tv_sec != last_t) {
+        tm = localtime((time_t *) & now.tv_sec);
+        strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+        last_t = now.tv_sec;
+    }
+    return buf;
+}
+
+int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
+                  const char *function, int log, int sout);
+
+char *gethost_name(void);
+
+#if (defined(HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT) || defined(HAVE_GSS_MAP_NAME_TO_ANY)) && HAVE_KRB5_PAC
+#define HAVE_PAC_SUPPORT 1
+#define MAX_PAC_GROUP_SIZE 200*60
+typedef struct {
+    uint16_t length;
+    uint16_t maxlength;
+    uint32_t pointer;
+} RPC_UNICODE_STRING;
+
+int check_k5_err(krb5_context context, const char *msg, krb5_error_code code);
+void align(int n);
+void getustr(RPC_UNICODE_STRING *string);
+char **getgids(char **Rids, uint32_t GroupIds, uint32_t GroupCount);
+char *getdomaingids(char *ad_groups, uint32_t DomainLogonId, char **Rids, uint32_t  GroupCount);
+char *getextrasids(char *ad_groups, uint32_t ExtraSids, uint32_t SidCount);
+uint64_t get6byt_be(void);
+uint32_t get4byt(void);
+uint16_t get2byt(void);
+uint8_t get1byt(void);
+char *xstrcpy( char *src, const char*dst);
+char *xstrcat( char *src, const char*dst);
+int checkustr(RPC_UNICODE_STRING *string);
+char *get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac);
+#else
+#define HAVE_PAC_SUPPORT 0
+#endif
diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc
--- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc	1970-01-01 01:00:00.000000000 +0100
+++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc	2013-09-22 00:39:23.494788294 +0100
@@ -0,0 +1,455 @@
+/*
+ * -----------------------------------------------------------------------------
+ *
+ * Author: Markus Moeller (markus_moeller at compuserve.com)
+ *
+ * Copyright (C) 2007 Markus Moeller. All rights reserved.
+ *
+ *   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
+ *   (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., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *   As a special exemption, M Moeller gives permission to link this program
+ *   with MIT, Heimdal or other GSS/Kerberos libraries, and distribute
+ *   the resulting executable, without including the source code for
+ *   the Libraries in the source distribution.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "squid.h"
+#include "rfc1738.h"
+#include "compat/getaddrinfo.h"
+#include "compat/getnameinfo.h"
+
+#include "negotiate_kerberos.h"
+
+#if HAVE_PAC_SUPPORT
+
+static int bpos;
+static krb5_data *ad_data;
+static unsigned char *p;
+
+int
+check_k5_err(krb5_context context, const char *function, krb5_error_code code)
+{
+    const char *errmsg;
+
+    if (code) {
+	errmsg = krb5_get_error_message(context, code);
+        debug((char *) "%s| %s: ERROR: %s failed: %s\n", LogTime(), PROGRAM, function, errmsg);
+	fprintf(stderr, "%s| %s: ERROR: %s: %s\n", LogTime(), PROGRAM, function, errmsg);
+	krb5_free_error_message(context, errmsg);
+    }
+    return code;
+}
+
+void
+align(int n){
+    if ( bpos % n != 0 ) {
+	int al;
+	al = (bpos/n);
+	bpos = bpos+(bpos-n*al);
+    }
+}
+
+void
+getustr(RPC_UNICODE_STRING *string) {
+
+    string->length = (uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8));
+    string->maxlength = (uint16_t)((p[bpos+2]<<0) | (p[bpos+2+1]<<8));
+    string->pointer = (uint32_t)((p[bpos+4]<<0) | (p[bpos+4+1]<<8) | (p[bpos+4+2]<<16) | (p[bpos+4+3]<<24));
+    bpos = bpos+8;
+
+}
+
+uint64_t
+get6byt_be(void) {
+    uint64_t var;
+
+    var = ((uint64_t)p[bpos+5]<<0) | ((uint64_t)p[bpos+4]<<8) | ((uint64_t)p[bpos+3]<<16) | ((uint64_t)p[bpos+2]<<24) | ((uint64_t)p[bpos+1]<<32) | ((uint64_t)p[bpos]<<40);
+    bpos = bpos+6;
+
+    return var;
+}
+
+uint32_t
+get4byt(void) {
+    uint32_t var;
+
+    var=(uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
+    bpos = bpos+4;
+
+    return var;
+}
+
+uint16_t 
+get2byt(void) {
+    uint16_t var;
+
+    var=(uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8)); 
+    bpos = bpos+2;
+
+    return var;
+}
+
+uint8_t
+get1byt(void) {
+    uint8_t var;
+
+    var=(uint8_t)((p[bpos]<<0));
+    bpos = bpos+1;
+
+    return var;
+}
+
+char *
+xstrcpy( char *src, const char *dst) {
+    if (dst) {
+	if (strlen(dst)>MAX_PAC_GROUP_SIZE)
+	    return NULL;
+	else
+	    return strcpy(src,dst);
+    } else
+	return src;
+}
+
+char *
+xstrcat( char *src, const char *dst) {
+    if (dst) {
+        if (strlen(src)+strlen(dst)+1>MAX_PAC_GROUP_SIZE)
+            return NULL;
+        else
+            return strcat(src,dst);
+    } else
+	return src;
+}
+
+
+int
+checkustr(RPC_UNICODE_STRING *string) {
+    uint32_t size,off,len;
+
+    if (string->pointer != 0){
+	align(4);
+	size = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
+	bpos = bpos+4;
+	off = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
+	bpos = bpos+4;
+	len = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
+	bpos = bpos+4;
+	if (len > size || off != 0 || 
+	    string->length > string->maxlength || len != string->length/2) {
+	    debug((char *) "%s| %s: ERROR: RPC_UNICODE_STRING encoding error => size: %d len: %d/%d maxlength: %d offset: %d\n", 
+		    LogTime(), PROGRAM, size, len, string->length, string->maxlength, off);
+	    return -1;
+	}
+	/* UNICODE string */
+	bpos = bpos+string->length;
+    }
+    return 0;
+}
+
+char **
+getgids(char **Rids, uint32_t GroupIds, uint32_t  GroupCount) {
+    if (GroupIds!= 0){
+        uint32_t ngroup;
+        uint32_t sauth;
+        int l;
+
+        align(4);
+        ngroup = get4byt();
+        if ( ngroup != GroupCount) {
+            debug((char *) "%s| %s: ERROR: Group encoding error => GroupCount: %d Array size: %d\n",
+                                LogTime(), PROGRAM, GroupCount, ngroup);
+            return NULL;
+        }
+        debug((char *) "%s| %s: INFO: Found %d rids\n", LogTime(), PROGRAM, GroupCount);
+
+	Rids=(char **)xcalloc(GroupCount*sizeof(char*),1);
+        for ( l=0; l<(int)GroupCount; l++) {
+	    Rids[l]=(char *)xcalloc(4*sizeof(char),1);
+            memcpy((void *)Rids[l],(void *)&p[bpos],4); 
+            sauth = get4byt();
+	    debug((char *) "%s| %s: Info: Got rid: %u\n", LogTime(), PROGRAM, sauth);
+	    /* attribute */
+            bpos = bpos+4; 
+        }
+    }
+    return Rids;
+}
+
+char *
+getdomaingids(char *ad_groups, uint32_t DomainLogonId, char **Rids, uint32_t GroupCount) {
+    if (DomainLogonId!= 0) {
+        uint32_t nauth;
+        uint8_t rev;
+        uint64_t idauth;
+        uint32_t sauth;
+	char dli[256];
+	char *ag;
+        size_t length;
+        int l;
+
+        align(4);
+
+        nauth = get4byt();
+	
+	/* prepend rids with DomainID */
+        length=1+1+6+nauth*4;
+	for (l=0; l<(int)GroupCount;l++){
+	    ag=(char *)xcalloc((length+4)*sizeof(char),1);
+	    memcpy((void *)ag,(const void*)&p[bpos],1);
+	    memcpy((void *)&ag[1],(const void*)&p[bpos+1],1);
+	    ag[1] = ag[1]+1;
+	    memcpy((void *)&ag[2],(const void*)&p[bpos+2],6+nauth*4);
+	    memcpy((void *)&ag[length],(const void*)Rids[l],4);
+	    if (l==0) {
+		if (!xstrcpy(ad_groups,"group=")) {
+		    debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", 
+				LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
+		}
+	    } else {
+		if (!xstrcat(ad_groups," group=")) {
+                    debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", 
+                                LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
+		}
+	    }
+	    if (!xstrcat(ad_groups,base64_encode_bin(ag, (int)(length+4)))) {
+                    debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", 
+                                LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
+	    }
+	    xfree(ag);
+	}
+
+	/* mainly for debug only */
+        rev = get1byt();
+        bpos = bpos + 1; /*nsub*/
+        idauth = get6byt_be();
+
+	snprintf(dli,sizeof(dli),"S-%d-%lu",rev,(long unsigned int)idauth);	
+        for ( l=0;l<(int)nauth;l++ ) {
+            sauth = get4byt();
+	    snprintf((char *)&dli[strlen(dli)],sizeof(dli)-strlen(dli),"-%u",sauth);	
+        }
+        debug((char *) "%s| %s: INFO: Got DomainLogonId %s\n", LogTime(), PROGRAM, dli); 
+    }
+    return ad_groups;
+}
+
+char *
+getextrasids(char *ad_groups, uint32_t ExtraSids, uint32_t SidCount) {
+    if (ExtraSids!= 0){
+        uint32_t ngroup;
+	uint32_t *pa;
+	char *ag;
+        size_t length;
+        int l;
+
+        align(4);
+        ngroup = get4byt();
+        if ( ngroup != SidCount) {
+            debug((char *) "%s| %s: ERROR: Group encoding error => SidCount: %d Array size: %d\n",
+                                LogTime(), PROGRAM, SidCount, ngroup);
+	    return NULL;
+        }
+        debug((char *) "%s| %s: INFO: Found %d ExtraSIDs\n", LogTime(), PROGRAM, SidCount);
+
+	pa=(uint32_t *)xmalloc(SidCount*sizeof(uint32_t));
+        for ( l=0; l < (int)SidCount; l++ ){
+            pa[l] = get4byt();
+            bpos = bpos+4; /* attr */
+        }
+        
+        for ( l=0; l<(int)SidCount; l++ ){
+	    char es[256];
+            uint32_t nauth;
+            uint8_t rev;
+            uint64_t idauth;
+            uint32_t sauth;
+            int k;
+            
+	    if (pa[l] != 0){
+		nauth = get4byt();
+
+		length = 1+1+6+nauth*4;
+		ag = (char *)xcalloc((length)*sizeof(char),1);
+		memcpy((void *)ag,(const void*)&p[bpos],length);
+		if (!ad_groups) {
+		    if (!xstrcpy(ad_groups,"group=")) {
+			debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", 
+                                	LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
+		    }
+		} else {
+		    if (!xstrcat(ad_groups," group=")) {
+			debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
+					LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
+		    }
+		}
+		if (!xstrcat(ad_groups,base64_encode_bin(ag, (int)length))) {
+                    debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
+                                LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
+		}
+		xfree(ag);
+
+		rev = get1byt();
+		bpos = bpos + 1; /* nsub */
+		idauth = get6byt_be();
+
+		snprintf(es,sizeof(es),"S-%d-%lu",rev,(long unsigned int)idauth);	
+		for ( k=0;k<(int)nauth;k++ ) {
+		    sauth = get4byt();
+		    snprintf((char *)&es[strlen(es)],sizeof(es)-strlen(es),"-%u",sauth);	
+		}
+		debug((char *) "%s| %s: INFO: Got ExtraSid %s\n", LogTime(), PROGRAM, es); 
+	    }
+        }
+	xfree(pa);
+    }
+    return ad_groups;
+}
+
+char *
+get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac){
+    krb5_error_code ret;
+    RPC_UNICODE_STRING EffectiveName;
+    RPC_UNICODE_STRING FullName;
+    RPC_UNICODE_STRING LogonScript;
+    RPC_UNICODE_STRING ProfilePath;
+    RPC_UNICODE_STRING HomeDirectory;
+    RPC_UNICODE_STRING HomeDirectoryDrive;
+    RPC_UNICODE_STRING LogonServer;
+    RPC_UNICODE_STRING LogonDomainName;
+    uint32_t GroupCount=0;
+    uint32_t GroupIds=0;
+    uint32_t LogonDomainId=0;
+    uint32_t SidCount=0;
+    uint32_t ExtraSids=0;
+    /*
+    uint32_t ResourceGroupDomainSid=0;
+    uint32_t ResourceGroupCount=0;
+    uint32_t ResourceGroupIds=0;
+    */
+    char **Rids=NULL;
+    int l=0;
+
+    ad_data = (krb5_data *)xmalloc(sizeof(krb5_data));
+
+#define KERB_LOGON_INFO 1
+    ret = krb5_pac_get_buffer(context, pac, KERB_LOGON_INFO, ad_data);
+    if (check_k5_err(context, "krb5_pac_get_buffer", ret)) 
+	goto k5clean;
+    
+    p = (unsigned char *)ad_data->data;
+
+    debug((char *) "%s| %s: INFO: Got PAC data of lengh %d\n", 
+		    LogTime(), PROGRAM, (int)ad_data->length);
+
+    /* Skip 16 bytes icommon RPC header
+     * Skip 4 bytes RPC unique pointer referent
+     * http://msdn.microsoft.com/en-gb/library/cc237933.aspx
+     */
+    /* Some data are pointers to data which follows the main KRB5 LOGON structure => 
+     *         So need to read the data 
+     * some logical consistency checks are done when analysineg the pointer data
+     */
+    bpos = 20;
+    /* 8 bytes LogonTime
+     * 8 bytes LogoffTime
+     * 8 bytes KickOffTime
+     * 8 bytes PasswordLastSet
+     * 8 bytes PasswordCanChange
+     * 8 bytes PasswordMustChange
+     */
+    bpos = bpos+48;
+    getustr(&EffectiveName);
+    getustr(&FullName);
+    getustr(&LogonScript);
+    getustr(&ProfilePath);
+    getustr(&HomeDirectory);
+    getustr(&HomeDirectoryDrive);
+    /* 2 bytes LogonCount
+     * 2 bytes BadPasswordCount
+     * 4 bytes UserID
+     * 4 bytes PrimaryGroupId
+     */
+    bpos = bpos+12;
+    GroupCount = get4byt();
+    GroupIds = get4byt();
+    /* 4 bytes UserFlags
+     * 16 bytes UserSessionKey
+     */
+    bpos = bpos+20;
+    getustr(&LogonServer);
+    getustr(&LogonDomainName);
+    LogonDomainId = get4byt();
+    /* 8 bytes Reserved1
+     * 4 bytes UserAccountControl
+     * 4 bytes SubAuthStatus
+     * 8 bytes LastSuccessfullLogon
+     * 8 bytes LastFailedLogon
+     * 4 bytes FailedLogonCount
+     * 4 bytes Reserved2
+     */
+    bpos = bpos+40;
+    SidCount = get4byt();
+    ExtraSids = get4byt();
+    /* 4 bytes ResourceGroupDomainSid
+     * 4 bytes ResourceGroupCount
+     * 4 bytes ResourceGroupIds
+     */
+    bpos = bpos+12;
+    /* 
+     * Read all data from structure => Now check pointers
+     */
+    if (checkustr(&EffectiveName)<0)
+	goto k5clean;
+    if (checkustr(&FullName)<0)
+	goto k5clean;
+    if (checkustr(&LogonScript)<0)
+	goto k5clean;
+    if (checkustr(&ProfilePath)<0)
+	goto k5clean;
+    if (checkustr(&HomeDirectory)<0)
+	goto k5clean;
+    if (checkustr(&HomeDirectoryDrive)<0)
+	goto k5clean;
+    Rids = getgids(Rids,GroupIds,GroupCount);
+    if (checkustr(&LogonServer)<0)
+	goto k5clean;
+    if (checkustr(&LogonDomainName)<0)
+	goto k5clean;
+    ad_groups = getdomaingids(ad_groups,LogonDomainId,Rids,GroupCount);
+    if ((ad_groups = getextrasids(ad_groups,ExtraSids,SidCount))==NULL)
+        goto k5clean;
+    
+    debug((char *) "%s| %s: INFO: Read %d of %d bytes \n", LogTime(), PROGRAM, bpos, (int)ad_data->length);
+    if (Rids) {
+        for ( l=0; l<(int)GroupCount; l++) {
+	    xfree(Rids[l]);
+        }
+        xfree(Rids);
+    }
+    krb5_free_data(context, ad_data);
+    return ad_groups; 
+k5clean:
+    if (Rids) {
+        for ( l=0; l<(int)GroupCount; l++) {
+	    xfree(Rids[l]);
+        }
+        xfree(Rids);
+    }
+    krb5_free_data(context, ad_data);
+    return NULL;
+}
+#endif
diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh 3.4-mm/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh
--- 3.4/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh	1970-01-01 01:00:00.000000000 +0100
+++ 3.4-mm/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh	2013-09-21 21:23:25.897011347 +0100
@@ -0,0 +1,7 @@
+#!/bin/bash
+if [[ -z "$1" ]]; then
+	echo "Need squid hostname"
+	exit 0
+fi
+dir=`dirname $0`
+$dir/negotiate_kerberos_auth_test $1 | awk '{sub(/Token:/,"YR"); print $0}END{print "QQ"}' | $dir/negotiate_kerberos_auth -d
diff -rubwBEN 3.4/src/peer_proxy_negotiate_auth.cc 3.4-mm/src/peer_proxy_negotiate_auth.cc
--- 3.4/src/peer_proxy_negotiate_auth.cc	2013-08-26 22:02:02.226038000 +0100
+++ 3.4-mm/src/peer_proxy_negotiate_auth.cc	2013-09-21 21:20:41.093000457 +0100
@@ -210,21 +210,29 @@
         static krb5_keytab_entry entry;
         static krb5_kt_cursor cursor;
         static krb5_creds *creds = NULL;
-#if HAVE_HEIMDAL_KERBEROS
+#if defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_KRB5_GET_RENEWED_CREDS)
         static krb5_creds creds2;
 #endif
         static krb5_principal principal = NULL;
         static krb5_deltat skew;
 
+#if HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+        krb5_get_init_creds_opt *options;
+#else
         krb5_get_init_creds_opt options;
+#endif
         krb5_error_code code = 0;
         krb5_deltat rlife;
 #if HAVE_PROFILE_H && HAVE_KRB5_GET_PROFILE && HAVE_PROFILE_GET_INTEGER && HAVE_PROFILE_RELEASE
         profile_t profile;
 #endif
-#if HAVE_HEIMDAL_KERBEROS
+#if defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_KRB5_GET_RENEWED_CREDS)
         krb5_kdc_flags flags;
-        krb5_realm *client_realm;
+#if HAVE_KRB5_PRINCIPAL_GET_REALM
+        const char *client_realm;
+#else
+        krb5_realm client_realm;
+#endif
 #endif
         char *mem_cache;
 
@@ -236,7 +244,7 @@
                 (creds->times.endtime - time(0) > skew) &&
                 (creds->times.renew_till - time(0) > 2 * skew)) {
             if (creds->times.endtime - time(0) < 2 * skew) {
-#if !HAVE_HEIMDAL_KERBEROS
+#if HAVE_KRB5_GET_RENEWED_CREDS
                 /* renew ticket */
                 code =
                     krb5_get_renewed_creds(kparam.context, creds, principal,
@@ -256,10 +264,15 @@
                            << error_message(code));
                     return (1);
                 }
+#if HAVE_KRB5_PRINCIPAL_GET_REALM
+                client_realm = krb5_principal_get_realm(kparam.context, principal);
+#else
                 client_realm = krb5_princ_realm(kparam.context, creds2.client);
+#endif
                 code =
                     krb5_make_principal(kparam.context, &creds2.server,
-                                        *client_realm, KRB5_TGS_NAME, *client_realm, NULL);
+                                        (krb5_const_realm)&client_realm, KRB5_TGS_NAME, 
+				 	(krb5_const_realm)&client_realm, NULL);
                 if (code) {
                     debugs(11, 5,
                            HERE << "Error while getting krbtgt principal : " <<
@@ -400,7 +413,11 @@
 
             creds = (krb5_creds *) xmalloc(sizeof(*creds));
             memset(creds, 0, sizeof(*creds));
+#if HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+	    krb5_get_init_creds_opt_alloc(kparam.context, &options);
+#else
             krb5_get_init_creds_opt_init(&options);
+#endif
             code = krb5_string_to_deltat((char *) MAX_RENEW_TIME, &rlife);
             if (code != 0 || rlife == 0) {
                 debugs(11, 5,
@@ -408,8 +425,18 @@
                        " : " << error_message(code));
                 return (1);
             }
+#if HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+            krb5_get_init_creds_opt_set_renew_life(options, rlife);
+            code =
+                krb5_get_init_creds_keytab(kparam.context, creds, principal,
+                                           keytab, 0, NULL, options);
+#if HAVE_KRB5_GET_INIT_CREDS_FREE_CONTEXT
+	krb5_get_init_creds_opt_free(kparam.context, options);
+#else
+	krb5_get_init_creds_opt_free(options);
+#endif
+#else
             krb5_get_init_creds_opt_set_renew_life(&options, rlife);
-
             code =
                 krb5_get_init_creds_keytab(kparam.context, creds, principal,
                                            keytab, 0, NULL, &options);
@@ -413,6 +440,7 @@
             code =
                 krb5_get_init_creds_keytab(kparam.context, creds, principal,
                                            keytab, 0, NULL, &options);
+#endif
             if (code) {
                 debugs(11, 5,
                        HERE <<

