Fix an uninitialized variable in wb_context_init
[ira/wip.git] / source3 / lib / wbclient.c
index 3cf992c7de9a8ec95208bcbbf5b84086c679b359..0d310d821b2d985b5c14ce283558ee20a447051d 100644 (file)
 #include "includes.h"
 #include "wbc_async.h"
 
+wbcErr map_wbc_err_from_errno(int error)
+{
+       switch(error) {
+       case EPERM:
+       case EACCES:
+               return WBC_ERR_AUTH_ERROR;
+       case ENOMEM:
+               return WBC_ERR_NO_MEMORY;
+       case EIO:
+       default:
+               return WBC_ERR_UNKNOWN_FAILURE;
+       }
+}
+
+bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err)
+{
+       enum tevent_req_state state;
+       uint64_t error;
+       if (!tevent_req_is_error(req, &state, &error)) {
+               *pwbc_err = WBC_ERR_SUCCESS;
+               return false;
+       }
+
+       switch (state) {
+       case TEVENT_REQ_USER_ERROR:
+               *pwbc_err = error;
+               break;
+       case TEVENT_REQ_TIMED_OUT:
+               *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
+               break;
+       case TEVENT_REQ_NO_MEMORY:
+               *pwbc_err = WBC_ERR_NO_MEMORY;
+               break;
+       default:
+               *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
+               break;
+       }
+       return true;
+}
+
+wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req)
+{
+       wbcErr wbc_err;
+
+       if (tevent_req_is_wbcerr(req, &wbc_err)) {
+               return wbc_err;
+       }
+
+       return WBC_ERR_SUCCESS;
+}
+
 struct wb_context {
        struct tevent_queue *queue;
        int fd;
@@ -115,27 +166,6 @@ static int make_safe_fd(int fd)
        return -1;
 }
 
-static bool winbind_closed_fd(int fd)
-{
-       struct timeval tv;
-       fd_set r_fds;
-
-       if (fd == -1) {
-               return true;
-       }
-
-       FD_ZERO(&r_fds);
-       FD_SET(fd, &r_fds);
-       ZERO_STRUCT(tv);
-
-       if ((select(fd+1, &r_fds, NULL, NULL, &tv) == -1)
-           || FD_ISSET(fd, &r_fds)) {
-               return true;
-       }
-
-       return false;
-}
-
 struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
 {
        struct wb_context *result;
@@ -150,6 +180,7 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
                return NULL;
        }
        result->fd = -1;
+       result->is_priv = false;
        return result;
 }
 
@@ -224,7 +255,7 @@ static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx,
        }
 
        subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
-                                   (struct sockaddr *)&sunaddr,
+                                   (struct sockaddr *)(void *)&sunaddr,
                                    sizeof(sunaddr));
        if (subreq == NULL) {
                goto nomem;
@@ -265,111 +296,6 @@ static wbcErr wb_connect_recv(struct tevent_req *req)
        return tevent_req_simple_recv_wbcerr(req);
 }
 
-struct wb_int_trans_state {
-       struct tevent_context *ev;
-       int fd;
-       struct winbindd_request *wb_req;
-       struct winbindd_response *wb_resp;
-};
-
-static void wb_int_trans_write_done(struct tevent_req *subreq);
-static void wb_int_trans_read_done(struct tevent_req *subreq);
-
-static struct tevent_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
-                                           struct tevent_context *ev,
-                                           struct tevent_queue *queue, int fd,
-                                           struct winbindd_request *wb_req)
-{
-       struct tevent_req *result, *subreq;
-       struct wb_int_trans_state *state;
-
-       result = tevent_req_create(mem_ctx, &state,
-                                  struct wb_int_trans_state);
-       if (result == NULL) {
-               return NULL;
-       }
-
-       if (winbind_closed_fd(fd)) {
-               tevent_req_error(result, WBC_ERR_WINBIND_NOT_AVAILABLE);
-               return tevent_req_post(result, ev);
-       }
-
-       state->ev = ev;
-       state->fd = fd;
-       state->wb_req = wb_req;
-       state->wb_req->length = sizeof(struct winbindd_request);
-       state->wb_req->pid = getpid();
-
-       subreq = wb_req_write_send(state, state->ev, queue, state->fd,
-                                  state->wb_req);
-       if (subreq == NULL) {
-               goto fail;
-       }
-       tevent_req_set_callback(subreq, wb_int_trans_write_done, result);
-
-       return result;
-
- fail:
-       TALLOC_FREE(result);
-       return NULL;
-}
-
-static void wb_int_trans_write_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct wb_int_trans_state *state = tevent_req_data(
-               req, struct wb_int_trans_state);
-       wbcErr wbc_err;
-
-       wbc_err = wb_req_write_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!WBC_ERROR_IS_OK(wbc_err)) {
-               tevent_req_error(req, wbc_err);
-               return;
-       }
-
-       subreq = wb_resp_read_send(state, state->ev, state->fd);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, wb_int_trans_read_done, req);
-}
-
-static void wb_int_trans_read_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct wb_int_trans_state *state = tevent_req_data(
-               req, struct wb_int_trans_state);
-       wbcErr wbc_err;
-
-       wbc_err = wb_resp_read_recv(subreq, state, &state->wb_resp);
-       TALLOC_FREE(subreq);
-       if (!WBC_ERROR_IS_OK(wbc_err)) {
-               tevent_req_error(req, wbc_err);
-               return;
-       }
-
-       tevent_req_done(req);
-}
-
-static wbcErr wb_int_trans_recv(struct tevent_req *req,
-                               TALLOC_CTX *mem_ctx,
-                               struct winbindd_response **presponse)
-{
-       struct wb_int_trans_state *state = tevent_req_data(
-               req, struct wb_int_trans_state);
-       wbcErr wbc_err;
-
-       if (tevent_req_is_wbcerr(req, &wbc_err)) {
-               return wbc_err;
-       }
-
-       *presponse = talloc_move(mem_ctx, &state->wb_resp);
-       return WBC_ERR_SUCCESS;
-}
-
 static const char *winbindd_socket_dir(void)
 {
 #ifdef SOCKET_WRAPPER
@@ -448,9 +374,10 @@ static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
 
        ZERO_STRUCT(state->wb_req);
        state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
+       state->wb_req.pid = getpid();
 
-       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
-                                  &state->wb_req);
+       subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+                                     state->wb_ctx->fd, &state->wb_req);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -464,12 +391,12 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq)
        struct wb_open_pipe_state *state = tevent_req_data(
                req, struct wb_open_pipe_state);
        struct winbindd_response *wb_resp;
-       wbcErr wbc_err;
+       int ret, err;
 
-       wbc_err = wb_int_trans_recv(subreq, state, &wb_resp);
+       ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err);
        TALLOC_FREE(subreq);
-       if (!WBC_ERROR_IS_OK(wbc_err)) {
-               tevent_req_error(req, wbc_err);
+       if (ret == -1) {
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
 
@@ -479,9 +406,10 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq)
        }
 
        state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
+       state->wb_req.pid = getpid();
 
-       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
-                                  &state->wb_req);
+       subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+                                     state->wb_ctx->fd, &state->wb_req);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -495,12 +423,12 @@ static void wb_open_pipe_getpriv_done(struct tevent_req *subreq)
        struct wb_open_pipe_state *state = tevent_req_data(
                req, struct wb_open_pipe_state);
        struct winbindd_response *wb_resp = NULL;
-       wbcErr wbc_err;
+       int ret, err;
 
-       wbc_err = wb_int_trans_recv(subreq, state, &wb_resp);
+       ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err);
        TALLOC_FREE(subreq);
-       if (!WBC_ERROR_IS_OK(wbc_err)) {
-               tevent_req_error(req, wbc_err);
+       if (ret == -1) {
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
 
@@ -580,8 +508,10 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
                return req;
        }
 
-       subreq = wb_int_trans_send(state, ev, wb_ctx->queue, wb_ctx->fd,
-                                  wb_req);
+       state->wb_req->pid = getpid();
+
+       subreq = wb_simple_trans_send(state, ev, wb_ctx->queue, wb_ctx->fd,
+                                     wb_req);
        if (subreq == NULL) {
                goto fail;
        }
@@ -673,8 +603,8 @@ static void wb_trans_connect_done(struct tevent_req *subreq)
                return;
        }
 
-       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
-                                  state->wb_req);
+       subreq = wb_simple_trans_send(state, state->ev, state->wb_ctx->queue,
+                                     state->wb_ctx->fd, state->wb_req);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -687,12 +617,12 @@ static void wb_trans_done(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct wb_trans_state *state = tevent_req_data(
                req, struct wb_trans_state);
-       wbcErr wbc_err;
+       int ret, err;
 
-       wbc_err = wb_int_trans_recv(subreq, state, &state->wb_resp);
+       ret = wb_simple_trans_recv(subreq, state, &state->wb_resp, &err);
        TALLOC_FREE(subreq);
 
-       if (wb_trans_retry(req, state, wbc_err)) {
+       if (wb_trans_retry(req, state, map_wbc_err_from_errno(err))) {
                return;
        }