wbclient: "ev" is no longer used in wbc_sids_to_xids
[metze/samba/wip.git] / source4 / libcli / wbclient / wbclient.c
index 1b2d314824bd7463d5ad4f69a928b57054d950fc..1ff35c8eba5a305cd410d7b9b8e380cb535609a4 100644 (file)
 */
 
 #include "includes.h"
+#include <tevent.h>
+#include "nsswitch/winbind_client.h"
 #include "libcli/wbclient/wbclient.h"
+#include "libcli/security/dom_sid.h"
+#include "nsswitch/libwbclient/wbclient.h"
 
-/**
- * Get the server_id of the winbind task.
- *
- * \param[in] msg_ctx message context to use
- * \param[in] mem_ctx talloc context to use
- * \param[out] ids array of server_id structs containing the winbind id
- * \return NT_STATUS_OK on success, NT_STATUS_INTERNAL_ERROR on failure
- */
-static NTSTATUS get_server_id(struct messaging_context *msg_ctx,
-                             TALLOC_CTX *mem_ctx, struct server_id **ids)
+NTSTATUS wbc_sids_to_xids(struct id_map *ids, uint32_t count)
 {
-       *ids = irpc_servers_byname(msg_ctx, mem_ctx, "winbind_server");
-       if (*ids == NULL || (*ids)[0].id == 0) {
-               DEBUG(0, ("Geting the winbind server ID failed.\n"));
-               return NT_STATUS_INTERNAL_ERROR;
+       TALLOC_CTX *mem_ctx;
+       uint32_t i;
+       struct wbcDomainSid *sids;
+       struct wbcUnixId *xids;
+       wbcErr result;
+       bool wb_off;
+
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               return NT_STATUS_NO_MEMORY;
        }
-       return NT_STATUS_OK;
-}
-
-/**
- * Initialize the wbclient context, talloc_free() when done.
- *
- * \param mem_ctx talloc context to allocate memory from
- * \param msg_ctx message context to use
- * \param
- */
-struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx,
-                            struct messaging_context *msg_ctx,
-                            struct event_context *event_ctx)
-{
-       struct wbc_context *ctx;
-       NTSTATUS status;
-
-       ctx = talloc(mem_ctx, struct wbc_context);
-       if (ctx == NULL) return NULL;
 
-       status = get_server_id(msg_ctx, mem_ctx, &ctx->ids);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(ctx);
-               return NULL;
+       sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
+       if (sids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
        }
 
-       ctx->msg_ctx = msg_ctx;
-       ctx->event_ctx = event_ctx;
-
-       return ctx;
-}
-
-struct wbc_idmap_state {
-       struct composite_context *ctx;
-       struct winbind_get_idmap *req;
-       struct irpc_request *irpc_req;
-       struct id_mapping *ids;
-};
-
-static void sids_to_xids_recv_ids(struct irpc_request *req);
-
-struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx,
-                                               TALLOC_CTX *mem_ctx,
-                                               uint32_t count,
-                                               struct id_mapping *ids)
-{
-       struct composite_context *ctx;
-       struct wbc_idmap_state *state;
-
-       DEBUG(5, ("wbc_sids_to_xids called\n"));
-
-       ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);
-       if (ctx == NULL) return NULL;
+       xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+       if (xids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
 
-       state = talloc(ctx, struct wbc_idmap_state);
-       if (composite_nomem(state, ctx)) return ctx;
-       ctx->private_data = state;
+       for (i=0; i<count; i++) {
+               memcpy(&sids[i], ids[i].sid, sizeof(struct dom_sid));
+       }
 
-       state->req = talloc(state, struct winbind_get_idmap);
-       if (composite_nomem(state->req, ctx)) return ctx;
+       wb_off = winbind_env_set();
+       if (wb_off) {
+               (void)winbind_on();
+       }
 
-       state->req->in.count = count;
-       state->req->in.level = WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS;
-       state->req->in.ids = ids;
-       state->ctx = ctx;
+       result = wbcSidsToUnixIds(sids, count, xids);
 
-       state->irpc_req = IRPC_CALL_SEND(wbc_ctx->msg_ctx, wbc_ctx->ids[0],
-                                        winbind, WINBIND_GET_IDMAP, state->req,
-                                        state);
-       if (composite_nomem(state->irpc_req, ctx)) return ctx;
+       if (wb_off) {
+               (void)winbind_off();
+       }
 
-       composite_continue_irpc(ctx, state->irpc_req, sids_to_xids_recv_ids,
-                               state);
-       return ctx;
-}
+       if (!WBC_ERROR_IS_OK(result)) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
 
-static void sids_to_xids_recv_ids(struct irpc_request *req)
-{
-       struct wbc_idmap_state *state = talloc_get_type_abort(
-                                                       req->async.private,
-                                                       struct wbc_idmap_state);
+       for (i=0; i<count; i++) {
+               struct wbcUnixId *xid = &xids[i];
+               struct unixid *id = &ids[i].xid;
+
+               switch (xid->type) {
+                   case WBC_ID_TYPE_UID:
+                       id->type = ID_TYPE_UID;
+                       id->id = xid->id.uid;
+                       break;
+                   case WBC_ID_TYPE_GID:
+                       id->type = ID_TYPE_GID;
+                       id->id = xid->id.gid;
+                       break;
+                   case WBC_ID_TYPE_BOTH:
+                       id->type = ID_TYPE_BOTH;
+                       id->id = xid->id.uid;
+                       break;
+                   case WBC_ID_TYPE_NOT_SPECIFIED:
+                       id->type = ID_TYPE_NOT_SPECIFIED;
+                       id->id = UINT32_MAX;
+                       break;
+               }
+               ids[i].status = ID_MAPPED;
+       }
 
-       state->ctx->status = irpc_call_recv(state->irpc_req);
-       if (!composite_is_ok(state->ctx)) return;
+       TALLOC_FREE(mem_ctx);
 
-       state->ids = state->req->out.ids;
-       composite_done(state->ctx);
+       return NT_STATUS_OK;
 }
 
-NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx,
-                              struct id_mapping **ids)
+NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
+                         uint32_t count)
 {
-       NTSTATUS status = composite_wait(ctx);
-               DEBUG(5, ("wbc_sids_to_xids_recv called\n"));
-       if (NT_STATUS_IS_OK(status)) {
-               struct wbc_idmap_state *state = talloc_get_type_abort(
-                                                       ctx->private_data,
-                                                       struct wbc_idmap_state);
-               *ids = state->ids;
+       TALLOC_CTX *mem_ctx;
+       uint32_t i;
+       struct wbcDomainSid *sids;
+       struct wbcUnixId *xids;
+       wbcErr result;
+       bool wb_off;
+
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               return NT_STATUS_NO_MEMORY;
        }
 
-       return status;
-}
-
-static void xids_to_sids_recv_ids(struct irpc_request *req);
-
-struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
-                                               TALLOC_CTX *mem_ctx,
-                                               uint32_t count,
-                                               struct id_mapping *ids)
-{
-       struct composite_context *ctx;
-       struct wbc_idmap_state *state;
-
-       DEBUG(5, ("wbc_xids_to_sids called\n"));
-
-       ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);
-       if (ctx == NULL) return NULL;
-
-       state = talloc(ctx, struct wbc_idmap_state);
-       if (composite_nomem(state, ctx)) return ctx;
-       ctx->private_data = state;
-
-       state->req = talloc(state, struct winbind_get_idmap);
-       if (composite_nomem(state->req, ctx)) return ctx;
-
-       state->req->in.count = count;
-       state->req->in.level = WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS;
-       state->req->in.ids = ids;
-       state->ctx = ctx;
+       sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
+       if (sids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
 
-       state->irpc_req = IRPC_CALL_SEND(wbc_ctx->msg_ctx, wbc_ctx->ids[0],
-                                        winbind, WINBIND_GET_IDMAP, state->req,
-                                        state);
-       if (composite_nomem(state->irpc_req, ctx)) return ctx;
+       xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+       if (xids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
 
-       composite_continue_irpc(ctx, state->irpc_req, xids_to_sids_recv_ids,
-                       state);
+       for (i=0; i<count; i++) {
+               struct id_map *id = &ids[i];
+               struct wbcUnixId *xid = &xids[i];
+
+               switch (id->xid.type) {
+                   case ID_TYPE_UID:
+                           *xid = (struct wbcUnixId) {
+                                   .type = WBC_ID_TYPE_UID,
+                                   .id.uid = id->xid.id
+                           };
+                           break;
+                   case ID_TYPE_GID:
+                           *xid = (struct wbcUnixId) {
+                                   .type = WBC_ID_TYPE_GID,
+                                   .id.uid = id->xid.id
+                           };
+                           break;
+                   default:
+                           TALLOC_FREE(mem_ctx);
+                           return NT_STATUS_NOT_FOUND;
+               }
+       }
 
-       return ctx;
-}
+       wb_off = winbind_env_set();
+       if (wb_off) {
+               (void)winbind_on();
+       }
 
-static void xids_to_sids_recv_ids(struct irpc_request *req)
-{
-       struct wbc_idmap_state *state = talloc_get_type_abort(
-                                                       req->async.private,
-                                                       struct wbc_idmap_state);
+       result = wbcUnixIdsToSids(xids, count, sids);
 
-       state->ctx->status = irpc_call_recv(state->irpc_req);
-       if (!composite_is_ok(state->ctx)) return;
+       if (wb_off) {
+               (void)winbind_off();
+       }
 
-       state->ids = state->req->out.ids;
-       composite_done(state->ctx);
-}
+       if (!WBC_ERROR_IS_OK(result)) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
 
-NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
-                              struct id_mapping **ids)
-{
-       NTSTATUS status = composite_wait(ctx);
-               DEBUG(5, ("wbc_xids_to_sids_recv called\n"));
-       if (NT_STATUS_IS_OK(status)) {
-               struct wbc_idmap_state *state = talloc_get_type_abort(
-                                                       ctx->private_data,
-                                                       struct wbc_idmap_state);
-               *ids = state->ids;
+       for (i=0; i<count; i++) {
+               struct wbcDomainSid *sid = &sids[i];
+               struct wbcDomainSid null_sid = { 0 };
+               struct id_map *id = &ids[i];
+
+               if (memcmp(sid, &null_sid, sizeof(*sid)) != 0) {
+                       struct dom_sid domsid;
+                       id->status = ID_MAPPED;
+
+                       memcpy(&domsid, sid, sizeof(struct dom_sid));
+                       id->sid = dom_sid_dup(ids, &domsid);
+                       if (id->sid == NULL) {
+                               TALLOC_FREE(mem_ctx);
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       id->status = ID_UNMAPPED;
+                       id->sid = NULL;
+               }
        }
 
-       return status;
+       TALLOC_FREE(mem_ctx);
+       return NT_STATUS_OK;
 }
-