libwbclient: Make source4/ use nsswitch/libwbclient
authorVolker Lendecke <vl@samba.org>
Tue, 9 Feb 2016 08:30:09 +0000 (09:30 +0100)
committerRalph Boehme <slow@samba.org>
Mon, 22 Feb 2016 19:29:16 +0000 (20:29 +0100)
Right now there's no async user of this, so I think it's okay to use the
sync libwbclient. If we really get async libwbclient users, we need to
put it there instead of calling the struct protocol directly.

The code before this patch did not look at the _NO_WINBIND environment
variable. So ignore it here too.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source4/libcli/wbclient/wbclient.c
source4/libcli/wbclient/wscript_build

index bb894356843115478f1865a5f15928899c096c76..f306556ff40ad8168492327a9551d24fb45f8f64 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"
-
-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("SELFTEST_WINBINDD_SOCKET_DIR");
-       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;
-}
+#include "nsswitch/libwbclient/wbclient.h"
 
 NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, 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 = (p - sids);
+       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);
-
-       if (resp->result != WINBINDD_OK || p == NULL) {
+       if (!WBC_ERROR_IS_OK(result)) {
+               TALLOC_FREE(mem_ctx);
                return NT_STATUS_INTERNAL_ERROR;
        }
 
-       p = resp->extra_data.data;
-
        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;
-       }
-
-       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);
+               ids[i].status = ID_MAPPED;
        }
 
-       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;
-}
+       TALLOC_FREE(mem_ctx);
 
-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;
 }
index f3cb3afd5f5ddb04f17b37c43cac7fd9b29f13dd..679a2815803662641b97af519ff047ae72461879 100644 (file)
@@ -2,7 +2,7 @@
 
 bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD',
                   source='wbclient.c',
-                  public_deps='samba-errors events',
+                  public_deps='samba-errors events wbclient',
                   cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR,
                   deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND',
                   private_library=True