wbclient: "ev" is no longer used in wbc_sids_to_xids
[metze/samba/wip.git] / source4 / libcli / wbclient / wbclient.c
index 3f8003bbbaf7c0481e08148a948fcf938dc177dc..1ff35c8eba5a305cd410d7b9b8e380cb535609a4 100644 (file)
 
 #include "includes.h"
 #include <tevent.h>
-#include "lib/util/tevent_unix.h"
+#include "nsswitch/winbind_client.h"
 #include "libcli/wbclient/wbclient.h"
-#include "nsswitch/wb_reqtrans.h"
-#include "system/network.h"
-#include "libcli/util/error.h"
 #include "libcli/security/dom_sid.h"
+#include "nsswitch/libwbclient/wbclient.h"
 
-/**
- * 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 imessaging_context *msg_ctx,
-                            struct tevent_context *event_ctx)
-{
-       struct wbc_context *ctx;
-
-       ctx = talloc(mem_ctx, struct wbc_context);
-       if (ctx == NULL) return NULL;
-
-       ctx->event_ctx = event_ctx;
-
-       ctx->irpc_handle = irpc_binding_handle_by_name(ctx, msg_ctx,
-                                                      "winbind_server",
-                                                      &ndr_table_winbind);
-       if (ctx->irpc_handle == NULL) {
-               talloc_free(ctx);
-               return NULL;
-       }
-
-       return ctx;
-}
-
-static int wb_simple_trans(struct tevent_context *ev, int fd,
-                          struct winbindd_request *wb_req,
-                          TALLOC_CTX *mem_ctx,
-                          struct winbindd_response **resp, int *err)
-{
-       struct tevent_req *req;
-       bool polled;
-       int ret;
-
-       req = wb_simple_trans_send(ev, ev, NULL, fd, wb_req);
-       if (req == NULL) {
-               *err = ENOMEM;
-               return -1;
-       }
-
-       polled = tevent_req_poll(req, ev);
-       if (!polled) {
-               *err = errno;
-               DEBUG(10, ("tevent_req_poll returned %s\n",
-                          strerror(*err)));
-               return -1;
-       }
-
-       ret = wb_simple_trans_recv(req, mem_ctx, resp, err);
-       TALLOC_FREE(req);
-       return ret;
-}
-
-static const char *winbindd_socket_dir(void)
-{
-#ifdef SOCKET_WRAPPER
-       const char *env_dir;
-
-       env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR);
-       if (env_dir) {
-               return env_dir;
-       }
-#endif
-
-       return WINBINDD_SOCKET_DIR;
-}
-
-static int winbindd_pipe_sock(void)
-{
-       struct sockaddr_un sunaddr = {};
-       int ret, fd;
-       char *path;
-
-       ret = asprintf(&path, "%s/%s", winbindd_socket_dir(),
-                      WINBINDD_SOCKET_NAME);
-       if (ret == -1) {
-               errno = ENOMEM;
-               return -1;
-       }
-       sunaddr.sun_family = AF_UNIX;
-       strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
-       free(path);
-
-       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (fd == -1) {
-               return -1;
-       }
-
-       ret = connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
-       if (ret == -1) {
-               int err = errno;
-               close(fd);
-               errno = err;
-               return -1;
-       }
-
-       return fd;
-}
-
-NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids,
-                         uint32_t count)
+NTSTATUS wbc_sids_to_xids(struct id_map *ids, uint32_t count)
 {
        TALLOC_CTX *mem_ctx;
-       struct winbindd_request req = {};
-       struct winbindd_response *resp;
        uint32_t i;
-       int fd, ret, err;
-       char *sids, *p;
-       size_t sidslen;
-
-       fd = winbindd_pipe_sock();
-       if (fd == -1) {
-               return map_nt_error_from_unix_common(errno);
-       }
+       struct wbcDomainSid *sids;
+       struct wbcUnixId *xids;
+       wbcErr result;
+       bool wb_off;
 
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
-               close(fd);
                return NT_STATUS_NO_MEMORY;
        }
 
-       sidslen = count * (DOM_SID_STR_BUFLEN + 1);
-
-       sids = talloc_array(mem_ctx, char, sidslen);
+       sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
        if (sids == NULL) {
-               close(fd);
                TALLOC_FREE(mem_ctx);
                return NT_STATUS_NO_MEMORY;
        }
 
-       p = sids;
+       xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+       if (xids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        for (i=0; i<count; i++) {
-               p += dom_sid_string_buf(ids[i].sid, p, sidslen - (p - sids));
-               *p++ = '\n';
+               memcpy(&sids[i], ids[i].sid, sizeof(struct dom_sid));
        }
-       *p++ = '\0';
 
-       DEBUG(10, ("sids=\n%s", sids));
+       wb_off = winbind_env_set();
+       if (wb_off) {
+               (void)winbind_on();
+       }
 
-       req.length = sizeof(struct winbindd_request);
-       req.cmd = WINBINDD_SIDS_TO_XIDS;
-       req.pid = getpid();
-       req.extra_data.data = sids;
-       req.extra_len = sidslen;
+       result = wbcSidsToUnixIds(sids, count, xids);
 
-       ret = wb_simple_trans(ev, fd, &req, mem_ctx, &resp, &err);
-       if (ret == -1) {
-               return map_nt_error_from_unix_common(err);
+       if (wb_off) {
+               (void)winbind_off();
        }
 
-       close(fd);
-
-       p = resp->extra_data.data;
+       if (!WBC_ERROR_IS_OK(result)) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
 
        for (i=0; i<count; i++) {
+               struct wbcUnixId *xid = &xids[i];
                struct unixid *id = &ids[i].xid;
-               char *q;
 
-               switch (p[0]) {
-               case 'U':
+               switch (xid->type) {
+                   case WBC_ID_TYPE_UID:
                        id->type = ID_TYPE_UID;
-                       id->id = strtoul(p+1, &q, 10);
+                       id->id = xid->id.uid;
                        break;
-               case 'G':
+                   case WBC_ID_TYPE_GID:
                        id->type = ID_TYPE_GID;
-                       id->id = strtoul(p+1, &q, 10);
+                       id->id = xid->id.gid;
                        break;
-               case 'B':
+                   case WBC_ID_TYPE_BOTH:
                        id->type = ID_TYPE_BOTH;
-                       id->id = strtoul(p+1, &q, 10);
+                       id->id = xid->id.uid;
                        break;
-               default:
+                   case WBC_ID_TYPE_NOT_SPECIFIED:
                        id->type = ID_TYPE_NOT_SPECIFIED;
                        id->id = UINT32_MAX;
-                       q = strchr(p, '\n');
                        break;
-               };
-               ids[i].status = ID_MAPPED;
-
-               if (q == NULL || q[0] != '\n') {
-                       TALLOC_FREE(mem_ctx);
-                       return NT_STATUS_INTERNAL_ERROR;
                }
-               p = q+1;
-       }
-
-       return NT_STATUS_OK;
-}
-
-struct wbc_id_to_sid_state {
-       struct winbindd_request wbreq;
-       struct dom_sid sid;
-};
-
-static void wbc_id_to_sid_done(struct tevent_req *subreq);
-
-static struct tevent_req *wbc_id_to_sid_send(TALLOC_CTX *mem_ctx,
-                                            struct tevent_context *ev,
-                                            int fd, const struct unixid *id)
-{
-       struct tevent_req *req, *subreq;
-       struct wbc_id_to_sid_state *state;
-
-       req = tevent_req_create(mem_ctx, &state, struct wbc_id_to_sid_state);
-       if (req == NULL) {
-               return NULL;
+               ids[i].status = ID_MAPPED;
        }
 
-       switch(id->type) {
-       case ID_TYPE_UID:
-               state->wbreq.cmd = WINBINDD_UID_TO_SID;
-               state->wbreq.data.uid = id->id;
-               break;
-       case ID_TYPE_GID:
-               state->wbreq.cmd = WINBINDD_GID_TO_SID;
-               state->wbreq.data.gid = id->id;
-               break;
-       default:
-               tevent_req_error(req, ENOENT);
-               return tevent_req_post(req, ev);
-       }
+       TALLOC_FREE(mem_ctx);
 
-       subreq = wb_simple_trans_send(state, ev, NULL, fd, &state->wbreq);
-       if (tevent_req_nomem(subreq, req)) {
-               return tevent_req_post(req, ev);
-       }
-       tevent_req_set_callback(subreq, wbc_id_to_sid_done, req);
-       return req;
-}
-
-static void wbc_id_to_sid_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct wbc_id_to_sid_state *state = tevent_req_data(
-               req, struct wbc_id_to_sid_state);
-       struct winbindd_response *wbresp;
-       int ret, err;
-
-       ret = wb_simple_trans_recv(subreq, state, &wbresp, &err);
-       TALLOC_FREE(subreq);
-       if (ret == -1) {
-               tevent_req_error(req, err);
-               return;
-       }
-       if ((wbresp->result != WINBINDD_OK) ||
-           !dom_sid_parse(wbresp->data.sid.sid, &state->sid)) {
-               tevent_req_error(req, ENOENT);
-               return;
-       }
-       tevent_req_done(req);
+       return NT_STATUS_OK;
 }
 
-static int wbc_id_to_sid_recv(struct tevent_req *req, struct dom_sid *sid)
+NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
+                         uint32_t count)
 {
-       struct wbc_id_to_sid_state *state = tevent_req_data(
-               req, struct wbc_id_to_sid_state);
-       int err;
+       TALLOC_CTX *mem_ctx;
+       uint32_t i;
+       struct wbcDomainSid *sids;
+       struct wbcUnixId *xids;
+       wbcErr result;
+       bool wb_off;
 
-       if (tevent_req_is_unix_error(req, &err)) {
-               return err;
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               return NT_STATUS_NO_MEMORY;
        }
-       sid_copy(sid, &state->sid);
-       return 0;
-}
-
-struct wbc_ids_to_sids_state {
-       struct tevent_context *ev;
-       int fd;
-       struct id_map *ids;
-       uint32_t count;
-       uint32_t idx;
-};
-
-static void wbc_ids_to_sids_done(struct tevent_req *subreq);
-
-static struct tevent_req *wbc_ids_to_sids_send(
-       TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-       int fd, struct id_map *ids, uint32_t count)
-{
-       struct tevent_req *req, *subreq;
-       struct wbc_ids_to_sids_state *state;
 
-       req = tevent_req_create(mem_ctx, &state,
-                               struct wbc_ids_to_sids_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->fd = fd;
-       state->ids = ids;
-       state->count = count;
-
-       if (count == 0) {
-               tevent_req_done(req);
-               return tevent_req_post(req, ev);
+       sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
+       if (sids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
        }
 
-       subreq = wbc_id_to_sid_send(state, state->ev, state->fd,
-                                   &state->ids[state->idx].xid);
-       if (tevent_req_nomem(subreq, req)) {
-               return tevent_req_post(req, ev);
+       xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+       if (xids == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
        }
-       tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req);
-       return req;
-}
 
-static void wbc_ids_to_sids_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct wbc_ids_to_sids_state *state = tevent_req_data(
-               req, struct wbc_ids_to_sids_state);
-       struct id_map *id;
-       struct dom_sid sid;
-       int ret;
-
-       ret = wbc_id_to_sid_recv(subreq, &sid);
-       TALLOC_FREE(subreq);
-
-       id = &state->ids[state->idx];
-       if (ret == 0) {
-               id->status = ID_MAPPED;
-               id->sid = dom_sid_dup(state->ids, &sid);
-               if (id->sid == NULL) {
-                       tevent_req_error(req, ENOMEM);
-                       return;
+       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;
                }
-       } else {
-               id->status = ID_UNMAPPED;
-               id->sid = NULL;
-       }
-
-       state->idx += 1;
-       if (state->idx == state->count) {
-               tevent_req_done(req);
-               return;
-       }
-
-       subreq = wbc_id_to_sid_send(state, state->ev, state->fd,
-                                   &state->ids[state->idx].xid);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
        }
-       tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req);
-}
 
-static int wbc_ids_to_sids_recv(struct tevent_req *req)
-{
-       int err;
-       if (tevent_req_is_unix_error(req, &err)) {
-               return err;
+       wb_off = winbind_env_set();
+       if (wb_off) {
+               (void)winbind_on();
        }
-       return 0;
-}
 
-NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
-                         uint32_t count)
-{
-       struct tevent_req *req;
-       NTSTATUS status;
-       bool polled;
-       int ret, fd;
-
-       DEBUG(5, ("wbc_xids_to_sids called: %u ids\n", (unsigned)count));
-
-       fd = winbindd_pipe_sock();
-       if (fd == -1) {
-               status = map_nt_error_from_unix_common(errno);
-               DEBUG(10, ("winbindd_pipe_sock returned %s\n",
-                          strerror(errno)));
-               return status;
-       }
+       result = wbcUnixIdsToSids(xids, count, sids);
 
-       req = wbc_ids_to_sids_send(ev, ev, fd, ids, count);
-       if (req == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto done;
+       if (wb_off) {
+               (void)winbind_off();
        }
 
-       polled = tevent_req_poll(req, ev);
-       if (!polled) {
-               status = map_nt_error_from_unix_common(errno);
-               DEBUG(10, ("tevent_req_poll returned %s\n",
-                          strerror(errno)));
-               goto done;
+       if (!WBC_ERROR_IS_OK(result)) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_INTERNAL_ERROR;
        }
 
-       ret = wbc_ids_to_sids_recv(req);
-       TALLOC_FREE(req);
-       if (ret != 0) {
-               status = map_nt_error_from_unix_common(ret);
-               DEBUG(10, ("tevent_req_poll returned %s\n",
-                          strerror(ret)));
-       } else {
-               status = NT_STATUS_OK;
+       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;
+               }
        }
 
-done:
-       close(fd);
-       return status;
+       TALLOC_FREE(mem_ctx);
+       return NT_STATUS_OK;
 }