diff options
author | Volker Lendecke <vl@samba.org> | 2014-01-30 19:05:09 +0000 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2014-02-10 10:56:55 +0100 |
commit | fefc59619b58cb0c38bf7e6ac2ebcc25a5ebbd6c (patch) | |
tree | 5b0e853edff4ce41123e29239856d2305a81e8ce | |
parent | 907f49ef1f599397174858a4e57f9eb91e35593b (diff) | |
download | samba-fefc59619b58cb0c38bf7e6ac2ebcc25a5ebbd6c.tar.gz samba-fefc59619b58cb0c38bf7e6ac2ebcc25a5ebbd6c.tar.xz samba-fefc59619b58cb0c38bf7e6ac2ebcc25a5ebbd6c.zip |
libwbclient4: Add wbc_sids_to_xids
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Kai Blin <kai@samba.org>
-rw-r--r-- | source4/libcli/wbclient/wbclient.c | 167 | ||||
-rw-r--r-- | source4/libcli/wbclient/wbclient.h | 5 | ||||
-rw-r--r-- | source4/libcli/wbclient/wscript_build | 2 |
3 files changed, 173 insertions, 1 deletions
diff --git a/source4/libcli/wbclient/wbclient.c b/source4/libcli/wbclient/wbclient.c index 4f50c106947..5b95be12593 100644 --- a/source4/libcli/wbclient/wbclient.c +++ b/source4/libcli/wbclient/wbclient.c @@ -22,6 +22,10 @@ #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; +} diff --git a/source4/libcli/wbclient/wbclient.h b/source4/libcli/wbclient/wbclient.h index 1fa2f59c575..33a21f318d2 100644 --- a/source4/libcli/wbclient/wbclient.h +++ b/source4/libcli/wbclient/wbclient.h @@ -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); diff --git a/source4/libcli/wbclient/wscript_build b/source4/libcli/wbclient/wscript_build index 85439fc0040..2c95a046904 100644 --- a/source4/libcli/wbclient/wscript_build +++ b/source4/libcli/wbclient/wscript_build @@ -3,7 +3,7 @@ bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD', source='wbclient.c', public_deps='errors events', - deps='NDR_WINBIND MESSAGING RPC_NDR_WINBIND', + deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND', private_library=True ) |