.
.SH SYNOPSIS
.if !'po4a'hide' .B ext_kerberos_ldap_group_acl
-.if !'po4a'hide' .B [\-h] [\-d] [\-i] [\-s] [\-a] [\-D Realm ] [\-N Netbios\-Realm\-List] [\-m Max\-Depth] [\-u Ldap\-User] [\-p Ldap\-Password] [\-b Ldap\-Bind\-Path] [\-l Ldap\-URL] [\-S ldap server list] \-g Group\-Realm\-List \-t Hex\-Group\-Realm\-List \-T Hex\-Group\-Hex\-Realm\-List
+.if !'po4a'hide' .B [\-h] [\-d] [\-i] [\-s] [\-a] [\-D Realm ] [\-N Netbios\-Realm\-List] [\-P service principal name] [\-m Max\-Depth] [\-u Ldap\-User] [\-p Ldap\-Password] [\-b Ldap\-Bind\-Path] [\-l Ldap\-URL] [\-S ldap server list] \-g Group\-Realm\-List \-t Hex\-Group\-Realm\-List \-T Hex\-Group\-Hex\-Realm\-List
.
.SH DESCRIPTION
.B ext_kerberos_ldap_group_acl
A list of Netbios name mappings to Kerberos domain names of the form
Netbios\-Name@Kerberos\-Realm[:Netbios\-Name@Kerberos\-Realm] (e.g. for users
using NTLM authentication).
+.if !'po4a'hide' .B \-P service principal name
+The principal name in the keytab to use. Avoids automated selection of name.
.if !'po4a'hide' .TP 12
.if !'po4a'hide' .B \-m Max\-Depth
Maximal depth of recursive group search.
Password for LDAP server.
.IP
As the password needs to be printed in plain text in your Squid configuration
-it is strongly recommended to use an account with minimal associated privileges.
+it is strongly recommended to use an account with minimal associated privileges.
+
This to limit the damage in case someone could get hold of a copy of your Squid
configuration file or extracts the password used from a process listing.
.
A list of group name per Kerberos domain of the form
Group|Group@|Group@Realm[:Group@|Group@Realm]
.if !'po4a'hide' .TP 12
-.if !'po4a'hide' .B \-t Hex\-Group\-Realm\-List
+.if !'po4a'hide' .B \-t Hex\-Group\-Realm\-List
A list of group name per Kerberos domain of the
form Group|Group@|Group@Realm[:Group@|Group@Realm] where group is in
UTF\-8 hex format
.if !'po4a'hide' .P
.if !'po4a'hide' .ft CR
.if !'po4a'hide' .nf
-.if !'po4a'hide' external_acl_type kerberos_ldap_group1 ttl=3600 negative_ttl=3600 %LOGIN /path/to/ext_kerberos_ldap_group_acl \-g GROUP1
+.if !'po4a'hide' external_acl_type kerberos_ldap_group1 ttl=3600 negative_ttl=3600 %LOGIN /path/to/ext_kerberos_ldap_group_acl \-g GROUP1
.if !'po4a'hide' .br
-.if !'po4a'hide' external_acl_type kerberos_ldap_group2 ttl=3600 negative_ttl=3600 %LOGIN /path/to/ext_kerberos_ldap_group_acl \-g GROUP2
+.if !'po4a'hide' external_acl_type kerberos_ldap_group2 ttl=3600 negative_ttl=3600 %LOGIN /path/to/ext_kerberos_ldap_group_acl \-g GROUP2
.if !'po4a'hide' .br
.if !'po4a'hide' acl group1 external kerberos_ldap_group1
.if !'po4a'hide' .br
3) For NDOMAIN\\user
a) Use realm given by \-N NDOMAIN@REALM and then use values given by \-g option which contain a @REALM e.g. \-g GROUP1@REALM:GROUP2@REALM
-To support Non\-ASCII character use \-t GROUP or \-t GROUP@REALM instead of \-g where GROUP is the hex UTF\-8 representation e.g.
+To support Non\-ASCII character use \-t GROUP or \-t GROUP@REALM instead of \-g where GROUP is the hex UTF\-8 representation e.g.
\-t 6d61726b7573 instead of \-g markus
The ldap server list can be:
server \- In this case server can be used for all Kerberos domains
-server@ \- In this case server can be used for all Kerberos domains
-server@domain \- In this case server can be used for Kerberos domain domain
+server@ \- In this case server can be used for all Kerberos domains
+server@domain \- In this case server can be used for Kerberos domain domain
server1a@domain1:server1b@domain1:server2@domain2:server3@:server4 \- A list is build with a colon as separator
.
#endif
}
+static void
+k5_debug(const char* msg, krb5_error_code code)
+{
+ const char *errmsg;
+ errmsg = krb5_get_error_message(kparam.context, code);
+ debug((char *) "%s| %s: DEBUG: %s : %s\n", LogTime(), PROGRAM, msg, errmsg);
+#if HAVE_KRB5_FREE_ERROR_MESSAGE
+ krb5_free_error_message(kparam.context, errmsg);
+#elif HAVE_KRB5_FREE_ERROR_STRING
+ krb5_free_error_string(kparam.context, (char *)errmsg);
+#else
+ xfree(errmsg);
+#endif
+}
+
static void
k5_error(const char* msg, krb5_error_code code)
{
* create Kerberos memory cache
*/
int
-krb5_create_cache(char *domain)
+krb5_create_cache(char *domain, char *service_principal_name)
{
krb5_keytab keytab = NULL;
}
code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc[ccindex]);
if (code) {
- k5_error("Error while resolving memory ccache",code);
+ k5_error("Error while resolving memory ccache", code);
retval = 1;
goto cleanup;
}
if (principal)
krb5_free_principal(kparam.context, principal);
principal = NULL;
- k5_error("No default principal found in ccache",code);
+ k5_debug("No default principal found in ccache", code);
} else {
/*
* Look for krbtgt and check if it is expired (or soon to be expired)
*/
code = krb5_cc_start_seq_get(kparam.context, kparam.cc[ccindex], &ccursor);
if (code) {
- k5_error("Error while starting ccache scan",code);
+ k5_error("Error while starting ccache scan", code);
code = krb5_cc_close (kparam.context, kparam.cc[ccindex]);
if (code) {
- k5_error("Error while closing ccache",code);
+ k5_error("Error while closing ccache", code);
}
if (kparam.cc[ccindex]) {
code = krb5_cc_destroy(kparam.context, kparam.cc[ccindex]);
if (code) {
- k5_error("Error while destroying ccache",code);
+ k5_error("Error while destroying ccache", code);
}
}
} else {
while ((krb5_cc_next_cred(kparam.context, kparam.cc[ccindex], &ccursor, creds)) == 0) {
code2 = krb5_unparse_name(kparam.context, creds->server, &principal_name);
if (code2) {
- k5_error("Error while unparsing principal",code2);
+ k5_error("Error while unparsing principal", code2);
code = krb5_cc_destroy(kparam.context, kparam.cc[ccindex]);
if (code) {
- k5_error("Error while destroying ccache",code);
+ k5_error("Error while destroying ccache", code);
}
assert(creds != NULL);
krb5_free_creds(kparam.context, creds);
debug((char *) "%s| %s: DEBUG: Reset credential cache to %s\n", LogTime(), PROGRAM, mem_cache);
code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc[ccindex]);
if (code) {
- k5_error("Error while resolving memory ccache",code);
+ k5_error("Error while resolving memory ccache", code);
retval = 1;
goto cleanup;
}
principal = NULL;
code = krb5_cc_destroy(kparam.context, kparam.cc[ccindex]);
if (code) {
- k5_error("Error while destroying ccache",code);
+ k5_error("Error while destroying ccache", code);
}
assert(creds != NULL);
krb5_free_creds(kparam.context, creds);
debug((char *) "%s| %s: DEBUG: Reset credential cache to %s\n", LogTime(), PROGRAM, mem_cache);
code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc[ccindex]);
if (code) {
- k5_error("Error while resolving ccache",code);
+ k5_error("Error while resolving ccache", code);
retval = 1;
goto cleanup;
}
creds = NULL;
code2 = krb5_cc_end_seq_get(kparam.context, kparam.cc[ccindex], &ccursor);
if (code2) {
- k5_error("Error while ending ccache scan",code2);
+ k5_error("Error while ending ccache scan", code2);
retval = 1;
goto cleanup;
}
code = krb5_kt_resolve(kparam.context, keytab_name, &keytab);
if (code) {
- k5_error2("Error while resolving keytab ",keytab_name,code);
+ k5_error2("Error while resolving keytab ", keytab_name,code);
retval = 1;
goto cleanup;
}
code = krb5_kt_start_seq_get(kparam.context, keytab, &cursor);
if (code) {
- k5_error("Error while starting keytab scan",code);
+ k5_error("Error while starting keytab scan", code);
retval = 1;
goto cleanup;
}
{
code = krb5_unparse_name(kparam.context, entry.principal, &principal_name);
if (code) {
- k5_error("Error while unparsing principal name",code);
+ k5_error("Error while unparsing principal name", code);
} else {
debug((char *) "%s| %s: DEBUG: Found principal name: %s\n", LogTime(), PROGRAM, principal_name);
found = 1;
+ if (service_principal_name && strcasecmp(principal_name,service_principal_name) != 0 ) {
+ debug((char *) "%s| %s: DEBUG: principal name does not match parameter: %s\n", LogTime(), PROGRAM, service_principal_name);
+ safe_free(principal_name);
+ found = 0;
+ }
}
}
#if USE_HEIMDAL_KRB5 || ( HAVE_KRB5_KT_FREE_ENTRY && HAVE_DECL_KRB5_KT_FREE_ENTRY )
code = krb5_free_keytab_entry_contents(kparam.context, &entry);
#endif
if (code) {
- k5_error("Error while freeing keytab entry",code);
+ k5_error("Error while freeing keytab entry", code);
retval = 1;
break;
}
#endif
if (code) {
- k5_error("Error while initialising credentials from keytab",code);
+ k5_error("Error while initialising credentials from keytab", code);
safe_free(principal_name);
if (principal)
krb5_free_principal(kparam.context, principal);
}
code = krb5_cc_initialize(kparam.context, kparam.cc[ccindex], principal);
if (code) {
- k5_error("Error while initialising memory caches",code);
+ k5_error("Error while initialising cache", code);
safe_free(principal_name);
if (principal)
krb5_free_principal(kparam.context, principal);
}
code = krb5_cc_store_cred(kparam.context, kparam.cc[ccindex], creds);
if (code) {
- k5_error("Error while storing credentials",code);
+ k5_error("Error while storing credentials", code);
if (principal)
krb5_free_principal(kparam.context, principal);
safe_free(principal_name);
}
if (code && code != KRB5_KT_END) {
- k5_error("Error while scanning keytab",code);
+ k5_error("Error while scanning keytab", code);
retval = 1;
goto cleanup;
}
code = krb5_kt_end_seq_get(kparam.context, keytab, &cursor);
if (code) {
- k5_error("Error while ending keytab scan",code);
+ k5_error("Error while ending keytab scan", code);
retval = 1;
goto cleanup;
}
/*
* if no principal name found in keytab for domain use the prinipal name which can get a TGT
*/
- if (!principal_name) {
+ if (!principal_name && !service_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);
*/
code = krb5_unparse_name(kparam.context, principal_list[i], &principal_name);
if (code) {
- k5_error("Error while unparsing principal name",code);
+ k5_error("Error while unparsing principal name", code);
goto loop_end;
}
debug((char *) "%s| %s: DEBUG: Keytab entry has principal: %s\n", LogTime(), PROGRAM, principal_name);
code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0);
#endif
if (code) {
- k5_error("Error while initialising credentials from keytab",code);
+ k5_error("Error while initialising credentials from keytab", code);
goto loop_end;
}
code = krb5_cc_initialize(kparam.context, kparam.cc[ccindex], principal_list[i]);
if (code) {
- k5_error("Error while initialising memory caches",code);
+ k5_error("Error while initialising memory caches", code);
goto loop_end;
}
code = krb5_cc_store_cred(kparam.context, kparam.cc[ccindex], creds);
if (code) {
- k5_error("Error while storing credentials",code);
+ k5_error("Error while storing credentials", code);
goto loop_end;
}
if (creds->server)
code = krb5_parse_name(kparam.context, service, &creds->server);
xfree(service);
if (code) {
- k5_error("Error while initialising TGT credentials",code);
+ k5_error("Error while initialising TGT credentials", code);
goto loop_end;
}
code = krb5_get_credentials(kparam.context, 0, kparam.cc[ccindex], creds, &tgt_creds);
if (code) {
- k5_error("Error while getting tgt",code);
+ k5_error("Error while getting tgt", code);
goto loop_end;
} else {
debug((char *) "%s| %s: DEBUG: Found trusted principal name: %s\n", LogTime(), PROGRAM, principal_name);
*/
code = krb5_unparse_name(kparam.context, principal, &principal_name);
if (code) {
- k5_error("Error while unparsing principal name",code);
+ k5_error("Error while unparsing principal name", code);
retval = 1;
goto cleanup;
}