|
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,54 @@ func (c *NamenodeConnection) readSaslResponse(expectedState hadoop.RpcSaslProto_
|
170 | 171 | return resp, nil
|
171 | 172 | }
|
172 | 173 |
|
| 174 | +func isValidHostname(host string, addr string) bool { |
| 175 | + addrs, err := net.LookupHost(host) |
| 176 | + if err != nil { |
| 177 | + return false |
| 178 | + } |
| 179 | + if len(addrs) == 0 { |
| 180 | + return false |
| 181 | + } |
| 182 | + for _, a := range addrs { |
| 183 | + if a != addr { |
| 184 | + return false |
| 185 | + } |
| 186 | + } |
| 187 | + return true |
| 188 | + |
| 189 | +} |
| 190 | + |
| 191 | +func reverseLookup(host string, restrict bool) string { |
| 192 | + addrs, err := net.LookupHost(host) |
| 193 | + if err != nil { |
| 194 | + return "" |
| 195 | + } |
| 196 | + for _, addr := range addrs { |
| 197 | + names, err := net.LookupAddr(addr) |
| 198 | + if err != nil { |
| 199 | + continue |
| 200 | + } |
| 201 | + for _, name := range names { |
| 202 | + if restrict { |
| 203 | + if !isValidHostname(name, addr) { |
| 204 | + continue |
| 205 | + } |
| 206 | + } |
| 207 | + return strings.TrimSuffix(name, ".") |
| 208 | + } |
| 209 | + } |
| 210 | + return "" |
| 211 | +} |
| 212 | + |
173 | 213 | // getKerberosTicket returns an initial kerberos negotiation token and the
|
174 | 214 | // paired session key, along with an error if any occured.
|
175 | 215 | func (c *NamenodeConnection) getKerberosTicket() (spnego.NegTokenInit, krbtypes.EncryptionKey, error) {
|
176 | 216 | host, _, _ := net.SplitHostPort(c.host.address)
|
| 217 | + // Hadoop uses the reverse-resolved hostname for the SPN, so we do the same. |
| 218 | + // https://github.com/apache/hadoop/blob/7a7db7f0dc4107f44b281eb834fdffc9fd9b08b3/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSUtil.java#L445 |
| 219 | + if revHost := reverseLookup(host, true); revHost != "" { |
| 220 | + host = revHost |
| 221 | + } |
177 | 222 | spn := replaceSPNHostWildcard(c.kerberosServicePrincipleName, host)
|
178 | 223 |
|
179 | 224 | ticket, key, err := c.kerberosClient.GetServiceTicket(spn)
|
|
0 commit comments