diff --git a/ldapauth/ldap.go b/ldapauth/ldap.go index 4c06242..3a2fbfb 100644 --- a/ldapauth/ldap.go +++ b/ldapauth/ldap.go @@ -243,7 +243,9 @@ func bind( tlsState, ok := conn.TLSConnectionState() if ok && !opts.DisableChannelBinding { - bindRequest.Negotiator = ntlmNegotiatorWithChannelBinding(tlsState.PeerCertificates[0]) + bindRequest.Negotiator = ntlmNegotiatorWithChannelBinding(tlsState.PeerCertificates[0], creds.Domain) + } else { + bindRequest.Negotiator = ntlmNegotiatorForDomain(creds.Domain) } _, err = conn.NTLMChallengeBind(bindRequest) diff --git a/ldapauth/ntlm.go b/ldapauth/ntlm.go index 75e4203..e8a3715 100644 --- a/ldapauth/ntlm.go +++ b/ldapauth/ntlm.go @@ -10,13 +10,18 @@ import ( ) type ntlmNegotiator struct { - cert *x509.Certificate + cert *x509.Certificate + overrideTargetName string } var _ ldap.NTLMNegotiator = &ntlmNegotiator{} -func ntlmNegotiatorWithChannelBinding(cert *x509.Certificate) ldap.NTLMNegotiator { - return &ntlmNegotiator{cert: cert} +func ntlmNegotiatorWithChannelBinding(cert *x509.Certificate, domain string) ldap.NTLMNegotiator { + return &ntlmNegotiator{cert: cert, overrideTargetName: domain} +} + +func ntlmNegotiatorForDomain(domain string) ldap.NTLMNegotiator { + return &ntlmNegotiator{overrideTargetName: domain} } func (n *ntlmNegotiator) Negotiate(domain string, worktation string) ([]byte, error) { @@ -48,6 +53,17 @@ func (n *ntlmNegotiator) ChallengeResponse(challenge []byte, username string, ha cm.TargetInfo.List = cm.TargetInfo.List[:len(cm.TargetInfo.List)-1] } + // Authenticate with the domain name that was specified, not the domain that + // the server advertises. This grants compatibility with the LDAP SOCKS + // feature of ntlmrelayx.py which is sensitive to the exact domain name (DNS + // vs NetBIOS name). + if n.overrideTargetName != "" && n.overrideTargetName != "." { + cm.TargetName, err = ntlm.CreateStringPayload(n.overrideTargetName) + if err != nil { + return nil, fmt.Errorf("override target name: create string payload: %w", err) + } + } + // add channel bindings cm.TargetInfo.AddAvPair(ntlm.MsvChannelBindings, ChannelBindingHash(n.cert)) cm.TargetInfo.AddAvPair(ntlm.MsvAvEOL, nil)