summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-30 07:22:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:23 -0500
commita0ab1f7afda62964d480af9dc26e60a38d1350e0 (patch)
treec078770b99b8a2972ff71cd090acb2ebfe0d7a60
parent003fbe7f6472ed433bc5495b422f3e6d5278da17 (diff)
downloadsamba-a0ab1f7afda62964d480af9dc26e60a38d1350e0.tar.gz
samba-a0ab1f7afda62964d480af9dc26e60a38d1350e0.tar.bz2
samba-a0ab1f7afda62964d480af9dc26e60a38d1350e0.zip
r5107: moved the horrible ldap socket code, and the even worse
asn1-tied-to-blocking-sockets code into the ldap client and torture suite, and out of the generic libs, so nobody else is tempted to use it for any new code. (This used to be commit 39d1ced21baeca40d1fca62ba65243ca8f15757e)
-rw-r--r--source4/lib/util_sock.c175
-rw-r--r--source4/libcli/ldap/ldap_client.c240
-rw-r--r--source4/libcli/util/asn1.c61
-rw-r--r--source4/torture/ldap/common.c65
4 files changed, 299 insertions, 242 deletions
diff --git a/source4/lib/util_sock.c b/source4/lib/util_sock.c
index 1859aef4d7..b2f949ebe5 100644
--- a/source4/lib/util_sock.c
+++ b/source4/lib/util_sock.c
@@ -122,178 +122,3 @@ void set_socket_options(int fd, const char *options)
}
}
-
-/****************************************************************************
- Check the timeout.
-****************************************************************************/
-static BOOL timeout_until(struct timeval *timeout,
- const struct timeval *endtime)
-{
- struct timeval now;
-
- GetTimeOfDay(&now);
-
- if ((now.tv_sec > endtime->tv_sec) ||
- ((now.tv_sec == endtime->tv_sec) &&
- (now.tv_usec > endtime->tv_usec)))
- return False;
-
- timeout->tv_sec = endtime->tv_sec - now.tv_sec;
- timeout->tv_usec = endtime->tv_usec - now.tv_usec;
- return True;
-}
-
-
-/****************************************************************************
- Read data from the client, reading exactly N bytes, with timeout.
-****************************************************************************/
-ssize_t read_data_until(int fd,char *buffer,size_t N,
- const struct timeval *endtime)
-{
- ssize_t ret;
- size_t total=0;
-
- while (total < N) {
-
- if (endtime != NULL) {
- fd_set r_fds;
- struct timeval timeout;
- int res;
-
- FD_ZERO(&r_fds);
- FD_SET(fd, &r_fds);
-
- if (!timeout_until(&timeout, endtime))
- return -1;
-
- res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout);
- if (res <= 0)
- return -1;
- }
-
- ret = sys_read(fd,buffer + total,N - total);
-
- if (ret == 0) {
- DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
- return 0;
- }
-
- if (ret == -1) {
- DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
- return -1;
- }
- total += ret;
- }
- return (ssize_t)total;
-}
-
-
-/****************************************************************************
- Write data to a fd with timeout.
-****************************************************************************/
-ssize_t write_data_until(int fd,char *buffer,size_t N,
- const struct timeval *endtime)
-{
- size_t total=0;
- ssize_t ret;
-
- while (total < N) {
-
- if (endtime != NULL) {
- fd_set w_fds;
- struct timeval timeout;
- int res;
-
- FD_ZERO(&w_fds);
- FD_SET(fd, &w_fds);
-
- if (!timeout_until(&timeout, endtime))
- return -1;
-
- res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout);
- if (res <= 0)
- return -1;
- }
-
- ret = sys_write(fd,buffer + total,N - total);
-
- if (ret == -1) {
- DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
- return -1;
- }
- if (ret == 0)
- return total;
-
- total += ret;
- }
- return (ssize_t)total;
-}
-
-
-
-/****************************************************************************
- create an outgoing socket. timeout is in milliseconds.
- **************************************************************************/
-int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeout)
-{
- struct sockaddr_in sock_out;
- int res,ret;
- int connect_loop = 250; /* 250 milliseconds */
- int loops = (timeout) / connect_loop;
-
- /* create a socket to write to */
- res = socket(PF_INET, type, 0);
- if (res == -1)
- { DEBUG(0,("socket error\n")); return -1; }
-
- if (type != SOCK_STREAM) return(res);
-
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
-
- sock_out.sin_port = htons( port );
- sock_out.sin_family = PF_INET;
-
- /* set it non-blocking */
- set_blocking(res,False);
-
- DEBUG(3,("Connecting to %s at port %d\n", sys_inet_ntoa(*addr),port));
-
- /* and connect it to the destination */
-connect_again:
- ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
-
- /* Some systems return EAGAIN when they mean EINPROGRESS */
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN) && loops--) {
- msleep(connect_loop);
- goto connect_again;
- }
-
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN)) {
- DEBUG(1,("timeout connecting to %s:%d\n", sys_inet_ntoa(*addr),port));
- close(res);
- return -1;
- }
-
-#ifdef EISCONN
- if (ret < 0 && errno == EISCONN) {
- errno = 0;
- ret = 0;
- }
-#endif
-
- if (ret < 0) {
- DEBUG(2,("error connecting to %s:%d (%s)\n",
- sys_inet_ntoa(*addr),port,strerror(errno)));
- close(res);
- return -1;
- }
-
- /* set it blocking again */
- set_blocking(res,True);
-
- return res;
-}
-
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index c9e81ac28f..73099ec1be 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -29,6 +29,246 @@
#include "asn_1.h"
#include "dlinklist.h"
+
+
+/****************************************************************************
+ Check the timeout.
+****************************************************************************/
+static BOOL timeout_until(struct timeval *timeout,
+ const struct timeval *endtime)
+{
+ struct timeval now;
+
+ GetTimeOfDay(&now);
+
+ if ((now.tv_sec > endtime->tv_sec) ||
+ ((now.tv_sec == endtime->tv_sec) &&
+ (now.tv_usec > endtime->tv_usec)))
+ return False;
+
+ timeout->tv_sec = endtime->tv_sec - now.tv_sec;
+ timeout->tv_usec = endtime->tv_usec - now.tv_usec;
+ return True;
+}
+
+
+/****************************************************************************
+ Read data from the client, reading exactly N bytes, with timeout.
+****************************************************************************/
+static ssize_t read_data_until(int fd,char *buffer,size_t N,
+ const struct timeval *endtime)
+{
+ ssize_t ret;
+ size_t total=0;
+
+ while (total < N) {
+
+ if (endtime != NULL) {
+ fd_set r_fds;
+ struct timeval timeout;
+ int res;
+
+ FD_ZERO(&r_fds);
+ FD_SET(fd, &r_fds);
+
+ if (!timeout_until(&timeout, endtime))
+ return -1;
+
+ res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout);
+ if (res <= 0)
+ return -1;
+ }
+
+ ret = sys_read(fd,buffer + total,N - total);
+
+ if (ret == 0) {
+ DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
+ return 0;
+ }
+
+ if (ret == -1) {
+ DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
+ return -1;
+ }
+ total += ret;
+ }
+ return (ssize_t)total;
+}
+
+
+/****************************************************************************
+ Write data to a fd with timeout.
+****************************************************************************/
+static ssize_t write_data_until(int fd,char *buffer,size_t N,
+ const struct timeval *endtime)
+{
+ size_t total=0;
+ ssize_t ret;
+
+ while (total < N) {
+
+ if (endtime != NULL) {
+ fd_set w_fds;
+ struct timeval timeout;
+ int res;
+
+ FD_ZERO(&w_fds);
+ FD_SET(fd, &w_fds);
+
+ if (!timeout_until(&timeout, endtime))
+ return -1;
+
+ res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout);
+ if (res <= 0)
+ return -1;
+ }
+
+ ret = sys_write(fd,buffer + total,N - total);
+
+ if (ret == -1) {
+ DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (ret == 0)
+ return total;
+
+ total += ret;
+ }
+ return (ssize_t)total;
+}
+
+
+
+static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data,
+ const struct timeval *endtime)
+{
+ if (read_data_until(sock, result, 1, endtime) != 1)
+ return False;
+
+ return asn1_write(data, result, 1);
+}
+
+/* Read a complete ASN sequence (ie LDAP result) from a socket */
+static BOOL asn1_read_sequence_until(int sock, struct asn1_data *data,
+ const struct timeval *endtime)
+{
+ uint8_t b;
+ size_t len;
+ char *buf;
+
+ ZERO_STRUCTP(data);
+
+ if (!read_one_uint8(sock, &b, data, endtime))
+ return False;
+
+ if (b != 0x30) {
+ data->has_error = True;
+ return False;
+ }
+
+ if (!read_one_uint8(sock, &b, data, endtime))
+ return False;
+
+ if (b & 0x80) {
+ int n = b & 0x7f;
+ if (!read_one_uint8(sock, &b, data, endtime))
+ return False;
+ len = b;
+ while (n > 1) {
+ if (!read_one_uint8(sock, &b, data, endtime))
+ return False;
+ len = (len<<8) | b;
+ n--;
+ }
+ } else {
+ len = b;
+ }
+
+ buf = talloc_size(NULL, len);
+ if (buf == NULL)
+ return False;
+
+ if (read_data_until(sock, buf, len, endtime) != len)
+ return False;
+
+ if (!asn1_write(data, buf, len))
+ return False;
+
+ talloc_free(buf);
+
+ data->ofs = 0;
+
+ return True;
+}
+
+
+
+/****************************************************************************
+ create an outgoing socket. timeout is in milliseconds.
+ **************************************************************************/
+static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeout)
+{
+ struct sockaddr_in sock_out;
+ int res,ret;
+ int connect_loop = 250; /* 250 milliseconds */
+ int loops = (timeout) / connect_loop;
+
+ /* create a socket to write to */
+ res = socket(PF_INET, type, 0);
+ if (res == -1)
+ { DEBUG(0,("socket error\n")); return -1; }
+
+ if (type != SOCK_STREAM) return(res);
+
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
+ putip((char *)&sock_out.sin_addr,(char *)addr);
+
+ sock_out.sin_port = htons( port );
+ sock_out.sin_family = PF_INET;
+
+ /* set it non-blocking */
+ set_blocking(res,False);
+
+ DEBUG(3,("Connecting to %s at port %d\n", sys_inet_ntoa(*addr),port));
+
+ /* and connect it to the destination */
+connect_again:
+ ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
+
+ /* Some systems return EAGAIN when they mean EINPROGRESS */
+ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN) && loops--) {
+ msleep(connect_loop);
+ goto connect_again;
+ }
+
+ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN)) {
+ DEBUG(1,("timeout connecting to %s:%d\n", sys_inet_ntoa(*addr),port));
+ close(res);
+ return -1;
+ }
+
+#ifdef EISCONN
+ if (ret < 0 && errno == EISCONN) {
+ errno = 0;
+ ret = 0;
+ }
+#endif
+
+ if (ret < 0) {
+ DEBUG(2,("error connecting to %s:%d (%s)\n",
+ sys_inet_ntoa(*addr),port,strerror(errno)));
+ close(res);
+ return -1;
+ }
+
+ /* set it blocking again */
+ set_blocking(res,True);
+
+ return res;
+}
+
#if 0
static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn,
const char *base,
diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c
index 550450fea7..1124cc1701 100644
--- a/source4/libcli/util/asn1.c
+++ b/source4/libcli/util/asn1.c
@@ -379,67 +379,6 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag)
return !data->has_error;
}
-static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data,
- const struct timeval *endtime)
-{
- if (read_data_until(sock, result, 1, endtime) != 1)
- return False;
-
- return asn1_write(data, result, 1);
-}
-
-/* Read a complete ASN sequence (ie LDAP result) from a socket */
-BOOL asn1_read_sequence_until(int sock, struct asn1_data *data,
- const struct timeval *endtime)
-{
- uint8_t b;
- size_t len;
- char *buf;
-
- ZERO_STRUCTP(data);
-
- if (!read_one_uint8(sock, &b, data, endtime))
- return False;
-
- if (b != 0x30) {
- data->has_error = True;
- return False;
- }
-
- if (!read_one_uint8(sock, &b, data, endtime))
- return False;
-
- if (b & 0x80) {
- int n = b & 0x7f;
- if (!read_one_uint8(sock, &b, data, endtime))
- return False;
- len = b;
- while (n > 1) {
- if (!read_one_uint8(sock, &b, data, endtime))
- return False;
- len = (len<<8) | b;
- n--;
- }
- } else {
- len = b;
- }
-
- buf = talloc_size(NULL, len);
- if (buf == NULL)
- return False;
-
- if (read_data_until(sock, buf, len, endtime) != len)
- return False;
-
- if (!asn1_write(data, buf, len))
- return False;
-
- talloc_free(buf);
-
- data->ofs = 0;
-
- return True;
-}
/* Get the length to be expected in buf */
BOOL asn1_object_length(uint8_t *buf, size_t buf_length,
diff --git a/source4/torture/ldap/common.c b/source4/torture/ldap/common.c
index 162934a38d..b9f0f5c655 100644
--- a/source4/torture/ldap/common.c
+++ b/source4/torture/ldap/common.c
@@ -103,6 +103,61 @@ NTSTATUS torture_ldap_close(struct ldap_connection *conn)
return NT_STATUS_OK;
}
+
+/*
+ Write data to a fd
+*/
+static ssize_t write_data(int fd, char *buffer, size_t N)
+{
+ size_t total=0;
+ ssize_t ret;
+
+ while (total < N) {
+ ret = sys_write(fd,buffer + total,N - total);
+
+ if (ret == -1) {
+ DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (ret == 0)
+ return total;
+
+ total += ret;
+ }
+
+ return (ssize_t)total;
+}
+
+
+/*
+ Read data from the client, reading exactly N bytes
+*/
+static ssize_t read_data(int fd, char *buffer, size_t N)
+{
+ ssize_t ret;
+ size_t total=0;
+
+ while (total < N) {
+
+ ret = sys_read(fd,buffer + total,N - total);
+
+ if (ret == 0) {
+ DEBUG(10,("read_data: read of %d returned 0. Error = %s\n",
+ (int)(N - total), strerror(errno) ));
+ return 0;
+ }
+
+ if (ret == -1) {
+ DEBUG(0,("read_data: read failure for %d. Error = %s\n",
+ (int)(N - total), strerror(errno) ));
+ return -1;
+ }
+ total += ret;
+ }
+
+ return (ssize_t)total;
+}
+
BOOL ldap_sasl_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
const struct timeval *endtime)
{
@@ -131,26 +186,24 @@ BOOL ldap_sasl_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
RSIVAL(length, 0, wrapped.length);
- result = (write_data_until(conn->sock, length, 4,
- endtime) == 4);
+ result = (write_data(conn->sock, length, 4) == 4);
if (!result)
return result;
- result = (write_data_until(conn->sock, wrapped.data, wrapped.length,
- endtime) == wrapped.length);
+ result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length);
if (!result)
return result;
wrapped = data_blob(NULL, 0x4000);
data_blob_clear(&wrapped);
- result = (read_data_until(conn->sock, length, 4, NULL) == 4);
+ result = (read_data(conn->sock, length, 4) == 4);
if (!result)
return result;
len = RIVAL(length,0);
- result = (read_data_until(conn->sock, wrapped.data, MIN(wrapped.length,len), NULL) == len);
+ result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len);
if (!result)
return result;