summaryrefslogtreecommitdiff
path: root/source3/lib/util_sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util_sock.c')
-rw-r--r--source3/lib/util_sock.c238
1 files changed, 117 insertions, 121 deletions
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index d16a8f079a..945506ea77 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -1277,80 +1277,6 @@ ssize_t receive_smb_raw(int fd,
}
/****************************************************************************
- Wrapper for receive_smb_raw().
- Checks the MAC on signed packets.
-****************************************************************************/
-
-bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre)
-{
- if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) {
- return false;
- }
-
- if (srv_encryption_on()) {
- NTSTATUS status = srv_decrypt_buffer(buffer);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("receive_smb: SMB decryption failed "
- "on incoming packet! Error %s\n",
- nt_errstr(status) ));
- cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT);
- return false;
- }
- }
-
- /* Check the incoming SMB signature. */
- if (!srv_check_sign_mac(buffer, true)) {
- DEBUG(0, ("receive_smb: SMB Signature verification "
- "failed on incoming packet!\n"));
- cond_set_smb_read_error(pre,SMB_READ_BAD_SIG);
- return false;
- }
-
- return true;
-}
-
-/****************************************************************************
- Send an smb to a fd.
-****************************************************************************/
-
-bool send_smb(int fd, char *buffer)
-{
- size_t len;
- size_t nwritten=0;
- ssize_t ret;
- char *buf_out = buffer;
-
- /* Sign the outgoing packet if required. */
- srv_calculate_sign_mac(buf_out);
-
- if (srv_encryption_on()) {
- NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("send_smb: SMB encryption failed "
- "on outgoing packet! Error %s\n",
- nt_errstr(status) ));
- return false;
- }
- }
-
- len = smb_len(buf_out) + 4;
-
- while (nwritten < len) {
- ret = write_data(fd,buf_out+nwritten,len - nwritten);
- if (ret <= 0) {
- DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
- (int)len,(int)ret, strerror(errno) ));
- srv_free_enc_buffer(buf_out);
- return false;
- }
- nwritten += ret;
- }
-
- srv_free_enc_buffer(buf_out);
- return true;
-}
-
-/****************************************************************************
Open a socket of the specified type, port, and address for incoming data.
****************************************************************************/
@@ -1824,18 +1750,66 @@ static bool matchname(const char *remotehost,
return false;
}
-static struct {
- struct sockaddr_storage ss;
- char *name;
-} nc;
+/*******************************************************************
+ Deal with the singleton cache.
+******************************************************************/
+
+struct name_addr_pair {
+ struct sockaddr_storage ss;
+ const char *name;
+};
+
+/*******************************************************************
+ Lookup a name/addr pair. Returns memory allocated from memcache.
+******************************************************************/
+
+static bool lookup_nc(struct name_addr_pair *nc)
+{
+ DATA_BLOB tmp;
+
+ ZERO_STRUCTP(nc);
+
+ if (!memcache_lookup(
+ NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_peer_name"),
+ &tmp)) {
+ return false;
+ }
+
+ memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
+ nc->name = (const char *)tmp.data + sizeof(nc->ss);
+ return true;
+}
+
+/*******************************************************************
+ Save a name/addr pair.
+******************************************************************/
+
+static void store_nc(const struct name_addr_pair *nc)
+{
+ DATA_BLOB tmp;
+ size_t namelen = strlen(nc->name);
+
+ tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
+ if (!tmp.data) {
+ return;
+ }
+ memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
+ memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
+
+ memcache_add(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_peer_name"),
+ tmp);
+ data_blob_free(&tmp);
+}
/*******************************************************************
Return the DNS name of the remote end of a socket.
******************************************************************/
-const char *get_peer_name(int fd,
- bool force_lookup)
+const char *get_peer_name(int fd, bool force_lookup)
{
+ struct name_addr_pair nc;
char addr_buf[INET6_ADDRSTRLEN];
struct sockaddr_storage ss;
socklen_t length = sizeof(ss);
@@ -1850,13 +1824,15 @@ const char *get_peer_name(int fd,
possible */
if (!lp_hostname_lookups() && (force_lookup == false)) {
length = sizeof(nc.ss);
- p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
+ nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
&nc.ss, &length);
- SAFE_FREE(nc.name);
- nc.name = SMB_STRDUP(p);
+ store_nc(&nc);
+ lookup_nc(&nc);
return nc.name ? nc.name : "UNKNOWN";
}
+ lookup_nc(&nc);
+
memset(&ss, '\0', sizeof(ss));
p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length);
@@ -1865,9 +1841,7 @@ const char *get_peer_name(int fd,
return nc.name ? nc.name : "UNKNOWN";
}
- /* Not the same. Reset the cache. */
- zero_addr(&nc.ss);
- SAFE_FREE(nc.name);
+ /* Not the same. We need to lookup. */
if (fd == -1) {
return "UNKNOWN";
}
@@ -1904,7 +1878,11 @@ const char *get_peer_name(int fd,
strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
}
- nc.name = SMB_STRDUP(name_buf);
+ nc.name = name_buf;
+ nc.ss = ss;
+
+ store_nc(&nc);
+ lookup_nc(&nc);
return nc.name ? nc.name : "UNKNOWN";
}
@@ -2026,50 +2004,68 @@ out_umask:
const char *get_mydnsfullname(void)
{
- static char *dnshostname_cache;
-
- if (dnshostname_cache == NULL || !*dnshostname_cache) {
- struct addrinfo *res = NULL;
- char my_hostname[HOST_NAME_MAX];
- bool ret;
+ struct addrinfo *res = NULL;
+ char my_hostname[HOST_NAME_MAX];
+ bool ret;
+ DATA_BLOB tmp;
- /* get my host name */
- if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
- DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
- return NULL;
- }
+ if (memcache_lookup(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_mydnsfullname"),
+ &tmp)) {
+ SMB_ASSERT(tmp.length > 0);
+ return (const char *)tmp.data;
+ }
- /* Ensure null termination. */
- my_hostname[sizeof(my_hostname)-1] = '\0';
+ /* get my host name */
+ if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
+ DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
+ return NULL;
+ }
- ret = interpret_string_addr_internal(&res,
- my_hostname,
- AI_ADDRCONFIG|AI_CANONNAME);
+ /* Ensure null termination. */
+ my_hostname[sizeof(my_hostname)-1] = '\0';
- if (!ret || res == NULL) {
- DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
- "name %s [%s]\n",
+ ret = interpret_string_addr_internal(&res,
my_hostname,
- gai_strerror(ret) ));
- return NULL;
- }
+ AI_ADDRCONFIG|AI_CANONNAME);
- /*
- * Make sure that getaddrinfo() returns the "correct" host name.
- */
+ if (!ret || res == NULL) {
+ DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
+ "name %s [%s]\n",
+ my_hostname,
+ gai_strerror(ret) ));
+ return NULL;
+ }
- if (res->ai_canonname == NULL) {
- DEBUG(3,("get_mydnsfullname: failed to get "
- "canonical name for %s\n",
- my_hostname));
- freeaddrinfo(res);
- return NULL;
- }
+ /*
+ * Make sure that getaddrinfo() returns the "correct" host name.
+ */
- dnshostname_cache = SMB_STRDUP(res->ai_canonname);
+ if (res->ai_canonname == NULL) {
+ DEBUG(3,("get_mydnsfullname: failed to get "
+ "canonical name for %s\n",
+ my_hostname));
freeaddrinfo(res);
+ return NULL;
}
- return dnshostname_cache;
+
+ /* This copies the data, so we must do a lookup
+ * afterwards to find the value to return.
+ */
+
+ memcache_add(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_mydnsfullname"),
+ data_blob_string_const(res->ai_canonname));
+
+ freeaddrinfo(res);
+
+ if (!memcache_lookup(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_mydnsfullname"),
+ &tmp)) {
+ return NULL;
+ }
+
+ return (const char *)tmp.data;
}
/************************************************************