cancel
Showing results for 
Search instead for 
Did you mean: 

Kerberos cross domain auth fails with KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN

betawayoflife
Champ on-the-rise
Champ on-the-rise

Hi guys,

i've a problem authenticating kerberos with multiple domains.

I'm using Alfresco 4.2f on Windows Server 2012 R2 and i've a forest trust (function level 2008 r2) between two domains.

My kerberos cross domain setup is like in the word document from here:
[MNT-10368] support for cross-domain kerberos authentication - Alfresco JIRA 

or this guide Configuring cross-domain support for Kerberos | Alfresco Documentation

The problem is, i'm able to login fine with users from my main domain, but not with users from my second domain.

I've traced the krb5 packages with wireshark and if i try to login from the second domain i get following package:

"KRB5 Error: KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN".

In this package i can see that the user from the second domain tries to authenticate with the realm from the main domain.


The problem is exactly the same as here (without answer): Kerberos with multiple domains on Share 4.0.d 

Here is my authentication part from alfresco-global.properties):

ldap.authentication.defaultAdministratorUserNames=alfrescoadmin
kerberos.authentication.defaultAdministratorUserNames=alfrescoadmin
authentication.chain=kerberos1:kerberos,ldap-domain1:ldap-ad,ldap-domain2:ldap-ad‍‍‍‍‍‍

Here is my krb5.ini:

[libdefaults]
default_realm = DOMAIN1.LOC
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 2h
default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac

[realms]
DOMAIN1.LOC = {
kdc = dc01.domain1.loc:88
admin_server = dc01.domain1.loc:749
default_domain = domain1.loc
}
DOMAIN2.LOC = {
kdc = dc01.domain2.loc:88
admin_server = dc01.domain2.loc:749
default_domain = domain2.loc
}

[domain_realm]
dc01.domain1.loc = DOMAIN1.LOC
.dc01.domain1.loc = DOMAIN1.LOC
dc01.domain2.loc = DOMAIN2.LOC
.dc01.domain2.loc = DOMAIN2.LOC‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here is my kerberos subsystem config:

ntlm.authentication.sso.enabled=true
kerberos.authentication.realm=DOMAIN1.LOC
kerberos.authentication.sso.enabled=true
kerberos.authentication.user.configEntryName=Alfresco
kerberos.authentication.http.configEntryName=AlfrescoHTTP
kerberos.authentication.http.password=HighSecure
kerberos.authentication.authenticateCIFS=false
kerberos.authentication.browser.ticketLogons=true‍‍‍‍‍‍‍‍

Here is my java.login.config:

Alfresco {
com.sun.security.auth.module.Krb5LoginModule sufficient;
};
AlfrescoHTTP {
com.sun.security.auth.module.Krb5LoginModule required
storeKey=true
useKeyTab=true
keyTab="C:/etc/alfrescohttp.keytab"
principal="HTTP/ecm01.domain1.loc";
};
com.sun.net.ssl.client {
com.sun.security.auth.module.Krb5LoginModule sufficient;
};
other {
com.sun.security.auth.module.Krb5LoginModule sufficient;
};‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here is the changed part from java.security:

login.config.url.1=file:${java.home}/lib/security/java.login.config

And finaly the LDAP part for both domains:

ldap.authentication.active=false 
ldap.synchronization.active=true

#
# This properties file brings together the common options for LDAP authentication rather than editing the bean definitions
#
ldap.authentication.allowGuestLogin=false

# How to map the user id entered by the user to taht passed through to LDAP
# In Active Directory, this can either be the user principal name (UPN) or DN.
# UPNs are in the form <sAMAccountName>@domain and are held in the userPrincipalName attribute of a user
ldap.authentication.userNameFormat=%s

# The LDAP context factory to use
ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory

# The URL to connect to the LDAP server
ldap.authentication.java.naming.provider.url=ldap://dc01.domain1.loc:389

# The authentication mechanism to use
ldap.authentication.java.naming.security.authentication=simple

# Escape commas entered by the user at bind time
# Useful when using simple authentication and the CN is part of the DN and contains commas
ldap.authentication.escapeCommasInBind=false

# Escape commas entered by the user when setting the authenticated user
# Useful when using simple authentication and the CN is part of the DN and contains commas, and the escaped \, is
# pulled in as part of an LDAP sync
# If this option is set to true it will break the default home folder provider as space names can not contain \
ldap.authentication.escapeCommasInUid=false

# The default principal to bind with (only used for LDAP sync). This should be a UPN or DN
ldap.synchronization.java.naming.security.principal=DOMAIN1\\alfrescoldap

# The password for the default principal (only used for LDAP sync)
ldap.synchronization.java.naming.security.credentials=HighSecure

# If positive, this property indicates that RFC 2696 paged results should be
# used to split query results into batches of the specified size. This
# overcomes any size limits imposed by the LDAP server.
ldap.synchronization.queryBatchSize=1000

# The query to select all objects that represent the groups to import.
ldap.synchronization.groupQuery=(objectclass\=group)

# The query to select objects that represent the groups to import that have changed since a certain time.
ldap.synchronization.groupDifferentialQuery=(objectclass\=group)

# The query to select all objects that represent the users to import.
ldap.synchronization.personQuery=(objectclass\=user)

# The query to select objects that represent the users to import that have changed since a certain time.
ldap.synchronization.personDifferentialQuery=(objectclass\=user)

# The group search base restricts the LDAP group query to a sub section of tree on the LDAP server.
ldap.synchronization.groupSearchBase=dc=domain1,dc=loc

# The user search base restricts the LDAP user query to a sub section of tree on the LDAP server.
ldap.synchronization.userSearchBase=dc=domain1,dc=loc

# The name of the operational attribute recording the last update time for a group or user.
ldap.synchronization.modifyTimestampAttributeName=modifyTimestamp

# The timestamp format. Unfortunately, this varies between directory servers.
ldap.synchronization.timestampFormat=yyyyMMddHHmmss'.0Z'

# The attribute name on people objects found in LDAP to use as the uid in Alfresco
ldap.synchronization.userIdAttributeName=sAMAccountName

# The attribute on person objects in LDAP to map to the first name property in Alfresco
ldap.synchronization.userFirstNameAttributeName=givenName

# The attribute on person objects in LDAP to map to the last name property in Alfresco
ldap.synchronization.userLastNameAttributeName=sn

# The attribute on person objects in LDAP to map to the email property in Alfresco
ldap.synchronization.userEmailAttributeName=mail

# The attribute on person objects in LDAP to map to the organizational id  property in Alfresco
ldap.synchronization.userOrganizationalIdAttributeName=company

# The default home folder provider to use for people created via LDAP import
ldap.synchronization.defaultHomeFolderProvider=userHomeFolderProvider

# The attribute on LDAP group objects to map to the gid property in Alfrecso
ldap.synchronization.groupIdAttributeName=cn

# The group type in LDAP
ldap.synchronization.groupType=group

# The person type in LDAP
ldap.synchronization.personType=user

# The attribute in LDAP on group objects that defines the DN for its members
ldap.synchronization.groupMemberAttributeName=member‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

ldap.authentication.active=false 
ldap.synchronization.active=true

#
# This properties file brings together the common options for LDAP authentication rather than editing the bean definitions
#
ldap.authentication.allowGuestLogin=false

# How to map the user id entered by the user to taht passed through to LDAP
# In Active Directory, this can either be the user principal name (UPN) or DN.
# UPNs are in the form <sAMAccountName>@domain and are held in the userPrincipalName attribute of a user
ldap.authentication.userNameFormat=%s

# The LDAP context factory to use
ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory

# The URL to connect to the LDAP server
ldap.authentication.java.naming.provider.url=ldap://dc01.domain2.loc:389

# The authentication mechanism to use
ldap.authentication.java.naming.security.authentication=simple

# Escape commas entered by the user at bind time
# Useful when using simple authentication and the CN is part of the DN and contains commas
ldap.authentication.escapeCommasInBind=false

# Escape commas entered by the user when setting the authenticated user
# Useful when using simple authentication and the CN is part of the DN and contains commas, and the escaped \, is
# pulled in as part of an LDAP sync
# If this option is set to true it will break the default home folder provider as space names can not contain \
ldap.authentication.escapeCommasInUid=false

# The default principal to bind with (only used for LDAP sync). This should be a UPN or DN
ldap.synchronization.java.naming.security.principal=DOMAIN2\\alfrescoldap2

# The password for the default principal (only used for LDAP sync)
ldap.synchronization.java.naming.security.credentials=HighSecure

# If positive, this property indicates that RFC 2696 paged results should be
# used to split query results into batches of the specified size. This
# overcomes any size limits imposed by the LDAP server.
ldap.synchronization.queryBatchSize=1000

# The query to select all objects that represent the groups to import.
ldap.synchronization.groupQuery=(objectclass\=group)

# The query to select objects that represent the groups to import that have changed since a certain time.
ldap.synchronization.groupDifferentialQuery=(objectclass\=group)

# The query to select all objects that represent the users to import.
ldap.synchronization.personQuery=(objectclass\=user)

# The query to select objects that represent the users to import that have changed since a certain time.
ldap.synchronization.personDifferentialQuery=(objectclass\=user)

# The group search base restricts the LDAP group query to a sub section of tree on the LDAP server.
ldap.synchronization.groupSearchBase=dc=domain2,dc=loc

# The user search base restricts the LDAP user query to a sub section of tree on the LDAP server.
ldap.synchronization.userSearchBase=dc=domain2,dc=loc

# The name of the operational attribute recording the last update time for a group or user.
ldap.synchronization.modifyTimestampAttributeName=modifyTimestamp

# The timestamp format. Unfortunately, this varies between directory servers.
ldap.synchronization.timestampFormat=yyyyMMddHHmmss'.0Z'

# The attribute name on people objects found in LDAP to use as the uid in Alfresco
ldap.synchronization.userIdAttributeName=sAMAccountName

# The attribute on person objects in LDAP to map to the first name property in Alfresco
ldap.synchronization.userFirstNameAttributeName=givenName

# The attribute on person objects in LDAP to map to the last name property in Alfresco
ldap.synchronization.userLastNameAttributeName=sn

# The attribute on person objects in LDAP to map to the email property in Alfresco
ldap.synchronization.userEmailAttributeName=mail

# The attribute on person objects in LDAP to map to the organizational id  property in Alfresco
ldap.synchronization.userOrganizationalIdAttributeName=company

# The default home folder provider to use for people created via LDAP import
ldap.synchronization.defaultHomeFolderProvider=userHomeFolderProvider

# The attribute on LDAP group objects to map to the gid property in Alfrecso
ldap.synchronization.groupIdAttributeName=cn

# The group type in LDAP
ldap.synchronization.groupType=group

# The person type in LDAP
ldap.synchronization.personType=user

# The attribute in LDAP on group objects that defines the DN for its members
ldap.synchronization.groupMemberAttributeName=member‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Hopefully anyone can bring me in the right direction.


Thanks.


Beta

7 REPLIES 7

afaust
Legendary Innovator
Legendary Innovator

Can you provide more details, e.g. the principal set to authenticate on the Share tier (which is typically different from the Repository tier, which you have provided). I know you said you have configured it "like in the word document" but that word document is lacking some details I would have expected and all too often I have also seen slight errors / oversight tha turned out to be the cause of problems.

Also you can activate Java debug output for Kerberos authentication (system property sun.security.krb5.debug set to true) and provide the details here so that people have more to go on.

betawayoflife
Champ on-the-rise
Champ on-the-rise

Hi Axel,

i edit my first post and add more details.

I've already activatet the krb5.debug but i get no message / error in the alfrescout-stdout.

I only get following messages:

 2017-01-02 08:43:40,386 DEBUG [app.servlet.KerberosAuthenticationFilter] [http-apr-8080-exec-2] New Kerberos auth request from 1.2.3.4 (1.2.3.4:65030)
2017-01-02 08:43:40,386 DEBUG [app.servlet.KerberosAuthenticationFilter] [http-apr-8080-exec-2] Issuing login challenge to browser.
2017-01-02 08:43:40,464 DEBUG [app.servlet.KerberosAuthenticationFilter] [http-apr-8080-exec-3] Login page requested, chaining ...

In the webinterface i only get following error:

Unable to login - unknown username/password.

Thx,
Beta

afaust
Legendary Innovator
Legendary Innovator

If krb5.debug is activated correctly the catalina.out / alfrescout-stdout log file should contain significant technical details about all Kerberos interactions. If that is not the case I would advise to check the krb5.debug activation. The property cannot be set via alfresco-global.properties and must be provided as a JVM parameter. When using the Windows Service for Tomcat this requires a reconfiguration of the service itself.

betawayoflife
Champ on-the-rise
Champ on-the-rise

Thx, i forget the "D" for the tomcat config...

The right entry for the tomcat config:

-Dsun.security.krb5.debug=true‍

Now i see following error in the log:

2017-01-02 12:25:31,912 DEBUG [app.servlet.KerberosAuthenticationFilter] [http-apr-8080-exec-2] Login page requested, chaining ...
default etypes for default_tkt_enctypes: 23.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=dc01.domain1.loc UDP:88, timeout=30000, number of retries =3, #bytes=145
>>> KDCCommunication: kdc=dc01.domain1.loc UDP:88, timeout=30000,Attempt =1, #bytes=145
>>> KrbKdcReq send: #bytes read=100
>>> KdcAccessibility: remove dc01.domain1.loc:88
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
sTime is Mon Jan 02 12:25:31 CET 2017 1483356331000
suSec is 895582
error code is 6
error Message is Client not found in Kerberos database
realm is DOMAIN1.LOC
sname is krbtgt/DOMAIN1.LOC
msgType is 30‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The strange thing is that i try to login with a user from domain2.loc.

Thx,

Joe

afaust
Legendary Innovator
Legendary Innovator

But you have configured a specific kerberos.authentication.realm which is used as the default real / domain. Did you provide the domain as an explicit realm when trying to login, e.g. use a prinicipal name like user.name@domain2.loc?

Yes, in the kerberos subsystem config.

kerberos.authentication.realm=DOMAIN1.LOC

If i remove this line alfresco won't come up because of a missing propertie.


I've tried with "DOMAIN2\username", "username@domain2" and "username@domain2.loc".

Same error for all of them.

If i try to login with a user from domain1 the DEBUG log looks like this:
(it works and the log is much longer)

2017-01-02 13:53:10,844 DEBUG [app.servlet.KerberosAuthenticationFilter] [http-apr-8080-exec-5] Login page requested, chaining ...
default etypes for default_tkt_enctypes: 23.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=dc01.domain1.loc UDP:88, timeout=30000, number of retries =3, #bytes=141
>>> KDCCommunication: kdc=dc01.domain1.loc UDP:88, timeout=30000,Attempt =1, #bytes=141
>>> KrbKdcReq send: #bytes read=185
>>>Pre-Authentication Data:
PA-DATA type = 11
PA-ETYPE-INFO etype = 23, salt =

>>>Pre-Authentication Data:
PA-DATA type = 19
PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
PA-DATA type = 2
PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
PA-DATA type = 16

>>>Pre-Authentication Data:
PA-DATA type = 15

>>> KdcAccessibility: remove dc01.domain1.loc:88
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
sTime is Mon Jan 02 13:53:10 CET 2017 1483361590000
suSec is 363334
error code is 25
error Message is Additional pre-authentication required
realm is DOMAIN1.LOC
sname is krbtgt/DOMAIN1.LOC
eData provided.
msgType is 30
>>>Pre-Authentication Data:
PA-DATA type = 11
PA-ETYPE-INFO etype = 23, salt =

>>>Pre-Authentication Data:
PA-DATA type = 19
PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
PA-DATA type = 2
PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
PA-DATA type = 16

>>>Pre-Authentication Data:
PA-DATA type = 15

KrbAsReqBuilder: PREAUTH FAILED/REQ, re-send AS-REQ
default etypes for default_tkt_enctypes: 23.
default etypes for default_tkt_enctypes: 23.
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=dc01.domain1.loc UDP:88, timeout=30000, number of retries =3, #bytes=219
>>> KDCCommunication: kdc=dc01.domain1.loc UDP:88, timeout=30000,Attempt =1, #bytes=219
>>> KrbKdcReq send: #bytes read=1393
>>> KdcAccessibility: remove dc01.domain1.loc:88
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
>>> KrbAsRep cons in KrbAsReq.getReply informix

betawayoflife
Champ on-the-rise
Champ on-the-rise

Any ideas Axel or anyone else?