mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +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;
|
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);
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user