Skip to content

Commit 1825e37

Browse files
ldapauth: Allow service tickets with alternate protocol in SPN
1 parent a20f0f0 commit 1825e37

File tree

1 file changed

+45
-11
lines changed

1 file changed

+45
-11
lines changed

ldapauth/gssapi.go

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,57 @@ func (client *gssapiClient) DeleteSecContext() error {
107107
}
108108

109109
func (client *gssapiClient) getServiceTicket(target string) (tkt messages.Ticket, key types.EncryptionKey, err error) {
110+
if client.ccache == nil {
111+
return client.GetServiceTicket(target)
112+
}
113+
110114
// ask our own copy of the ccache for a suitable service ticket before asking the client
111-
if client.ccache != nil {
112-
entry, ok := client.ccache.GetEntry(types.NewPrincipalName(nametype.KRB_NT_SRV_INST, target))
113-
if !ok {
114-
return tkt, key, fmt.Errorf("CCACHE does not contain service ticket for %q", target)
115+
entry, ok := client.ccache.GetEntry(types.NewPrincipalName(nametype.KRB_NT_SRV_INST, target))
116+
if !ok {
117+
// check for tickets with same host but alternative protocol
118+
for _, cred := range client.ccache.GetEntries() {
119+
if sameHost(cred.Server.PrincipalName, target) {
120+
entry = cred
121+
122+
break
123+
}
115124
}
125+
}
116126

117-
if entry.Key.KeyType == etypeID.RC4_HMAC {
118-
return tkt, key, fmt.Errorf("RC4 tickets from ccache are currently not supported " +
119-
"(see https://github.com/jcmturner/gokrb5/pull/498), but you should be able " +
120-
"to request an AES256 ticket instead (even with NT hash)")
121-
}
127+
if entry == nil {
128+
return tkt, key, fmt.Errorf("CCache does not contain service ticket for %q", target)
129+
}
130+
131+
if entry.Key.KeyType == etypeID.RC4_HMAC {
132+
return tkt, key, fmt.Errorf("RC4 tickets from ccache are currently not supported " +
133+
"(see https://github.com/jcmturner/gokrb5/pull/498), but you should be able " +
134+
"to request an AES256 ticket instead (even with NT hash)")
135+
}
136+
137+
return tkt, entry.Key, tkt.Unmarshal(entry.Ticket)
138+
}
139+
140+
func sameHost(firstSPN types.PrincipalName, otherSPNString string) bool {
141+
if len(firstSPN.NameString) < 2 || !strings.Contains(otherSPNString, "/") {
142+
return false
143+
}
144+
145+
firstHost := strings.ToLower(strings.Join(firstSPN.NameString[1:], "."))
146+
secondHost := strings.ToLower(strings.Split(otherSPNString, "/")[1])
147+
148+
if firstHost == secondHost {
149+
return true
150+
}
151+
152+
if !strings.Contains(firstHost, ".") && strings.HasPrefix(secondHost, firstHost+".") {
153+
return true
154+
}
122155

123-
return tkt, entry.Key, tkt.Unmarshal(entry.Ticket)
156+
if !strings.Contains(secondHost, ".") && strings.HasPrefix(firstHost, secondHost+".") {
157+
return true
124158
}
125159

126-
return client.GetServiceTicket(target)
160+
return false
127161
}
128162

129163
func (client *gssapiClient) newKRB5TokenAPREQ(

0 commit comments

Comments
 (0)