s4:winbind: convert wb_sid2domain to tevent_req internally
authorStefan Metzmacher <metze@samba.org>
Thu, 23 Aug 2012 11:14:17 +0000 (13:14 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 24 Aug 2012 23:39:41 +0000 (01:39 +0200)
The public wrapper still uses composite_context, because I don't
have time to fix all the callers...

metze

source4/winbind/wb_sid2domain.c

index 62854a2b6ac1a8efdfadb6ce12f2f128f8f43813..637fe1d8afcc208c0c4b8af55414d54e95627eb9 100644 (file)
@@ -20,6 +20,8 @@
 */
 
 #include "includes.h"
+#include <tevent.h>
+#include "../lib/util/tevent_ntstatus.h"
 #include "libcli/composite/composite.h"
 #include "winbind/wb_server.h"
 #include "smbd/service_task.h"
@@ -43,43 +45,42 @@ static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
        return domain;
 }
 
-struct sid2domain_state {
-       struct composite_context *ctx;
+struct wb_sid2domain_state {
        struct wbsrv_service *service;
-       struct dom_sid *sid;
+       struct dom_sid sid;
 
        struct wbsrv_domain *domain;
 };
 
-static void sid2domain_recv_dom_info(struct composite_context *ctx);
-static void sid2domain_recv_name(struct composite_context *ctx);
-static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx);
-static void sid2domain_recv_init(struct composite_context *ctx);
+static void wb_sid2domain_recv_dom_info(struct composite_context *ctx);
+static void wb_sid2domain_recv_name(struct composite_context *ctx);
+static void wb_sid2domain_recv_trusted_dom_info(struct composite_context *ctx);
+static void wb_sid2domain_recv_init(struct composite_context *ctx);
 
-struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
-                                            struct wbsrv_service *service,
-                                            const struct dom_sid *sid)
+static struct tevent_req *_wb_sid2domain_send(TALLOC_CTX *mem_ctx,
+                                             struct tevent_context *ev,
+                                             struct wbsrv_service *service,
+                                             const struct dom_sid *sid)
 {
-       struct composite_context *result, *ctx;
-       struct sid2domain_state *state;
+       struct tevent_req *req;
+       struct wb_sid2domain_state *state;
+       struct composite_context *ctx;
+
        DEBUG(5, ("wb_sid2domain_send called\n"));
-       result = composite_create(mem_ctx, service->task->event_ctx);
-       if (result == NULL) goto failed;
 
-       state = talloc(result, struct sid2domain_state);
-       if (state == NULL) goto failed;
-       state->ctx = result;
-       result->private_data = state;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct wb_sid2domain_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
        state->service = service;
-       state->sid = dom_sid_dup(state, sid);
-       if (state->sid == NULL) goto failed;
+       state->sid = *sid;
 
        state->domain = find_domain_from_sid(service, sid);
        if (state->domain != NULL) {
-               result->status = NT_STATUS_OK;
-               composite_done(result);
-               return result;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
        }
 
        if (dom_sid_equal(service->primary_sid, sid) ||
@@ -88,103 +89,202 @@ struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
                                           lpcfg_workgroup(service->task->lp_ctx),
                                           lpcfg_realm(service->task->lp_ctx),
                                           service->primary_sid);
-               if (ctx == NULL) goto failed;
-               ctx->async.fn = sid2domain_recv_dom_info;
-               ctx->async.private_data = state;
-               return result;
-       }
-
-       ctx = wb_cmd_lookupsid_send(state, service, state->sid);
-       if (ctx == NULL) goto failed;
-       composite_continue(result, ctx, sid2domain_recv_name, state);
+               if (tevent_req_nomem(ctx, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               ctx->async.fn = wb_sid2domain_recv_dom_info;
+               ctx->async.private_data = req;
 
-       return result;
+               return req;
+       }
 
- failed:
-       talloc_free(result);
-       return NULL;
+       ctx = wb_cmd_lookupsid_send(state, service, &state->sid);
+       if (tevent_req_nomem(ctx, req)) {
+               return tevent_req_post(req, ev);
+       }
+       ctx->async.fn = wb_sid2domain_recv_name;
+       ctx->async.private_data = req;
 
+       return req;
 }
 
-static void sid2domain_recv_dom_info(struct composite_context *ctx)
+static void wb_sid2domain_recv_dom_info(struct composite_context *ctx)
 {
-       struct sid2domain_state *state =
-               talloc_get_type(ctx->async.private_data,
-                               struct sid2domain_state);
+       struct tevent_req *req =
+               talloc_get_type_abort(ctx->async.private_data,
+               struct tevent_req);
+       struct wb_sid2domain_state *state =
+               tevent_req_data(req,
+               struct wb_sid2domain_state);
        struct wb_dom_info *info;
+       NTSTATUS status;
 
-       state->ctx->status = wb_get_dom_info_recv(ctx, state, &info);
-       if (!composite_is_ok(state->ctx)) return;
+       status = wb_get_dom_info_recv(ctx, state, &info);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
 
        ctx = wb_init_domain_send(state, state->service, info);
-
-       composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
+       if (tevent_req_nomem(ctx, req)) {
+               return;
+       }
+       ctx->async.fn = wb_sid2domain_recv_init;
+       ctx->async.private_data = req;
 }
 
-static void sid2domain_recv_name(struct composite_context *ctx)
+static void wb_sid2domain_recv_name(struct composite_context *ctx)
 {
-       struct sid2domain_state *state =
-               talloc_get_type(ctx->async.private_data,
-                               struct sid2domain_state);
+       struct tevent_req *req =
+               talloc_get_type_abort(ctx->async.private_data,
+               struct tevent_req);
+       struct wb_sid2domain_state *state =
+               tevent_req_data(req,
+               struct wb_sid2domain_state);
        struct wb_sid_object *name;
+       NTSTATUS status;
 
-       state->ctx->status = wb_cmd_lookupsid_recv(ctx, state, &name);
-       if (!composite_is_ok(state->ctx)) return;
+       status = wb_cmd_lookupsid_recv(ctx, state, &name);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
 
        if (name->type == SID_NAME_UNKNOWN) {
-               composite_error(state->ctx, NT_STATUS_NO_SUCH_DOMAIN);
+               tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
                return;
        }
 
        if (name->type != SID_NAME_DOMAIN) {
-               state->sid->num_auths -= 1;
+               state->sid.num_auths -= 1;
        }
 
        ctx = wb_trusted_dom_info_send(state, state->service, name->domain,
-                                      state->sid);
-
-       composite_continue(state->ctx, ctx, sid2domain_recv_trusted_dom_info,
-                          state);
+                                      &state->sid);
+       if (tevent_req_nomem(ctx, req)) {
+               return;
+       }
+       ctx->async.fn = wb_sid2domain_recv_trusted_dom_info;
+       ctx->async.private_data = req;
 }
 
-static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx)
+static void wb_sid2domain_recv_trusted_dom_info(struct composite_context *ctx)
 {
-       struct sid2domain_state *state =
-               talloc_get_type(ctx->async.private_data,
-                               struct sid2domain_state);
+       struct tevent_req *req =
+               talloc_get_type_abort(ctx->async.private_data,
+               struct tevent_req);
+       struct wb_sid2domain_state *state =
+               tevent_req_data(req,
+               struct wb_sid2domain_state);
        struct wb_dom_info *info;
+       NTSTATUS status;
 
-       state->ctx->status = wb_trusted_dom_info_recv(ctx, state, &info);
-       if (!composite_is_ok(state->ctx)) return;
+       status = wb_trusted_dom_info_recv(ctx, state, &info);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
 
        ctx = wb_init_domain_send(state, state->service, info);
-
-       composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
+       if (tevent_req_nomem(ctx, req)) {
+               return;
+       }
+       ctx->async.fn = wb_sid2domain_recv_init;
+       ctx->async.private_data = req;
 }
 
-static void sid2domain_recv_init(struct composite_context *ctx)
+static void wb_sid2domain_recv_init(struct composite_context *ctx)
 {
-       struct sid2domain_state *state =
-               talloc_get_type(ctx->async.private_data,
-                               struct sid2domain_state);
+       struct tevent_req *req =
+               talloc_get_type_abort(ctx->async.private_data,
+               struct tevent_req);
+       struct wb_sid2domain_state *state =
+               tevent_req_data(req,
+               struct wb_sid2domain_state);
        struct wbsrv_domain *existing;
+       NTSTATUS status;
 
-       state->ctx->status = wb_init_domain_recv(ctx, state,
-                                                &state->domain);
-       if (!composite_is_ok(state->ctx)) {
+       status = wb_init_domain_recv(ctx, state, &state->domain);
+       if (tevent_req_nterror(req, status)) {
                DEBUG(10, ("Could not init domain\n"));
                return;
        }
 
-       existing = find_domain_from_sid(state->service, state->sid);
+       existing = find_domain_from_sid(state->service, &state->sid);
        if (existing != NULL) {
                DEBUG(5, ("Initialized domain twice, dropping second one\n"));
                talloc_free(state->domain);
                state->domain = existing;
+       } else {
+               talloc_steal(state->service, state->domain);
+               DLIST_ADD(state->service->domains, state->domain);
+       }
+
+       tevent_req_done(req);
+}
+
+static NTSTATUS _wb_sid2domain_recv(struct tevent_req *req,
+                                   struct wbsrv_domain **result)
+{
+       struct wb_sid2domain_state *state =
+               tevent_req_data(req,
+               struct wb_sid2domain_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
        }
 
-       talloc_steal(state->service, state->domain);
-       DLIST_ADD(state->service->domains, state->domain);
+       *result = state->domain;
+       tevent_req_received(req);
+       return NT_STATUS_OK;
+}
+
+struct sid2domain_state {
+       struct composite_context *ctx;
+       struct wbsrv_domain *domain;
+};
+
+static void sid2domain_recv_domain(struct tevent_req *subreq);
+
+struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
+                                            struct wbsrv_service *service,
+                                            const struct dom_sid *sid)
+{
+       struct composite_context *result;
+       struct sid2domain_state *state;
+       struct tevent_req *subreq;
+
+       DEBUG(5, ("wb_sid2domain_send called\n"));
+       result = composite_create(mem_ctx, service->task->event_ctx);
+       if (result == NULL) goto failed;
+
+       state = talloc(result, struct sid2domain_state);
+       if (state == NULL) goto failed;
+       state->ctx = result;
+       result->private_data = state;
+
+       subreq = _wb_sid2domain_send(state,
+                                    result->event_ctx,
+                                    service, sid);
+       if (subreq == NULL) goto failed;
+       tevent_req_set_callback(subreq, sid2domain_recv_domain, state);
+
+       return result;
+
+ failed:
+       talloc_free(result);
+       return NULL;
+
+}
+
+static void sid2domain_recv_domain(struct tevent_req *subreq)
+{
+       struct sid2domain_state *state =
+               tevent_req_callback_data(subreq,
+                               struct sid2domain_state);
+
+       state->ctx->status = _wb_sid2domain_recv(subreq, &state->domain);
+       TALLOC_FREE(subreq);
+       if (!composite_is_ok(state->ctx)) return;
 
        composite_done(state->ctx);
 }