Convert wb_resp_read to tevent_req
[ira/wip.git] / source3 / lib / wbclient.c
index ae9a034cc8db3d74b17703846a2118b0ad89489f..d299914c7326eac0f6fd0b41c216a341a6744ff1 100644 (file)
@@ -18,8 +18,7 @@
 */
 
 #include "includes.h"
-#include "winbindd/winbindd.h"
-#include "winbindd/winbindd_proto.h"
+#include "wbc_async.h"
 
 static int make_nonstd_fd(int fd)
 {
@@ -131,12 +130,6 @@ static bool winbind_closed_fd(int fd)
        return false;
 }
 
-struct wb_context {
-       struct async_req_queue *queue;
-       int fd;
-       bool is_priv;
-};
-
 struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
 {
        struct wb_context *result;
@@ -154,16 +147,29 @@ 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;
-       NTSTATUS status;
+       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);
@@ -173,13 +179,13 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
        /* Check permissions on unix socket directory */
 
        if (lstat(dir, &st) == -1) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
                goto post_status;
        }
 
        if (!S_ISDIR(st.st_mode) ||
            (st.st_uid != 0 && st.st_uid != geteuid())) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
                goto post_status;
        }
 
@@ -202,48 +208,58 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
        if ((lstat(sunaddr.sun_path, &st) == -1)
            || !S_ISSOCK(st.st_mode)
            || (st.st_uid != 0 && st.st_uid != geteuid())) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
                goto post_status;
        }
 
        wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0));
        if (wb_ctx->fd == -1) {
-               status = map_nt_error_from_unix(errno);
+               wbc_err = map_wbc_err_from_errno(errno);
                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);
+       tevent_req_set_callback(subreq, wbc_connect_connected, result);
+
+       if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
                goto nomem;
        }
 
-       return req;
+       return result;
 
  nomem:
-       status = NT_STATUS_NO_MEMORY;
+       wbc_err = WBC_ERR_NO_MEMORY;
  post_status:
-       req = async_req_new(mem_ctx);
-       if (req == NULL) {
-               return NULL;
-       }
-       if (async_post_ntstatus(req, ev, status)) {
-               return req;
+       if (async_post_error(result, ev, wbc_err)) {
+               return result;
        }
-       TALLOC_FREE(req);
+       TALLOC_FREE(result);
        return NULL;
 }
 
-static NTSTATUS wb_connect_recv(struct async_req *req)
+static void wbc_connect_connected(struct tevent_req *subreq)
 {
-       int dummy;
+       struct async_req *req =
+               tevent_req_callback_data(subreq, 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);
+}
 
-       return async_connect_recv(req, &dummy);
+static wbcErr wb_connect_recv(struct async_req *req)
+{
+       return async_req_simple_recv_wbcerr(req);
 }
 
 static struct winbindd_request *winbindd_request_copy(
@@ -278,15 +294,15 @@ struct wb_int_trans_state {
        struct winbindd_response *wb_resp;
 };
 
-static void wb_int_trans_write_done(struct async_req *subreq);
-static void wb_int_trans_read_done(struct async_req *subreq);
+static void wb_int_trans_write_done(struct tevent_req *subreq);
+static void wb_int_trans_read_done(struct tevent_req *subreq);
 
 static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
                                           struct tevent_context *ev, int fd,
                                           struct winbindd_request *wb_req)
 {
        struct async_req *result;
-       struct async_req *subreq;
+       struct tevent_req *subreq;
        struct wb_int_trans_state *state;
 
        if (!async_req_setup(mem_ctx, &result, &state,
@@ -295,8 +311,8 @@ static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
        }
 
        if (winbind_closed_fd(fd)) {
-               if (!async_post_ntstatus(result, ev,
-                                        NT_STATUS_PIPE_DISCONNECTED)) {
+               if (!async_post_error(result, ev,
+                                     WBC_ERR_WINBIND_NOT_AVAILABLE)) {
                        goto fail;
                }
                return result;
@@ -309,12 +325,12 @@ static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
        state->wb_req->length = sizeof(struct winbindd_request);
        state->wb_req->pid = getpid();
 
-       subreq = wb_req_write_send(state, state->ev, state->fd, state->wb_req);
+       subreq = wb_req_write_send(state, state->ev, NULL, state->fd,
+                                  state->wb_req);
        if (subreq == NULL) {
                goto fail;
        }
-       subreq->async.fn = wb_int_trans_write_done;
-       subreq->async.priv = result;
+       tevent_req_set_callback(subreq, wb_int_trans_write_done, result);
 
        return result;
 
@@ -323,61 +339,60 @@ static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
        return NULL;
 }
 
-static void wb_int_trans_write_done(struct async_req *subreq)
+static void wb_int_trans_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
+       struct async_req *req = tevent_req_callback_data(
+               subreq, struct async_req);
        struct wb_int_trans_state *state = talloc_get_type_abort(
                req->private_data, struct wb_int_trans_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_req_write_recv(subreq);
+       wbc_err = wb_req_write_recv(subreq);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(req, status);
+       if (!WBC_ERROR_IS_OK(wbc_err)) {
+               async_req_error(req, wbc_err);
                return;
        }
 
        subreq = wb_resp_read_send(state, state->ev, state->fd);
-       if (subreq == NULL) {
-               async_req_nterror(req, NT_STATUS_NO_MEMORY);
+       if (async_req_nomem(subreq, req)) {
+               return;
        }
-       subreq->async.fn = wb_int_trans_read_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_int_trans_read_done, req);
 }
 
-static void wb_int_trans_read_done(struct async_req *subreq)
+static void wb_int_trans_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
+       struct async_req *req = tevent_req_callback_data(
+               subreq, struct async_req);
        struct wb_int_trans_state *state = talloc_get_type_abort(
                req->private_data, struct wb_int_trans_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_resp_read_recv(subreq, state, &state->wb_resp);
+       wbc_err = wb_resp_read_recv(subreq, state, &state->wb_resp);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(req, status);
+       if (!WBC_ERROR_IS_OK(wbc_err)) {
+               async_req_error(req, wbc_err);
                return;
        }
 
        async_req_done(req);
 }
 
-static NTSTATUS wb_int_trans_recv(struct async_req *req,
-                                 TALLOC_CTX *mem_ctx,
-                                 struct winbindd_response **presponse)
+static wbcErr wb_int_trans_recv(struct async_req *req,
+                               TALLOC_CTX *mem_ctx,
+                               struct winbindd_response **presponse)
 {
        struct wb_int_trans_state *state = talloc_get_type_abort(
                req->private_data, struct wb_int_trans_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       if (async_req_is_nterror(req, &status)) {
-               return status;
+       if (async_req_is_wbcerr(req, &wbc_err)) {
+               return wbc_err;
        }
 
        *presponse = talloc_move(mem_ctx, &state->wb_resp);
-       return NT_STATUS_OK;
+       return WBC_ERR_SUCCESS;
 }
 
 static const char *winbindd_socket_dir(void)
@@ -448,13 +463,13 @@ static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
                subreq->async.priv, struct async_req);
        struct wb_open_pipe_state *state = talloc_get_type_abort(
                req->private_data, struct wb_open_pipe_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_connect_recv(subreq);
+       wbc_err = wb_connect_recv(subreq);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (!WBC_ERROR_IS_OK(wbc_err)) {
                state->wb_ctx->is_priv = true;
-               async_req_nterror(req, status);
+               async_req_error(req, wbc_err);
                return;
        }
 
@@ -478,12 +493,12 @@ static void wb_open_pipe_ping_done(struct async_req *subreq)
        struct wb_open_pipe_state *state = talloc_get_type_abort(
                req->private_data, struct wb_open_pipe_state);
        struct winbindd_response *wb_resp;
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_int_trans_recv(subreq, state, &wb_resp);
+       wbc_err = wb_int_trans_recv(subreq, state, &wb_resp);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(req, status);
+       if (!WBC_ERROR_IS_OK(wbc_err)) {
+               async_req_error(req, wbc_err);
                return;
        }
 
@@ -511,12 +526,12 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq)
        struct wb_open_pipe_state *state = talloc_get_type_abort(
                req->private_data, struct wb_open_pipe_state);
        struct winbindd_response *wb_resp = NULL;
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_int_trans_recv(subreq, state, &wb_resp);
+       wbc_err = wb_int_trans_recv(subreq, state, &wb_resp);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(req, status);
+       if (!WBC_ERROR_IS_OK(wbc_err)) {
+               async_req_error(req, wbc_err);
                return;
        }
 
@@ -540,21 +555,21 @@ static void wb_open_pipe_connect_priv_done(struct async_req *subreq)
                subreq->async.priv, struct async_req);
        struct wb_open_pipe_state *state = talloc_get_type_abort(
                req->private_data, struct wb_open_pipe_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_connect_recv(subreq);
+       wbc_err = wb_connect_recv(subreq);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(req, status);
+       if (!WBC_ERROR_IS_OK(wbc_err)) {
+               async_req_error(req, wbc_err);
                return;
        }
        state->wb_ctx->is_priv = true;
        async_req_done(req);
 }
 
-static NTSTATUS wb_open_pipe_recv(struct async_req *req)
+static wbcErr wb_open_pipe_recv(struct async_req *req)
 {
-       return async_req_simple_recv_ntstatus(req);
+       return async_req_simple_recv_wbcerr(req);
 }
 
 struct wb_trans_state {
@@ -631,27 +646,26 @@ struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 
 static bool wb_trans_retry(struct async_req *req,
                           struct wb_trans_state *state,
-                          NTSTATUS status)
+                          wbcErr wbc_err)
 {
        struct async_req *subreq;
 
-       if (NT_STATUS_IS_OK(status)) {
+       if (WBC_ERROR_IS_OK(wbc_err)) {
                return false;
        }
 
-       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)
-           || NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+       if (wbc_err == WBC_ERR_WINBIND_NOT_AVAILABLE) {
                /*
                 * Winbind not around or we can't connect to the pipe. Fail
                 * immediately.
                 */
-               async_req_nterror(req, status);
+               async_req_error(req, wbc_err);
                return true;
        }
 
        state->num_retries -= 1;
        if (state->num_retries == 0) {
-               async_req_nterror(req, status);
+               async_req_error(req, wbc_err);
                return true;
        }
 
@@ -685,7 +699,7 @@ static void wb_trans_retry_wait_done(struct async_req *subreq)
        ret = async_wait_recv(subreq);
        TALLOC_FREE(subreq);
        if (ret) {
-               async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               async_req_error(req, WBC_ERR_UNKNOWN_FAILURE);
                return;
        }
 
@@ -704,12 +718,12 @@ static void wb_trans_connect_done(struct async_req *subreq)
                subreq->async.priv, struct async_req);
        struct wb_trans_state *state = talloc_get_type_abort(
                req->private_data, struct wb_trans_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_open_pipe_recv(subreq);
+       wbc_err = wb_open_pipe_recv(subreq);
        TALLOC_FREE(subreq);
 
-       if (wb_trans_retry(req, state, status)) {
+       if (wb_trans_retry(req, state, wbc_err)) {
                return;
        }
 
@@ -729,29 +743,29 @@ static void wb_trans_done(struct async_req *subreq)
                subreq->async.priv, struct async_req);
        struct wb_trans_state *state = talloc_get_type_abort(
                req->private_data, struct wb_trans_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       status = wb_int_trans_recv(subreq, state, &state->wb_resp);
+       wbc_err = wb_int_trans_recv(subreq, state, &state->wb_resp);
        TALLOC_FREE(subreq);
 
-       if (wb_trans_retry(req, state, status)) {
+       if (wb_trans_retry(req, state, wbc_err)) {
                return;
        }
 
        async_req_done(req);
 }
 
-NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
-                      struct winbindd_response **presponse)
+wbcErr wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+                    struct winbindd_response **presponse)
 {
        struct wb_trans_state *state = talloc_get_type_abort(
                req->private_data, struct wb_trans_state);
-       NTSTATUS status;
+       wbcErr wbc_err;
 
-       if (async_req_is_nterror(req, &status)) {
-               return status;
+       if (async_req_is_wbcerr(req, &wbc_err)) {
+               return wbc_err;
        }
 
        *presponse = talloc_move(mem_ctx, &state->wb_resp);
-       return NT_STATUS_OK;
+       return WBC_ERR_SUCCESS;
 }