summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/async_req/async_sock.c583
-rw-r--r--lib/async_req/async_sock.h46
-rw-r--r--lib/tevent/tevent.h1
-rw-r--r--lib/util/tevent_unix.c46
-rw-r--r--lib/util/tevent_unix.h27
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/proto.h11
-rw-r--r--source3/lib/util.c99
-rw-r--r--source3/lib/util_sock.c29
-rw-r--r--source3/lib/wb_reqtrans.c401
-rw-r--r--source3/lib/wbclient.c62
-rw-r--r--source3/libsmb/cliconnect.c25
-rw-r--r--source3/libsmb/nmblib.c15
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c38
-rw-r--r--source3/utils/smbfilter.c11
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c33
16 files changed, 715 insertions, 715 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index 02ae880683..3563421e0e 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -22,6 +22,7 @@
#include "lib/tevent/tevent.h"
#include "lib/async_req/async_req.h"
#include "lib/async_req/async_sock.h"
+#include "lib/util/tevent_unix.h"
#include <fcntl.h>
#ifndef TALLOC_FREE
@@ -33,10 +34,7 @@
*/
enum async_syscall_type {
ASYNC_SYSCALL_SEND,
- ASYNC_SYSCALL_SENDALL,
ASYNC_SYSCALL_RECV,
- ASYNC_SYSCALL_RECVALL,
- ASYNC_SYSCALL_CONNECT
};
/**
@@ -54,36 +52,12 @@ struct async_syscall_state {
size_t length;
int flags;
} param_send;
- struct param_sendall {
- int fd;
- const void *buffer;
- size_t length;
- int flags;
- size_t sent;
- } param_sendall;
struct param_recv {
int fd;
void *buffer;
size_t length;
int flags;
} param_recv;
- struct param_recvall {
- int fd;
- void *buffer;
- size_t length;
- int flags;
- size_t received;
- } param_recvall;
- struct param_connect {
- /**
- * connect needs to be done on a nonblocking
- * socket. Keep the old flags around
- */
- long old_sockflags;
- int fd;
- const struct sockaddr *address;
- socklen_t address_len;
- } param_connect;
} param;
union {
@@ -337,109 +311,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
}
/**
- * fde event handler for the "sendall" syscall group
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the send
- * @param[in] flags Can only be TEVENT_FD_WRITE here
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_sendall_callback(struct tevent_context *ev,
- struct tevent_fd *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_sendall *p = &state->param.param_sendall;
-
- if (state->syscall_type != ASYNC_SYSCALL_SENDALL) {
- async_req_error(req, EIO);
- return;
- }
-
- state->result.result_ssize_t = send(p->fd,
- (const char *)p->buffer + p->sent,
- p->length - p->sent, p->flags);
- state->sys_errno = errno;
-
- if (state->result.result_ssize_t == -1) {
- async_req_error(req, state->sys_errno);
- return;
- }
-
- if (state->result.result_ssize_t == 0) {
- async_req_error(req, EOF);
- return;
- }
-
- p->sent += state->result.result_ssize_t;
- if (p->sent > p->length) {
- async_req_error(req, EIO);
- return;
- }
-
- if (p->sent == p->length) {
- TALLOC_FREE(state->fde);
- async_req_done(req);
- }
-}
-
-/**
- * @brief Send all bytes to a socket
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to send to
- * @param[in] buffer The buffer to send
- * @param[in] length How many bytes to send
- * @param[in] flags flags passed to send(2)
- *
- * async_sendall calls send(2) as long as it is necessary to send all of the
- * "length" bytes
- */
-
-struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- int fd, const void *buffer, size_t length,
- int flags)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- result = async_fde_syscall_new(
- mem_ctx, ev, ASYNC_SYSCALL_SENDALL,
- fd, TEVENT_FD_WRITE, async_sendall_callback,
- &state);
- if (result == NULL) {
- return NULL;
- }
-
- state->param.param_sendall.fd = fd;
- state->param.param_sendall.buffer = buffer;
- state->param.param_sendall.length = length;
- state->param.param_sendall.flags = flags;
- state->param.param_sendall.sent = 0;
-
- return result;
-}
-
-ssize_t sendall_recv(struct async_req *req, int *perr)
-{
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- int err;
-
- err = async_req_simple_recv_errno(req);
-
- if (err != 0) {
- *perr = err;
- return -1;
- }
-
- return state->result.result_ssize_t;
-}
-
-/**
* fde event handler for the "recv" syscall
* @param[in] ev The event context that sent us here
* @param[in] fde The file descriptor event associated with the recv
@@ -507,106 +378,138 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
return result;
}
-/**
- * fde event handler for the "recvall" syscall group
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the recv
- * @param[in] flags Can only be TEVENT_FD_READ here
- * @param[in] priv private data, "struct async_req *" in this case
- */
+struct async_send_state {
+ int fd;
+ const void *buf;
+ size_t len;
+ int flags;
+ ssize_t sent;
+};
-static void async_recvall_callback(struct tevent_context *ev,
- struct tevent_fd *fde, uint16_t flags,
- void *priv)
+static void async_send_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *private_data);
+
+struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, const void *buf, size_t len,
+ int flags)
{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_recvall *p = &state->param.param_recvall;
+ struct tevent_req *result;
+ struct async_send_state *state;
+ struct tevent_fd *fde;
- if (state->syscall_type != ASYNC_SYSCALL_RECVALL) {
- async_req_error(req, EIO);
- return;
+ result = tevent_req_create(mem_ctx, &state, struct async_send_state);
+ if (result == NULL) {
+ return result;
}
+ state->fd = fd;
+ state->buf = buf;
+ state->len = len;
+ state->flags = flags;
- state->result.result_ssize_t = recv(p->fd,
- (char *)p->buffer + p->received,
- p->length - p->received, p->flags);
- state->sys_errno = errno;
-
- if (state->result.result_ssize_t == -1) {
- async_req_error(req, state->sys_errno);
- return;
+ fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, async_send_handler,
+ result);
+ if (fde == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
}
+ return result;
+}
- if (state->result.result_ssize_t == 0) {
- async_req_error(req, EIO);
+static void async_send_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *private_data)
+{
+ struct tevent_req *req = talloc_get_type_abort(
+ private_data, struct tevent_req);
+ struct async_send_state *state = talloc_get_type_abort(
+ req->private_state, struct async_send_state);
+
+ state->sent = send(state->fd, state->buf, state->len, state->flags);
+ if (state->sent == -1) {
+ tevent_req_error(req, errno);
return;
}
+ tevent_req_done(req);
+}
- p->received += state->result.result_ssize_t;
- if (p->received > p->length) {
- async_req_error(req, EIO);
- return;
- }
+ssize_t async_send_recv(struct tevent_req *req, int *perrno)
+{
+ struct async_send_state *state = talloc_get_type_abort(
+ req->private_state, struct async_send_state);
- if (p->received == p->length) {
- TALLOC_FREE(state->fde);
- async_req_done(req);
+ if (tevent_req_is_unix_error(req, perrno)) {
+ return -1;
}
+ return state->sent;
}
-/**
- * Receive a specified number of bytes from a socket
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to recv from
- * @param[in] buffer The buffer to recv into
- * @param[in] length How many bytes to recv
- * @param[in] flags flags passed to recv(2)
- *
- * async_recvall will call recv(2) until "length" bytes are received
- */
+struct async_recv_state {
+ int fd;
+ void *buf;
+ size_t len;
+ int flags;
+ ssize_t received;
+};
-struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- int fd, void *buffer, size_t length,
- int flags)
+static void async_recv_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *private_data);
+
+struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, void *buf, size_t len, int flags)
{
- struct async_req *result;
- struct async_syscall_state *state;
+ struct tevent_req *result;
+ struct async_recv_state *state;
+ struct tevent_fd *fde;
- result = async_fde_syscall_new(
- mem_ctx, ev, ASYNC_SYSCALL_RECVALL,
- fd, TEVENT_FD_READ, async_recvall_callback,
- &state);
+ result = tevent_req_create(mem_ctx, &state, struct async_recv_state);
if (result == NULL) {
- return NULL;
+ return result;
}
+ state->fd = fd;
+ state->buf = buf;
+ state->len = len;
+ state->flags = flags;
- state->param.param_recvall.fd = fd;
- state->param.param_recvall.buffer = buffer;
- state->param.param_recvall.length = length;
- state->param.param_recvall.flags = flags;
- state->param.param_recvall.received = 0;
-
+ fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, async_recv_handler,
+ result);
+ if (fde == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
return result;
}
-ssize_t recvall_recv(struct async_req *req, int *perr)
+static void async_recv_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *private_data)
{
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- int err;
+ struct tevent_req *req = talloc_get_type_abort(
+ private_data, struct tevent_req);
+ struct async_recv_state *state = talloc_get_type_abort(
+ req->private_state, struct async_recv_state);
+
+ state->received = recv(state->fd, state->buf, state->len,
+ state->flags);
+ if (state->received == -1) {
+ tevent_req_error(req, errno);
+ return;
+ }
+ tevent_req_done(req);
+}
- err = async_req_simple_recv_errno(req);
+ssize_t async_recv_recv(struct tevent_req *req, int *perrno)
+{
+ struct async_recv_state *state = talloc_get_type_abort(
+ req->private_state, struct async_recv_state);
- if (err != 0) {
- *perr = err;
+ if (tevent_req_is_unix_error(req, perrno)) {
return -1;
}
-
- return state->result.result_ssize_t;
+ return state->received;
}
struct async_connect_state {
@@ -633,17 +536,18 @@ static void async_connect_connected(struct tevent_context *ev,
* connect in an async state. This will be reset when the request is finished.
*/
-struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len)
+struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, const struct sockaddr *address,
+ socklen_t address_len)
{
- struct async_req *result;
+ struct tevent_req *result;
struct async_connect_state *state;
struct tevent_fd *fde;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct async_connect_state)) {
+ result = tevent_req_create(
+ mem_ctx, &state, struct async_connect_state);
+ if (result == NULL) {
return NULL;
}
@@ -664,8 +568,8 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
state->result = connect(fd, address, address_len);
if (state->result == 0) {
- state->sys_errno = 0;
- goto post_status;
+ errno = 0;
+ goto post_errno;
}
/**
@@ -686,22 +590,20 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE,
async_connect_connected, result);
if (fde == NULL) {
- state->sys_errno = ENOMEM;
- goto post_status;
+ errno = ENOMEM;
+ goto post_errno;
}
return result;
post_errno:
state->sys_errno = errno;
- post_status:
fcntl(fd, F_SETFL, state->old_sockflags);
- if (!async_post_error(result, ev, state->sys_errno)) {
- goto fail;
+ if (state->sys_errno == 0) {
+ tevent_req_done(result);
+ } else {
+ tevent_req_error(result, state->sys_errno);
}
- return result;
- fail:
- TALLOC_FREE(result);
- return NULL;
+ return tevent_req_post(result, ev);
}
/**
@@ -716,10 +618,10 @@ static void async_connect_connected(struct tevent_context *ev,
struct tevent_fd *fde, uint16_t flags,
void *priv)
{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
+ struct tevent_req *req = talloc_get_type_abort(
+ priv, struct tevent_req);
struct async_connect_state *state = talloc_get_type_abort(
- req->private_data, struct async_connect_state);
+ req->private_state, struct async_connect_state);
TALLOC_FREE(fde);
@@ -743,27 +645,27 @@ static void async_connect_connected(struct tevent_context *ev,
DEBUG(10, ("connect returned %s\n", strerror(errno)));
fcntl(state->fd, F_SETFL, state->old_sockflags);
- async_req_error(req, state->sys_errno);
+ tevent_req_error(req, state->sys_errno);
return;
}
state->sys_errno = 0;
- async_req_done(req);
+ tevent_req_done(req);
}
-int async_connect_recv(struct async_req *req, int *perrno)
+int async_connect_recv(struct tevent_req *req, int *perrno)
{
struct async_connect_state *state = talloc_get_type_abort(
- req->private_data, struct async_connect_state);
+ req->private_state, struct async_connect_state);
int err;
fcntl(state->fd, F_SETFL, state->old_sockflags);
-
- if (async_req_is_errno(req, &err)) {
+ if (tevent_req_is_unix_error(req, &err)) {
*perrno = err;
return -1;
}
+
if (state->sys_errno == 0) {
return 0;
}
@@ -771,3 +673,226 @@ int async_connect_recv(struct async_req *req, int *perrno)
*perrno = state->sys_errno;
return -1;
}
+
+struct writev_state {
+ struct tevent_context *ev;
+ int fd;
+ struct iovec *iov;
+ int count;
+ size_t total_size;
+};
+
+static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
+ uint16_t flags, void *private_data);
+
+struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ int fd, struct iovec *iov, int count)
+{
+ struct tevent_req *result;
+ struct writev_state *state;
+ struct tevent_fd *fde;
+
+ result = tevent_req_create(mem_ctx, &state, struct writev_state);
+ if (result == NULL) {
+ return NULL;
+ }
+ state->ev = ev;
+ state->fd = fd;
+ state->total_size = 0;
+ state->count = count;
+ state->iov = (struct iovec *)talloc_memdup(
+ state, iov, sizeof(struct iovec) * count);
+ if (state->iov == NULL) {
+ goto fail;
+ }
+
+ fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, writev_handler,
+ result);
+ if (fde == NULL) {
+ goto fail;
+ }
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
+ uint16_t flags, void *private_data)
+{
+ struct tevent_req *req = talloc_get_type_abort(
+ private_data, struct tevent_req);
+ struct writev_state *state = talloc_get_type_abort(
+ req->private_state, struct writev_state);
+ size_t to_write, written;
+ int i;
+
+ to_write = 0;
+
+ for (i=0; i<state->count; i++) {
+ to_write += state->iov[i].iov_len;
+ }
+
+ written = sys_writev(state->fd, state->iov, state->count);
+ if (written == -1) {
+ tevent_req_error(req, errno);
+ return;
+ }
+ if (written == 0) {
+ tevent_req_error(req, EPIPE);
+ return;
+ }
+ state->total_size += written;
+
+ if (written == to_write) {
+ tevent_req_done(req);
+ return;
+ }
+
+ /*
+ * We've written less than we were asked to, drop stuff from
+ * state->iov.
+ */
+
+ while (written > 0) {
+ if (written < state->iov[0].iov_len) {
+ state->iov[0].iov_base =
+ (char *)state->iov[0].iov_base + written;
+ state->iov[0].iov_len -= written;
+ break;
+ }
+ written = state->iov[0].iov_len;
+ state->iov += 1;
+ state->count -= 1;
+ }
+}
+
+ssize_t writev_recv(struct tevent_req *req, int *perrno)
+{
+ struct writev_state *state = talloc_get_type_abort(
+ req->private_state, struct writev_state);
+
+ if (tevent_req_is_unix_error(req, perrno)) {
+ return -1;
+ }
+ return state->total_size;
+}
+
+struct read_packet_state {
+ int fd;
+ uint8_t *buf;
+ size_t nread;
+ ssize_t (*more)(uint8_t *buf, size_t buflen, void *private_data);
+ void *private_data;
+};
+
+static void read_packet_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *private_data);
+
+struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, size_t initial,
+ ssize_t (*more)(uint8_t *buf,
+ size_t buflen,
+ void *private_data),
+ void *private_data)
+{
+ struct tevent_req *result;
+ struct read_packet_state *state;
+ struct tevent_fd *fde;
+
+ result = tevent_req_create(mem_ctx, &state, struct read_packet_state);
+ if (result == NULL) {
+ return NULL;
+ }
+ state->fd = fd;
+ state->nread = 0;
+ state->more = more;
+ state->private_data = private_data;
+
+ state->buf = talloc_array(state, uint8_t, initial);
+ if (state->buf == NULL) {
+ goto fail;
+ }
+
+ fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler,
+ result);
+ if (fde == NULL) {
+ goto fail;
+ }
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void read_packet_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *private_data)
+{
+ struct tevent_req *req = talloc_get_type_abort(
+ private_data, struct tevent_req);
+ struct read_packet_state *state = talloc_get_type_abort(
+ req->private_state, struct read_packet_state);
+ size_t total = talloc_get_size(state->buf);
+ ssize_t nread, more;
+ uint8_t *tmp;
+
+ nread = read(state->fd, state->buf+state->nread, total-state->nread);
+ if (nread == -1) {
+ tevent_req_error(req, errno);
+ return;
+ }
+ if (nread == 0) {
+ tevent_req_error(req, EPIPE);
+ return;
+ }
+
+ state->nread += nread;
+ if (state->nread < total) {
+ /* Come back later */
+ return;
+ }
+
+ /*
+ * We got what was initially requested. See if "more" asks for -- more.
+ */
+ if (state->more == NULL) {
+ /* Nobody to ask, this is a async read_data */
+ tevent_req_done(req);
+ return;
+ }
+
+ more = state->more(state->buf, total, state->private_data);
+ if (more == -1) {
+ /* We got an invalid packet, tell the caller */
+ tevent_req_error(req, EIO);
+ return;
+ }
+ if (more == 0) {
+ /* We're done, full packet received */
+ tevent_req_done(req);
+ return;
+ }
+
+ tmp = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, total+more);
+ if (tevent_req_nomem(tmp, req)) {
+ return;
+ }
+ state->buf = tmp;
+}
+
+ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ uint8_t **pbuf, int *perrno)
+{
+ struct read_packet_state *state = talloc_get_type_abort(
+ req->private_state, struct read_packet_state);
+
+ if (tevent_req_is_unix_error(req, perrno)) {
+ return -1;
+ }
+ *pbuf = talloc_move(mem_ctx, &state->buf);
+ return talloc_get_size(*pbuf);
+}
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index c8739e9ed6..bfc4346d39 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -35,20 +35,36 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
int fd, void *buffer, size_t length,
int flags);
-struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len);
-int async_connect_recv(struct async_req *req, int *perrno);
-
-struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- int fd, const void *buffer, size_t length,
- int flags);
-ssize_t sendall_recv(struct async_req *req, int *perr);
-
-struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- int fd, void *buffer, size_t length,
- int flags);
-ssize_t recvall_recv(struct async_req *req, int *perr);
+
+struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, const void *buf, size_t len,
+ int flags);
+ssize_t async_send_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, void *buf, size_t len, int flags);
+ssize_t async_recv_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, const struct sockaddr *address,
+ socklen_t address_len);
+int async_connect_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ int fd, struct iovec *iov, int count);
+ssize_t writev_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, size_t initial,
+ ssize_t (*more)(uint8_t *buf,
+ size_t buflen,
+ void *private_data),
+ void *private_data);
+ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ uint8_t **pbuf, int *perrno);
#endif
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 16fac7327f..33747f0986 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include <talloc.h>
#include <sys/time.h>
+#include <../lib/replace/replace.h>
struct tevent_context;
struct tevent_ops;
diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c
new file mode 100644
index 0000000000..b89d5cd4d4
--- /dev/null
+++ b/lib/util/tevent_unix.c
@@ -0,0 +1,46 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap unix errno around tevent_req
+ Copyright (C) Volker Lendecke 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "tevent_unix.h"
+#include "../replace/replace.h"
+
+bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno)
+{
+ enum tevent_req_state state;
+ uint64_t err;
+
+ if (!tevent_req_is_error(req, &state, &err)) {
+ return false;
+ }
+ switch (state) {
+ case TEVENT_REQ_TIMED_OUT:
+ *perrno = ETIMEDOUT;
+ break;
+ case TEVENT_REQ_NO_MEMORY:
+ *perrno = ENOMEM;
+ break;
+ case TEVENT_REQ_USER_ERROR:
+ *perrno = err;
+ break;
+ default:
+ *perrno = EINVAL;
+ break;
+ }
+ return true;
+}
diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h
new file mode 100644
index 0000000000..dc3ffaef33
--- /dev/null
+++ b/lib/util/tevent_unix.h
@@ -0,0 +1,27 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap unix errno around tevent_req
+ Copyright (C) Volker Lendecke 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TEVENT_UNIX_H
+#define _TEVENT_UNIX_H
+
+#include "../tevent/tevent.h"
+
+bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno);
+
+#endif
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 4cd25c8cee..73b2989421 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -339,7 +339,8 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \
../lib/util/util.o ../lib/util/fsusage.o \
../lib/util/params.o ../lib/util/talloc_stack.o \
../lib/util/genrand.o ../lib/util/util_net.o \
- ../lib/util/become_daemon.o ../lib/util/system.o
+ ../lib/util/become_daemon.o ../lib/util/system.o \
+ ../lib/util/tevent_unix.o
CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \
../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3ca94b9192..daeef637ca 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1243,15 +1243,6 @@ bool is_valid_policy_hnd(const POLICY_HND *hnd);
bool policy_hnd_equal(const struct policy_handle *hnd1,
const struct policy_handle *hnd2);
const char *strip_hostname(const char *s);
-struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, size_t initial,
- ssize_t (*more)(uint8_t *buf, size_t buflen,
- void *priv),
- void *priv);
-ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- uint8_t **pbuf, int *perr);
-
/* The following definitions come from lib/util_file.c */
@@ -3117,7 +3108,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t,
bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name);
int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len);
void sort_query_replies(char *data, int n, struct in_addr ip);
-int name_mangle( char *In, char *Out, char name_type );
+char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type);
int name_extract(char *buf,int ofs, fstring name);
int name_len(char *s1);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index cda1fb474d..89f7be8e6c 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3145,102 +3145,3 @@ const char *strip_hostname(const char *s)
return s;
}
-
-struct read_pkt_state {
- struct event_context *ev;
- int fd;
- uint8_t *buf;
- ssize_t (*more)(uint8_t *buf, size_t buflen, void *priv);
- void *priv;
-};
-
-static void read_pkt_done(struct async_req *subreq);
-
-struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, size_t initial,
- ssize_t (*more)(uint8_t *buf, size_t buflen,
- void *priv),
- void *priv)
-{
- struct async_req *result, *subreq;
- struct read_pkt_state *state;
-
- if (!async_req_setup(mem_ctx, &result, &state,
- struct read_pkt_state)) {
- return NULL;
- }
- state->ev = ev;
- state->fd = fd;
- state->more = more;
-
- state->buf = talloc_array(state, uint8_t, initial);
- if (state->buf == NULL) {
- goto fail;
- }
- subreq = recvall_send(state, ev, fd, state->buf, initial, 0);
- if (subreq == NULL) {
- goto fail;
- }
- subreq->async.fn = read_pkt_done;
- subreq->async.priv = result;
- return result;
- fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void read_pkt_done(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct read_pkt_state *state = talloc_get_type_abort(
- req->private_data, struct read_pkt_state);
- size_t current_size;
- ssize_t received;
- ssize_t more;
- int err;
-
- received = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (received == -1) {
- async_req_error(req, err);
- return;
- }
- current_size = talloc_get_size(state->buf);
-
- more = state->more(state->buf, current_size, state->priv);
- if (more < 0) {
- async_req_error(req, EIO);
- return;
- }
- if (more == 0) {
- async_req_done(req);
- return;
- }
- state->buf = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t,
- current_size + more);
- if (async_req_nomem(state->buf, req)) {
- return;
- }
- subreq = recvall_send(state, state->ev, state->fd,
- state->buf + current_size, more, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
- subreq->async.fn = read_pkt_done;
- subreq->async.priv = req;
-}
-
-ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- uint8_t **pbuf, int *perr)
-{
- struct read_pkt_state *state = talloc_get_type_abort(
- req->private_data, struct read_pkt_state);
-
- if (async_req_is_errno(req, perr)) {
- return -1;
- }
- *pbuf = talloc_move(mem_ctx, &state->buf);
- return talloc_get_size(*pbuf);
-}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index c46aa2ac49..83e8a9d355 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -953,7 +953,7 @@ struct open_socket_out_state {
int wait_nsec;
};
-static void open_socket_out_connected(struct async_req *subreq);
+static void open_socket_out_connected(struct tevent_req *subreq);
static int open_socket_out_state_destructor(struct open_socket_out_state *s)
{
@@ -974,7 +974,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
int timeout)
{
char addr[INET6_ADDRSTRLEN];
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct open_socket_out_state *state;
NTSTATUS status;
@@ -1026,13 +1027,14 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
(struct sockaddr *)&state->ss,
state->salen);
if ((subreq == NULL)
- || !async_req_set_timeout(subreq, state->ev,
- timeval_set(0, state->wait_nsec))) {
+ || !tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(0, state->wait_nsec))) {
status = NT_STATUS_NO_MEMORY;
goto post_status;
}
subreq->async.fn = open_socket_out_connected;
- subreq->async.priv = result;
+ subreq->async.private_data = result;
return result;
post_status:
@@ -1045,18 +1047,18 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
return NULL;
}
-static void open_socket_out_connected(struct async_req *subreq)
+static void open_socket_out_connected(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct open_socket_out_state *state = talloc_get_type_abort(
req->private_data, struct open_socket_out_state);
- int err;
+ int ret;
int sys_errno;
- err = async_connect_recv(subreq, &sys_errno);
+ ret = async_connect_recv(subreq, &sys_errno);
TALLOC_FREE(subreq);
- if (err == 0) {
+ if (ret == 0) {
async_req_done(req);
return;
}
@@ -1083,13 +1085,14 @@ static void open_socket_out_connected(struct async_req *subreq)
if (async_req_nomem(subreq, req)) {
return;
}
- if (!async_req_set_timeout(subreq, state->ev,
- timeval_set(0, state->wait_nsec))) {
+ if (!tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(0, state->wait_nsec))) {
async_req_error(req, ENOMEM);
return;
}
subreq->async.fn = open_socket_out_connected;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
return;
}
diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
index 9bf6f29105..a5adf8f108 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -27,9 +27,7 @@
struct req_read_state {
struct winbindd_request *wb_req;
- struct tevent_context *ev;
size_t max_extra_data;
- int fd;
};
bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
@@ -83,145 +81,91 @@ wbcErr async_req_simple_recv_wbcerr(struct async_req *req)
return WBC_ERR_SUCCESS;
}
-static void wb_req_read_len(struct async_req *subreq);
-static void wb_req_read_main(struct async_req *subreq);
-static void wb_req_read_extra(struct async_req *subreq);
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_req_read_done(struct tevent_req *subreq);
struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int fd, size_t max_extra_data)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct req_read_state *state;
if (!async_req_setup(mem_ctx, &result, &state,
struct req_read_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
state->max_extra_data = max_extra_data;
- state->wb_req = talloc(state, struct winbindd_request);
- if (state->wb_req == NULL) {
- goto nomem;
- }
- subreq = recvall_send(state, ev, state->fd, &(state->wb_req->length),
- sizeof(state->wb_req->length), 0);
+ subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state);
if (subreq == NULL) {
goto nomem;
}
- subreq->async.fn = wb_req_read_len;
- subreq->async.priv = result;
+ subreq->async.fn = wb_req_read_done;
+ subreq->async.private_data = result;
return result;
-
nomem:
TALLOC_FREE(result);
return NULL;
}
-static void wb_req_read_len(struct async_req *subreq)
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
- req->private_data, struct req_read_state);
- int err;
- ssize_t ret;
-
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
+ private_data, struct req_read_state);
+ struct winbindd_request *req = (struct winbindd_request *)buf;
- if (state->wb_req->length != sizeof(struct winbindd_request)) {
- DEBUG(0, ("wb_req_read_len: Invalid request size received: "
- "%d (expected %d)\n", (int)state->wb_req->length,
- (int)sizeof(struct winbindd_request)));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
+ if (buflen == 4) {
+ if (req->length != sizeof(struct winbindd_request)) {
+ DEBUG(0, ("wb_req_read_len: Invalid request size "
+ "received: %d (expected %d)\n",
+ (int)req->length,
+ (int)sizeof(struct winbindd_request)));
+ return -1;
+ }
+ return sizeof(struct winbindd_request) - 4;
}
- subreq = recvall_send(
- req, state->ev, state->fd, (uint32 *)(state->wb_req)+1,
- sizeof(struct winbindd_request) - sizeof(uint32), 0);
- if (async_req_nomem(subreq, req)) {
- return;
+ if ((state->max_extra_data != 0)
+ && (req->extra_len > state->max_extra_data)) {
+ DEBUG(3, ("Got request with %d bytes extra data on "
+ "unprivileged socket\n", (int)req->extra_len));
+ return -1;
}
- subreq->async.fn = wb_req_read_main;
- subreq->async.priv = req;
+ return req->extra_len;
}
-static void wb_req_read_main(struct async_req *subreq)
+static void wb_req_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
req->private_data, struct req_read_state);
int err;
ssize_t ret;
+ uint8_t *buf;
- ret = recvall_recv(subreq, &err);
+ ret = read_packet_recv(subreq, state, &buf, &err);
TALLOC_FREE(subreq);
- if (ret < 0) {
+ if (ret == -1) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
- if ((state->max_extra_data != 0)
- && (state->wb_req->extra_len > state->max_extra_data)) {
- DEBUG(3, ("Got request with %d bytes extra data on "
- "unprivileged socket\n",
- (int)state->wb_req->extra_len));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
- }
-
- if (state->wb_req->extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- state->wb_req->extra_data.data = TALLOC_ARRAY(
- state->wb_req, char, state->wb_req->extra_len + 1);
- if (async_req_nomem(state->wb_req->extra_data.data, req)) {
- return;
- }
-
- state->wb_req->extra_data.data[state->wb_req->extra_len] = 0;
-
- subreq = recvall_send(
- req, state->ev, state->fd, state->wb_req->extra_data.data,
- state->wb_req->extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_req_read_extra;
- subreq->async.priv = req;
-}
-
-static void wb_req_read_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
+ state->wb_req = (struct winbindd_request *)buf;
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
+ if (state->wb_req->extra_len != 0) {
+ state->wb_req->extra_data.data =
+ (char *)buf + sizeof(struct winbindd_request);
+ } else {
+ state->wb_req->extra_data.data = NULL;
}
async_req_done(req);
}
-
wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_request **preq)
{
@@ -237,90 +181,60 @@ wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
}
struct req_write_state {
- struct winbindd_request *wb_req;
- struct tevent_context *ev;
- int fd;
+ struct iovec iov[2];
};
-static void wb_req_write_main(struct async_req *subreq);
-static void wb_req_write_extra(struct async_req *subreq);
+static void wb_req_write_done(struct tevent_req *subreq);
struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd,
struct winbindd_request *wb_req)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct req_write_state *state;
+ int count = 1;
if (!async_req_setup(mem_ctx, &result, &state,
struct req_write_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_req = wb_req;
- subreq = sendall_send(state, state->ev, state->fd, state->wb_req,
- sizeof(struct winbindd_request), 0);
- if (subreq == NULL) {
- goto nomem;
+ state->iov[0].iov_base = wb_req;
+ state->iov[0].iov_len = sizeof(struct winbindd_request);
+
+ if (wb_req->extra_len != 0) {
+ state->iov[1].iov_base = wb_req->extra_data.data;
+ state->iov[1].iov_len = wb_req->extra_len;
+ count = 2;
}
- subreq->async.fn = wb_req_write_main;
- subreq->async.priv = result;
+ subreq = writev_send(state, ev, fd, state->iov, count);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_req_write_done;
+ subreq->async.private_data = result;
return result;
- nomem:
+ fail:
TALLOC_FREE(result);
return NULL;
}
-static void wb_req_write_main(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct req_write_state *state = talloc_get_type_abort(
- req->private_data, struct req_write_state);
- int err;
- ssize_t ret;
-
- ret = sendall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (state->wb_req->extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- subreq = sendall_send(state, state->ev, state->fd,
- state->wb_req->extra_data.data,
- state->wb_req->extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_req_write_extra;
- subreq->async.priv = req;
-}
-
-static void wb_req_write_extra(struct async_req *subreq)
+static void wb_req_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
int err;
ssize_t ret;
- ret = sendall_recv(subreq, &err);
+ ret = writev_recv(subreq, &err);
TALLOC_FREE(subreq);
if (ret < 0) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
-
async_req_done(req);
}
@@ -331,40 +245,29 @@ wbcErr wb_req_write_recv(struct async_req *req)
struct resp_read_state {
struct winbindd_response *wb_resp;
- struct tevent_context *ev;
- size_t max_extra_data;
- int fd;
};
-static void wb_resp_read_len(struct async_req *subreq);
-static void wb_resp_read_main(struct async_req *subreq);
-static void wb_resp_read_extra(struct async_req *subreq);
+static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_resp_read_done(struct tevent_req *subreq);
struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct resp_read_state *state;
if (!async_req_setup(mem_ctx, &result, &state,
struct resp_read_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_resp = talloc(state, struct winbindd_response);
- if (state->wb_resp == NULL) {
- goto nomem;
- }
- subreq = recvall_send(state, ev, state->fd, &(state->wb_resp->length),
- sizeof(state->wb_resp->length), 0);
+ subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state);
if (subreq == NULL) {
goto nomem;
}
-
- subreq->async.fn = wb_resp_read_len;
- subreq->async.priv = result;
+ subreq->async.fn = wb_resp_read_done;
+ subreq->async.private_data = result;
return result;
nomem:
@@ -372,100 +275,50 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
return NULL;
}
-static void wb_resp_read_len(struct async_req *subreq)
+static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct resp_read_state *state = talloc_get_type_abort(
- req->private_data, struct resp_read_state);
- int err;
- ssize_t ret;
-
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (state->wb_resp->length < sizeof(struct winbindd_response)) {
- DEBUG(0, ("wb_resp_read_len: Invalid response size received: "
- "%d (expected at least%d)\n",
- (int)state->wb_resp->length,
- (int)sizeof(struct winbindd_response)));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
- }
-
- subreq = recvall_send(
- req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1,
- sizeof(struct winbindd_response) - sizeof(uint32), 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_read_main;
- subreq->async.priv = req;
+ struct winbindd_response *resp = (struct winbindd_response *)buf;
+
+ if (buflen == 4) {
+ if (resp->length < sizeof(struct winbindd_response)) {
+ DEBUG(0, ("wb_resp_read_len: Invalid response size "
+ "received: %d (expected at least%d)\n",
+ (int)resp->length,
+ (int)sizeof(struct winbindd_response)));
+ return -1;
+ }
+ }
+ return resp->length - 4;
}
-static void wb_resp_read_main(struct async_req *subreq)
+static void wb_resp_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct resp_read_state *state = talloc_get_type_abort(
req->private_data, struct resp_read_state);
+ uint8_t *buf;
int err;
ssize_t ret;
- size_t extra_len;
- ret = recvall_recv(subreq, &err);
+ ret = read_packet_recv(subreq, state, &buf, &err);
TALLOC_FREE(subreq);
- if (ret < 0) {
+ if (ret == -1) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
- extra_len = state->wb_resp->length - sizeof(struct winbindd_response);
- if (extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- state->wb_resp->extra_data.data = TALLOC_ARRAY(
- state->wb_resp, char, extra_len+1);
- if (async_req_nomem(state->wb_resp->extra_data.data, req)) {
- return;
- }
- ((char *)state->wb_resp->extra_data.data)[extra_len] = 0;
-
- subreq = recvall_send(
- req, state->ev, state->fd, state->wb_resp->extra_data.data,
- extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_read_extra;
- subreq->async.priv = req;
-}
-
-static void wb_resp_read_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
+ state->wb_resp = (struct winbindd_response *)buf;
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
+ if (state->wb_resp->length > sizeof(struct winbindd_response)) {
+ state->wb_resp->extra_data.data =
+ (char *)buf + sizeof(struct winbindd_response);
+ } else {
+ state->wb_resp->extra_data.data = NULL;
}
async_req_done(req);
}
-
wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_response **presp)
{
@@ -481,91 +334,61 @@ wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
}
struct resp_write_state {
- struct winbindd_response *wb_resp;
- struct tevent_context *ev;
- int fd;
+ struct iovec iov[2];
};
-static void wb_resp_write_main(struct async_req *subreq);
-static void wb_resp_write_extra(struct async_req *subreq);
+static void wb_resp_write_done(struct tevent_req *subreq);
struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd,
struct winbindd_response *wb_resp)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct resp_write_state *state;
+ int count = 1;
if (!async_req_setup(mem_ctx, &result, &state,
struct resp_write_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_resp = wb_resp;
- subreq = sendall_send(state, state->ev, state->fd, state->wb_resp,
- sizeof(struct winbindd_response), 0);
- if (subreq == NULL) {
- goto nomem;
+ state->iov[0].iov_base = wb_resp;
+ state->iov[0].iov_len = sizeof(struct winbindd_response);
+
+ if (wb_resp->length > sizeof(struct winbindd_response)) {
+ state->iov[1].iov_base = wb_resp->extra_data.data;
+ state->iov[1].iov_len =
+ wb_resp->length - sizeof(struct winbindd_response);
+ count = 2;
}
- subreq->async.fn = wb_resp_write_main;
- subreq->async.priv = result;
+ subreq = writev_send(state, ev, fd, state->iov, count);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_resp_write_done;
+ subreq->async.private_data = result;
return result;
- nomem:
+ fail:
TALLOC_FREE(result);
return NULL;
}
-static void wb_resp_write_main(struct async_req *subreq)
+static void wb_resp_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct resp_write_state *state = talloc_get_type_abort(
- req->private_data, struct resp_write_state);
+ subreq->async.private_data, struct async_req);
int err;
ssize_t ret;
- ret = sendall_recv(subreq, &err);
+ ret = writev_recv(subreq, &err);
TALLOC_FREE(subreq);
if (ret < 0) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
-
- if (state->wb_resp->length == sizeof(struct winbindd_response)) {
- async_req_done(req);
- return;
- }
-
- subreq = sendall_send(
- state, state->ev, state->fd,
- state->wb_resp->extra_data.data,
- state->wb_resp->length - sizeof(struct winbindd_response), 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_write_extra;
- subreq->async.priv = req;
-}
-
-static void wb_resp_write_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
-
- ret = sendall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (err < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
async_req_done(req);
}
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index 4d3a609530..b8d55a944a 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -147,17 +147,30 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
return result;
}
+struct wb_connect_state {
+ int dummy;
+};
+
+static void wbc_connect_connected(struct tevent_req *subreq);
+
static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- const char *dir)
+ struct tevent_context *ev,
+ struct wb_context *wb_ctx,
+ const char *dir)
{
- struct async_req *req;
+ struct async_req *result;
+ struct tevent_req *subreq;
+ struct wb_connect_state *state;
struct sockaddr_un sunaddr;
struct stat st;
char *path = NULL;
wbcErr wbc_err;
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct wb_connect_state)) {
+ return NULL;
+ }
+
if (wb_ctx->fd != -1) {
close(wb_ctx->fd);
wb_ctx->fd = -1;
@@ -205,33 +218,46 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
goto post_status;
}
- req = async_connect_send(mem_ctx, ev, wb_ctx->fd,
- (struct sockaddr *)&sunaddr,
- sizeof(sunaddr));
- if (req == NULL) {
+ subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
+ (struct sockaddr *)&sunaddr,
+ sizeof(sunaddr));
+ if (subreq == NULL) {
goto nomem;
}
- if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) {
- TALLOC_FREE(req);
+ subreq->async.fn = wbc_connect_connected;
+ subreq->async.private_data = result;
+
+ if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
goto nomem;
}
- return req;
+ return result;
nomem:
wbc_err = WBC_ERR_NO_MEMORY;
post_status:
- req = async_req_new(mem_ctx);
- if (req == NULL) {
- return NULL;
- }
- if (async_post_error(req, ev, wbc_err)) {
- return req;
+ if (async_post_error(result, ev, wbc_err)) {
+ return result;
}
- TALLOC_FREE(req);
+ TALLOC_FREE(result);
return NULL;
}
+static void wbc_connect_connected(struct tevent_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct async_req);
+ int res, err;
+
+ res = async_connect_recv(subreq, &err);
+ TALLOC_FREE(subreq);
+ if (res == -1) {
+ async_req_error(req, map_wbc_err_from_errno(err));
+ return;
+ }
+ async_req_done(req);
+}
+
static wbcErr wb_connect_recv(struct async_req *req)
{
return async_req_simple_recv_wbcerr(req);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index dabfc398ce..ad11ee0ed4 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1642,6 +1642,7 @@ bool cli_session_request(struct cli_state *cli,
{
char *p;
int len = 4;
+ char *tmp;
/* 445 doesn't have session request */
if (cli->port == 445)
@@ -1651,14 +1652,30 @@ bool cli_session_request(struct cli_state *cli,
memcpy(&(cli->called ), called , sizeof(*called ));
/* put in the destination name */
+
+ tmp = name_mangle(talloc_tos(), cli->called.name,
+ cli->called.name_type);
+ if (tmp == NULL) {
+ return false;
+ }
+
p = cli->outbuf+len;
- name_mangle(cli->called .name, p, cli->called .name_type);
- len += name_len(p);
+ memcpy(p, tmp, name_len(tmp));
+ len += name_len(tmp);
+ TALLOC_FREE(tmp);
/* and my name */
+
+ tmp = name_mangle(talloc_tos(), cli->calling.name,
+ cli->calling.name_type);
+ if (tmp == NULL) {
+ return false;
+ }
+
p = cli->outbuf+len;
- name_mangle(cli->calling.name, p, cli->calling.name_type);
- len += name_len(p);
+ memcpy(p, tmp, name_len(tmp));
+ len += name_len(tmp);
+ TALLOC_FREE(tmp);
/* send a session request (RFC 1002) */
/* setup the packet length
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 02b13ae63e..5f3eda44fe 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -1279,12 +1279,19 @@ static int name_interpret(char *in, fstring name)
Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
****************************************************************************/
-int name_mangle( char *In, char *Out, char name_type )
+char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type)
{
int i;
int len;
nstring buf;
- char *p = Out;
+ char *result;
+ char *p;
+
+ result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2);
+ if (result == NULL) {
+ return NULL;
+ }
+ p = result;
/* Safely copy the input string, In, into buf[]. */
if (strcmp(In,"*") == 0)
@@ -1321,7 +1328,7 @@ int name_mangle( char *In, char *Out, char name_type )
p[0] = len;
if( len > 0 )
p[len+1] = 0;
- return( name_len(Out) );
+ return result;
case '.':
p[0] = len;
p += (len + 1);
@@ -1333,7 +1340,7 @@ int name_mangle( char *In, char *Out, char name_type )
}
}
- return( name_len(Out) );
+ return result;
}
/****************************************************************************
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 6dead2d264..33e89c8acb 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1171,13 +1171,12 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
struct np_write_state {
struct event_context *ev;
struct np_proxy_state *p;
- const uint8_t *data;
- size_t len;
+ struct iovec iov;
ssize_t nwritten;
};
static void np_write_trigger(struct async_req *req);
-static void np_write_done(struct async_req *subreq);
+static void np_write_done(struct tevent_req *subreq);
struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct fake_file_handle *handle,
@@ -1218,8 +1217,8 @@ struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
state->ev = ev;
state->p = p;
- state->data = data;
- state->len = len;
+ state->iov.iov_base = CONST_DISCARD(void *, data);
+ state->iov.iov_len = len;
if (!async_req_enqueue(p->write_queue, ev, result,
np_write_trigger)) {
@@ -1242,27 +1241,26 @@ static void np_write_trigger(struct async_req *req)
{
struct np_write_state *state = talloc_get_type_abort(
req->private_data, struct np_write_state);
- struct async_req *subreq;
+ struct tevent_req *subreq;
- subreq = sendall_send(state, state->ev, state->p->fd, state->data,
- state->len, 0);
+ subreq = writev_send(state, state->ev, state->p->fd, &state->iov, 1);
if (async_req_nomem(subreq, req)) {
return;
}
subreq->async.fn = np_write_done;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
}
-static void np_write_done(struct async_req *subreq)
+static void np_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct np_write_state *state = talloc_get_type_abort(
req->private_data, struct np_write_state);
ssize_t received;
int err;
- received = sendall_recv(subreq, &err);
+ received = writev_recv(subreq, &err);
if (received < 0) {
async_req_nterror(req, map_nt_error_from_unix(err));
return;
@@ -1316,7 +1314,7 @@ struct np_read_state {
};
static void np_read_trigger(struct async_req *req);
-static void np_read_done(struct async_req *subreq);
+static void np_read_done(struct tevent_req *subreq);
struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct fake_file_handle *handle,
@@ -1393,28 +1391,28 @@ static void np_read_trigger(struct async_req *req)
{
struct np_read_state *state = talloc_get_type_abort(
req->private_data, struct np_read_state);
- struct async_req *subreq;
+ struct tevent_req *subreq;
- subreq = read_pkt_send(state, state->ev, state->p->fd, RPC_HEADER_LEN,
- rpc_frag_more_fn, NULL);
+ subreq = read_packet_send(state, state->ev, state->p->fd,
+ RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
if (async_req_nomem(subreq, req)) {
return;
}
subreq->async.fn = np_read_done;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
}
-static void np_read_done(struct async_req *subreq)
+static void np_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct np_read_state *state = talloc_get_type_abort(
req->private_data, struct np_read_state);
ssize_t received;
size_t thistime;
int err;
- received = read_pkt_recv(subreq, state->p, &state->p->msg, &err);
+ received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
TALLOC_FREE(subreq);
if (received == -1) {
async_req_nterror(req, map_nt_error_from_unix(err));
diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c
index 1fdea818d6..39a264011e 100644
--- a/source3/utils/smbfilter.c
+++ b/source3/utils/smbfilter.c
@@ -91,8 +91,15 @@ static void filter_request(char *buf)
d_printf("sesion_request: %s -> %s\n",
name1, name2);
if (netbiosname) {
- /* replace the destination netbios name */
- name_mangle(netbiosname, buf+4, 0x20);
+ char *mangled = name_mangle(
+ talloc_tos(), netbiosname, 0x20);
+ if (mangled != NULL) {
+ /* replace the destination netbios
+ * name */
+ memcpy(buf+4, mangled,
+ name_len(mangled));
+ TALLOC_FREE(mangled);
+ }
}
}
return;
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 0fa638e863..f1c063ed90 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -47,7 +47,8 @@ struct server_pipe_state {
static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_ServerReqChallenge *r)
{
- struct server_pipe_state *pipe_state = dce_call->context->private_data;
+ struct server_pipe_state *pipe_state =
+ (struct server_pipe_state *)dce_call->context->private_data;
ZERO_STRUCTP(r->out.return_credentials);
@@ -76,7 +77,8 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal
static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_ServerAuthenticate3 *r)
{
- struct server_pipe_state *pipe_state = dce_call->context->private_data;
+ struct server_pipe_state *pipe_state =
+ (struct server_pipe_state *)dce_call->context->private_data;
struct creds_CredentialState *creds;
void *sam_ctx;
struct samr_Password *mach_pwd;
@@ -148,7 +150,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
}
/* pull the user attributes */
- num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs,
+ num_records = gendb_search((struct ldb_context *)sam_ctx,
+ mem_ctx, NULL, &msgs,
+ trust_dom_attrs,
"(&(trustPartner=%s)(objectclass=trustedDomain))",
encoded_account);
@@ -179,7 +183,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
}
/* pull the user attributes */
- num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
+ num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
+ NULL, &msgs, attrs,
"(&(sAMAccountName=%s)(objectclass=user))",
ldb_binary_encode_string(mem_ctx, account_name));
@@ -848,13 +853,14 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C
return WERR_DS_SERVICE_UNAVAILABLE;
}
- domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
+ domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx,
r->in.domainname);
if (domain_dn == NULL) {
return WERR_DS_SERVICE_UNAVAILABLE;
}
- ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
+ ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ domain_dn, &res, attrs);
if (ret != 1) {
return WERR_NO_SUCH_DOMAIN;
}
@@ -1218,13 +1224,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
}
- domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
+ domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx,
+ mem_ctx,
r->in.domain_name);
if (domain_dn == NULL) {
return WERR_DS_SERVICE_UNAVAILABLE;
}
- ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
+ ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ domain_dn, &res, attrs);
if (ret != 1) {
return WERR_NO_SUCH_DOMAIN;
}
@@ -1377,9 +1385,11 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
return WERR_GENERAL_FAILURE;
}
- partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
+ partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx,
+ mem_ctx);
- ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
+ ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
+ &dom_res, dom_attrs);
if (ret == -1) {
return WERR_GENERAL_FAILURE;
}
@@ -1387,7 +1397,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
return WERR_GENERAL_FAILURE;
}
- ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
+ ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
+ partitions_basedn, &ref_res, ref_attrs,
"(&(objectClass=crossRef)(ncName=%s))",
ldb_dn_get_linearized(dom_res[0]->dn));
if (ret == -1) {