libwbclient4: Add wbc_sids_to_xids
authorVolker Lendecke <vl@samba.org>
Thu, 30 Jan 2014 19:05:09 +0000 (19:05 +0000)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 5 Mar 2014 15:33:21 +0000 (16:33 +0100)
Signed-off-by: Volker Lendecke <vl@samba.org>
Change-Id: I79f4b87a14e7074970bd024626e5838a4461cc2e
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/libcli/wbclient/wbclient.c
source4/libcli/wbclient/wbclient.h
source4/libcli/wbclient/wscript_build

index 4f50c106947b42b785f200b74dbe8e9efbe66161..5b95be125934ad3b2932059890a995e73ade402f 100644 (file)
 #include "includes.h"
 #include <tevent.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"
 
 /**
  * Initialize the wbclient context, talloc_free() when done.
@@ -194,3 +198,166 @@ NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
        return status;
 }
 
+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)
+{
+       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);
+       }
+
+       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);
+       if (sids == NULL) {
+               close(fd);
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       p = sids;
+       for (i=0; i<count; i++) {
+               p += dom_sid_string_buf(ids[i].sid, p, sidslen - (p - sids));
+               *p++ = '\n';
+       }
+       *p++ = '\0';
+
+       DEBUG(10, ("sids=\n%s", sids));
+
+       req.length = sizeof(struct winbindd_request);
+       req.cmd = WINBINDD_SIDS_TO_XIDS;
+       req.pid = getpid();
+       req.extra_data.data = sids;
+       req.extra_len = sidslen;
+
+       ret = wb_simple_trans(ev, fd, &req, mem_ctx, &resp, &err);
+       if (ret == -1) {
+               return map_nt_error_from_unix_common(err);
+       }
+
+       close(fd);
+
+       p = resp->extra_data.data;
+
+       for (i=0; i<count; i++) {
+               struct unixid *id = &ids[i].xid;
+               char *q;
+
+               switch (p[0]) {
+               case 'U':
+                       id->type = ID_TYPE_UID;
+                       id->id = strtoul(p+1, &q, 10);
+                       break;
+               case 'G':
+                       id->type = ID_TYPE_GID;
+                       id->id = strtoul(p+1, &q, 10);
+                       break;
+               case 'B':
+                       id->type = ID_TYPE_BOTH;
+                       id->id = strtoul(p+1, &q, 10);
+                       break;
+               default:
+                       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;
+}
index 1fa2f59c575797b3d0e89f982b3797de2565c5aa..33a21f318d2053ef9502b9b2a63583e7260b9c60 100644 (file)
@@ -39,6 +39,9 @@ struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx,
 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx,
                               struct id_map **ids);
 
+NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids,
+                         uint32_t count);
+
 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
                                                TALLOC_CTX *mem_ctx,
                                                uint32_t count,
@@ -47,3 +50,5 @@ struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
                               struct id_map **ids);
 
+NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
+                         uint32_t count);
index c9bfc8587f0c9c77250c5d23fd1d98e3184f7411..cf28887a2855aa123158162e8002cc532ef5c24b 100644 (file)
@@ -3,8 +3,8 @@
 bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD',
                   source='wbclient.c',
                   public_deps='errors events',
-                  deps='NDR_WINBIND MESSAGING RPC_NDR_WINBIND',
                   cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR,
+                  deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND',
                   private_library=True
        )