Macmod / godap

A complete TUI for LDAP.
MIT License
415 stars 20 forks source link

Kerberos incompatibilities #14

Open grawity opened 2 weeks ago

grawity commented 2 weeks ago
  1. In standard Kerberos implementations (e.g. MIT Kerberos, Heimdal Kerberos) KRB5CCNAME generally defaults to FILE:/tmp/krb5cc_<uid> (although a different default may be set via krb5.conf). Currently godap assumes an empty string by default.

    $ ~/go/bin/godap -k ldap.nullroute.lt
    2024/11/11 18:43:52 open : no such file or directory
  2. In standard Kerberos implementations KRB5CCNAME is typically in the form of type:value, with an implied default of FILE: for the type. That is, while KRB5CCNAME="/tmp/cache" is valid, so is KRB5CCNAME="FILE:/tmp/cache", and most software (such as sshd or pam_krb5) uses the latter format, which godap currently does not accept.

    $ klist
    Ticket cache: FILE:/tmp/krb5cc_1000
    
    $ export KRB5CCNAME="FILE:/tmp/krb5cc_1000"
    
    $ ldapwhoami -Q -Y GSSAPI -H ldap://ldap.nullroute.lt
    dn:uid=grawity,cn=gssapi,cn=auth
    
    $ ~/go/bin/godap -k ldap.nullroute.lt
    2024/11/11 18:44:28 open FILE:/tmp/krb5cc_1000: no such file or directory
  3. The KDC is not looked up via SRV records, but specifying it manually doesn't seem to work either:

    $ export KRB5CCNAME="/tmp/krb5cc_1000"
    
    $ ~/go/bin/godap -k ldap.nullroute.lt
    2024/11/11 18:46:26 [Root cause: Networking_Error] Networking_Error: TGS Exchange
    Error: issue sending TGS_REQ to KDC: communication error with KDC via TCP: no
    KDCs defined in configuration for realm NULLROUTE.LT
    
    $ ~/go/bin/godap -k --kdc star.nullroute.lt ldap.nullroute.lt
    2024/11/11 18:46:26 [Root cause: Networking_Error] Networking_Error: TGS Exchange
    Error: issue sending TGS_REQ to KDC: communication error with KDC via TCP: no
    KDCs defined in configuration for realm NULLROUTE.LT
Macmod commented 2 weeks ago

Hello @grawity, thanks for the raising the issue.

  1. Specifying the KRB5CCNAME explicitly is currently the "easiest" way because godap must be cross-platform, and I'm not aware of a good way to infer a "common default path" in a way that works for Linux, Windows & MacOS. If you know a better way to do it I'm totally open to suggestions - Kerberos is not really my area of expertise and most of the Kerberos code here is basically a "hack" that I wrote over a couple of weeks just to get it working for Active Directory.
  2. Godap doesn't parse prefixes like FILE: in the KRB5CCNAME variable; we should make this fact clear in the docs, or raise an error if the user specifies a prefix (I'll do that in the next release). For godap KRB5CCNAME is just a raw path to the CCACHE file.
  3. Looking up the KDC from the domain is a good suggestion and I'll do it in the next release too, but I don't understand the error you had. What's the backend you're using? Is it OpenLDAP?
Macmod commented 2 weeks ago

One thing that I noticed is that you didn't specify the domain name nullroute.lt with -d, so that field (which is used to fill the realm in the Kerberos config) was probably empty in the call to lc.KerbBindWithCCache. Maybe that was the issue?

grawity commented 2 weeks ago

Specifying the KRB5CCNAME explicitly is currently the "easiest" way because godap must be cross-platform, and I'm not aware of a good way to infer a "common default path" in a way that works for Linux, Windows & MacOS. If you know a better way to do it I'm totally open to suggestions - Kerberos is not really my area of expertise and most of the Kerberos code here is basically a "hack" that I wrote over a couple of weeks just to get it working for Active Directory.

Right, it gets a bit complex with macOS, and I guess it should be the job of go-krb5 to determine the actual default (as it already supports reading /etc/krb5.conf anyway). Though /tmp/krb5cc_<uid> is the traditional Unix default, so still perhaps better than nothing (especially if go-krb5 only supports file-based caches and won't be able to support the macOS default API cache anyway...)

Unfortunately go-krb5 seems a bit unmaintained these days.

For Windows there is no default path, and not even any tools to create such a path – programs are meant to use SSPI (e.g. alexbrainman/sspi) and don't have any direct access to the cache. One would have to install MIT Kerberos or Java to get any sort of file-based cache.

Godap doesn't parse prefixes like FILE: in the KRB5CCNAME variable; we should make this fact clear in the docs, or raise an error if the user specifies a prefix (I'll do that in the next release). For godap KRB5CCNAME is just a raw path to the CCACHE file.

Yeah, that's exactly the 'incompatibility' problem I was talking about – it has to parse the type prefix because KRB5CCNAME often already comes "from outside", e.g. it may be set by the OS when the user logs in to the system with an AD or Kerberos account, or when the user SSH's into the system with Kerberos ticket delegation enabled... In other words there's a pre-existing format for it.

So if KRB5CCNAME is used then the code should at least accept and trim the "FILE:" prefix specifically (and I guess warn about other unsupported types)... If not, then IMO it's better to ignore KRB5CCNAME entirely and use an option like --cache for the path.

Looking up the KDC from the domain is a good suggestion and I'll do it in the next release too, but I don't understand the error you had. What's the backend you're using? Is it OpenLDAP?

It's OpenLDAP + MIT Kerberos, but I see the program doesn't even start talking to the LDAP server.

One thing that I noticed is that you didn't specify the domain name nullroute.lt with -d, so that field (which is used to fill the realm in the Kerberos config) was probably empty in the call to lc.KerbBindWithCCache. Maybe that was the issue?

It might be (will test once I get back home). The error message implied that it already knows the realm, so it didn't occur to me that -d was needed.