summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;