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:
parent
272a58afff
commit
d67e614a07
@ -217,6 +217,10 @@ struct async_connect_state {
|
||||
long old_sockflags;
|
||||
socklen_t address_len;
|
||||
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,
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
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 tevent_req *async_connect_send(
|
||||
TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
|
||||
const struct sockaddr *address, socklen_t address_len,
|
||||
void (*before_connect)(void *private_data),
|
||||
void (*after_connect)(void *private_data),
|
||||
void *private_data)
|
||||
{
|
||||
struct tevent_req *result;
|
||||
struct async_connect_state *state;
|
||||
@ -258,6 +264,9 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
state->fd = fd;
|
||||
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);
|
||||
if (state->old_sockflags == -1) {
|
||||
@ -273,7 +282,16 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
set_blocking(fd, false);
|
||||
|
||||
if (state->before_connect != NULL) {
|
||||
state->before_connect(state->private_data);
|
||||
}
|
||||
|
||||
state->result = connect(fd, address, address_len);
|
||||
|
||||
if (state->after_connect != NULL) {
|
||||
state->after_connect(state->private_data);
|
||||
}
|
||||
|
||||
if (state->result == 0) {
|
||||
tevent_req_done(result);
|
||||
goto done;
|
||||
@ -328,8 +346,17 @@ static void async_connect_connected(struct tevent_context *ev,
|
||||
tevent_req_data(req, struct async_connect_state);
|
||||
int ret;
|
||||
|
||||
if (state->before_connect != NULL) {
|
||||
state->before_connect(state->private_data);
|
||||
}
|
||||
|
||||
ret = connect(state->fd, (struct sockaddr *)(void *)&state->address,
|
||||
state->address_len);
|
||||
|
||||
if (state->after_connect != NULL) {
|
||||
state->after_connect(state->private_data);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
state->sys_errno = 0;
|
||||
TALLOC_FREE(fde);
|
||||
|
@ -40,10 +40,12 @@ struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx,
|
||||
socklen_t *addr_len);
|
||||
ssize_t recvfrom_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);
|
||||
struct tevent_req *async_connect_send(
|
||||
TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
|
||||
const struct sockaddr *address, 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);
|
||||
|
||||
struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
|
||||
|
@ -83,7 +83,7 @@ struct tevent_req *ctdb_conn_init_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
subreq = async_connect_send(state, ev, state->conn->fd,
|
||||
(struct sockaddr *)&state->addr,
|
||||
sizeof(state->addr));
|
||||
sizeof(state->addr), NULL, NULL, NULL);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
subreq = async_connect_send(state, state->ev, state->fd,
|
||||
(struct sockaddr *)&state->ss,
|
||||
state->salen);
|
||||
state->salen, NULL, NULL, NULL);
|
||||
if ((subreq == NULL)
|
||||
|| !tevent_req_set_endtime(
|
||||
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,
|
||||
(struct sockaddr *)&state->ss,
|
||||
state->salen);
|
||||
state->salen, NULL, NULL, NULL);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
subreq = async_connect_send(state, ev, state->reader->sock,
|
||||
(struct sockaddr *)(void *)&state->addr,
|
||||
sizeof(state->addr));
|
||||
sizeof(state->addr), NULL, NULL, NULL);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
@ -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,
|
||||
(struct sockaddr *)(void *)&sunaddr,
|
||||
sizeof(sunaddr));
|
||||
sizeof(sunaddr), NULL, NULL, NULL);
|
||||
if (subreq == NULL) {
|
||||
goto nomem;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user