1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

lib: Add before/after hooks to async_connect

This will facilitiate [un]become_root for smbd to connect safely to ctdbd.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Christian Ambach <ambi@samba.org>
This commit is contained in:
Volker Lendecke 2013-05-16 16:11:54 +02:00 committed by Christian Ambach
parent 272a58afff
commit d67e614a07
6 changed files with 42 additions and 13 deletions

View File

@ -217,6 +217,10 @@ struct async_connect_state {
long old_sockflags; long old_sockflags;
socklen_t address_len; socklen_t address_len;
struct sockaddr_storage address; struct sockaddr_storage address;
void (*before_connect)(void *private_data);
void (*after_connect)(void *private_data);
void *private_data;
}; };
static void async_connect_connected(struct tevent_context *ev, static void async_connect_connected(struct tevent_context *ev,
@ -236,10 +240,12 @@ static void async_connect_connected(struct tevent_context *ev,
* connect in an async state. This will be reset when the request is finished. * connect in an async state. This will be reset when the request is finished.
*/ */
struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_req *async_connect_send(
struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
int fd, const struct sockaddr *address, const struct sockaddr *address, socklen_t address_len,
socklen_t address_len) void (*before_connect)(void *private_data),
void (*after_connect)(void *private_data),
void *private_data)
{ {
struct tevent_req *result; struct tevent_req *result;
struct async_connect_state *state; struct async_connect_state *state;
@ -258,6 +264,9 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
state->fd = fd; state->fd = fd;
state->sys_errno = 0; state->sys_errno = 0;
state->before_connect = before_connect;
state->after_connect = after_connect;
state->private_data = private_data;
state->old_sockflags = fcntl(fd, F_GETFL, 0); state->old_sockflags = fcntl(fd, F_GETFL, 0);
if (state->old_sockflags == -1) { if (state->old_sockflags == -1) {
@ -273,7 +282,16 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
set_blocking(fd, false); set_blocking(fd, false);
if (state->before_connect != NULL) {
state->before_connect(state->private_data);
}
state->result = connect(fd, address, address_len); state->result = connect(fd, address, address_len);
if (state->after_connect != NULL) {
state->after_connect(state->private_data);
}
if (state->result == 0) { if (state->result == 0) {
tevent_req_done(result); tevent_req_done(result);
goto done; goto done;
@ -328,8 +346,17 @@ static void async_connect_connected(struct tevent_context *ev,
tevent_req_data(req, struct async_connect_state); tevent_req_data(req, struct async_connect_state);
int ret; int ret;
if (state->before_connect != NULL) {
state->before_connect(state->private_data);
}
ret = connect(state->fd, (struct sockaddr *)(void *)&state->address, ret = connect(state->fd, (struct sockaddr *)(void *)&state->address,
state->address_len); state->address_len);
if (state->after_connect != NULL) {
state->after_connect(state->private_data);
}
if (ret == 0) { if (ret == 0) {
state->sys_errno = 0; state->sys_errno = 0;
TALLOC_FREE(fde); TALLOC_FREE(fde);

View File

@ -40,10 +40,12 @@ struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx,
socklen_t *addr_len); socklen_t *addr_len);
ssize_t recvfrom_recv(struct tevent_req *req, int *perrno); ssize_t recvfrom_recv(struct tevent_req *req, int *perrno);
struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_req *async_connect_send(
struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
int fd, const struct sockaddr *address, const struct sockaddr *address, socklen_t address_len,
socklen_t address_len); void (*before_connect)(void *private_data),
void (*after_connect)(void *private_data),
void *private_data);
int async_connect_recv(struct tevent_req *req, int *perrno); int async_connect_recv(struct tevent_req *req, int *perrno);
struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,

View File

@ -83,7 +83,7 @@ struct tevent_req *ctdb_conn_init_send(TALLOC_CTX *mem_ctx,
subreq = async_connect_send(state, ev, state->conn->fd, subreq = async_connect_send(state, ev, state->conn->fd,
(struct sockaddr *)&state->addr, (struct sockaddr *)&state->addr,
sizeof(state->addr)); sizeof(state->addr), NULL, NULL, NULL);
if (tevent_req_nomem(subreq, req)) { if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev); return tevent_req_post(req, ev);
} }

View File

@ -586,7 +586,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
subreq = async_connect_send(state, state->ev, state->fd, subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss, (struct sockaddr *)&state->ss,
state->salen); state->salen, NULL, NULL, NULL);
if ((subreq == NULL) if ((subreq == NULL)
|| !tevent_req_set_endtime( || !tevent_req_set_endtime(
subreq, state->ev, subreq, state->ev,
@ -638,7 +638,7 @@ static void open_socket_out_connected(struct tevent_req *subreq)
subreq = async_connect_send(state, state->ev, state->fd, subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss, (struct sockaddr *)&state->ss,
state->salen); state->salen, NULL, NULL, NULL);
if (tevent_req_nomem(subreq, req)) { if (tevent_req_nomem(subreq, req)) {
return; return;
} }

View File

@ -514,7 +514,7 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
subreq = async_connect_send(state, ev, state->reader->sock, subreq = async_connect_send(state, ev, state->reader->sock,
(struct sockaddr *)(void *)&state->addr, (struct sockaddr *)(void *)&state->addr,
sizeof(state->addr)); sizeof(state->addr), NULL, NULL, NULL);
if (tevent_req_nomem(subreq, req)) { if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev); return tevent_req_post(req, ev);
} }

View File

@ -288,7 +288,7 @@ static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx,
subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd, subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
(struct sockaddr *)(void *)&sunaddr, (struct sockaddr *)(void *)&sunaddr,
sizeof(sunaddr)); sizeof(sunaddr), NULL, NULL, NULL);
if (subreq == NULL) { if (subreq == NULL) {
goto nomem; goto nomem;
} }