|
6 | 6 | "net"
|
7 | 7 | "regexp"
|
8 | 8 | "sort"
|
| 9 | + "strings" |
9 | 10 |
|
10 | 11 | hadoop "github.com/colinmarc/hdfs/v2/internal/protocol/hadoop_common"
|
11 | 12 | "github.com/colinmarc/hdfs/v2/internal/sasl"
|
@@ -170,10 +171,32 @@ func (c *NamenodeConnection) readSaslResponse(expectedState hadoop.RpcSaslProto_
|
170 | 171 | return resp, nil
|
171 | 172 | }
|
172 | 173 |
|
| 174 | +func reverseResolve(host string) string { |
| 175 | + addrs, err := net.LookupHost(host) |
| 176 | + if err != nil { |
| 177 | + return "" |
| 178 | + } |
| 179 | + for _, addr := range addrs { |
| 180 | + names, err := net.LookupAddr(addr) |
| 181 | + if err != nil { |
| 182 | + continue |
| 183 | + } |
| 184 | + for _, name := range names { |
| 185 | + return strings.TrimSuffix(name, ".") |
| 186 | + } |
| 187 | + } |
| 188 | + return "" |
| 189 | +} |
| 190 | + |
173 | 191 | // getKerberosTicket returns an initial kerberos negotiation token and the
|
174 | 192 | // paired session key, along with an error if any occured.
|
175 | 193 | func (c *NamenodeConnection) getKerberosTicket() (spnego.NegTokenInit, krbtypes.EncryptionKey, error) {
|
176 | 194 | host, _, _ := net.SplitHostPort(c.host.address)
|
| 195 | + // Hadoop uses the reverse-resolved hostname for the SPN, so we do the same. |
| 196 | + // https://github.com/apache/hadoop/blob/7a7db7f0dc4107f44b281eb834fdffc9fd9b08b3/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSUtil.java#L445 |
| 197 | + if revHost := reverseResolve(host); revHost != "" { |
| 198 | + host = revHost |
| 199 | + } |
177 | 200 | spn := replaceSPNHostWildcard(c.kerberosServicePrincipleName, host)
|
178 | 201 |
|
179 | 202 | ticket, key, err := c.kerberosClient.GetServiceTicket(spn)
|
|
0 commit comments