diff options
author | Andreas Schneider <asn@samba.org> | 2011-06-08 14:50:20 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-07-04 18:27:55 +1000 |
commit | c663dfff880634865c4b9f8bad0fa8599899e66a (patch) | |
tree | b00703f55c9e391a295723d7bf625ebce50b6a22 /source3/lib | |
parent | 6b86590342799f3fd35700a1cd1f5fd2aba3547c (diff) | |
download | samba-c663dfff880634865c4b9f8bad0fa8599899e66a.tar.gz samba-c663dfff880634865c4b9f8bad0fa8599899e66a.tar.bz2 samba-c663dfff880634865c4b9f8bad0fa8599899e66a.zip |
s3-util: Add a get_remote_hostname() function.
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/util_sock.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 9b8632b181..a35bd58d11 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -27,6 +27,7 @@ #include "lib/socket/interfaces.h" #include "../lib/util/tevent_unix.h" #include "../lib/util/tevent_ntstatus.h" +#include "../lib/tsocket/tsocket.h" const char *client_name(int fd) { @@ -1126,6 +1127,113 @@ const char *get_peer_addr(int fd, char *addr, size_t addr_len) return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL); } +int get_remote_hostname(const struct tsocket_address *remote_address, + char **name, + TALLOC_CTX *mem_ctx) +{ + char name_buf[MAX_DNS_NAME_LENGTH]; + char tmp_name[MAX_DNS_NAME_LENGTH]; + struct name_addr_pair nc; + struct sockaddr_storage ss; + socklen_t len; + int rc; + + if (!lp_hostname_lookups()) { + nc.name = tsocket_address_inet_addr_string(remote_address, + mem_ctx); + if (nc.name == NULL) { + return -1; + } + + len = tsocket_address_bsd_sockaddr(remote_address, + (struct sockaddr *) &nc.ss, + sizeof(struct sockaddr_storage)); + if (len < 0) { + return -1; + } + + store_nc(&nc); + lookup_nc(&nc); + + if (nc.name == NULL) { + *name = talloc_strdup(mem_ctx, "UNKNOWN"); + } else { + *name = talloc_strdup(mem_ctx, nc.name); + } + return 0; + } + + lookup_nc(&nc); + + ZERO_STRUCT(ss); + + len = tsocket_address_bsd_sockaddr(remote_address, + (struct sockaddr *) &ss, + sizeof(struct sockaddr_storage)); + if (len < 0) { + return -1; + } + + /* it might be the same as the last one - save some DNS work */ + if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) { + if (nc.name == NULL) { + *name = talloc_strdup(mem_ctx, "UNKNOWN"); + } else { + *name = talloc_strdup(mem_ctx, nc.name); + } + return 0; + } + + /* Look up the remote host name. */ + rc = sys_getnameinfo((struct sockaddr *) &ss, + len, + name_buf, + sizeof(name_buf), + NULL, + 0, + 0); + if (rc < 0) { + char *p; + + p = tsocket_address_inet_addr_string(remote_address, mem_ctx); + if (p == NULL) { + return -1; + } + + DEBUG(1,("getnameinfo failed for %s with error %s\n", + p, + gai_strerror(rc))); + strlcpy(name_buf, p, sizeof(name_buf)); + + talloc_free(p); + } else { + if (!matchname(name_buf, (struct sockaddr *)&ss, len)) { + DEBUG(0,("matchname failed on %s\n", name_buf)); + strlcpy(name_buf, "UNKNOWN", sizeof(name_buf)); + } + } + + strlcpy(tmp_name, name_buf, sizeof(tmp_name)); + alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf)); + if (strstr(name_buf,"..")) { + strlcpy(name_buf, "UNKNOWN", sizeof(name_buf)); + } + + nc.name = name_buf; + nc.ss = ss; + + store_nc(&nc); + lookup_nc(&nc); + + if (nc.name == NULL) { + *name = talloc_strdup(mem_ctx, "UNKOWN"); + } else { + *name = talloc_strdup(mem_ctx, nc.name); + } + + return 0; +} + /******************************************************************* Create protected unix domain socket. |