s3: Add winbindd_lookupsids
authorVolker Lendecke <vl@samba.org>
Tue, 8 Mar 2011 13:31:44 +0000 (14:31 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 13 Apr 2011 21:13:24 +0000 (14:13 -0700)
Signed-off-by: Jeremy Allison <jra@samba.org>
nsswitch/winbind_struct_protocol.h
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_lookupsids.c [new file with mode: 0644]
source3/winbindd/winbindd_proto.h

index 9304702fa01733691956e7755f6e2bfbb07b6cf8..e5ed8e1b3a148de71bc5fb770536973a2e9bb0ab 100644 (file)
@@ -55,8 +55,9 @@ typedef char fstring[FSTRING_LEN];
  *     removed WINBINDD_SET_MAPPING
  *     removed WINBINDD_REMOVE_MAPPING
  * 26: added WINBINDD_DC_INFO
+ * 27: added WINBINDD_LOOKUPSIDS
  */
-#define WINBIND_INTERFACE_VERSION 26
+#define WINBIND_INTERFACE_VERSION 27
 
 /* Have to deal with time_t being 4 or 8 bytes due to structure alignment.
    On a 64bit Linux box, we have to support a constant structure size
@@ -108,6 +109,7 @@ enum winbindd_cmd {
        WINBINDD_LOOKUPSID,
        WINBINDD_LOOKUPNAME,
        WINBINDD_LOOKUPRIDS,
+       WINBINDD_LOOKUPSIDS,
 
        /* Lookup functions */
 
index c507a47fd771d120c0d250fc916059095dd089d4..902e5af16744fd9a24e4b554cb7d5cc76b2c7a9c 100644 (file)
@@ -1373,6 +1373,7 @@ WINBINDD_OBJ1 = \
                winbindd/wb_next_grent.o \
                winbindd/wb_dsgetdcname.o \
                winbindd/winbindd_lookupsid.o \
+               winbindd/winbindd_lookupsids.o \
                winbindd/winbindd_lookupname.o \
                winbindd/winbindd_sid_to_uid.o \
                winbindd/winbindd_sid_to_gid.o \
index fc6ea9378c06f2ffb0f2d9a395ada6e9dc129da6..330f9008317d81e1cbfcd8efd2e301ceb922b07d 100644 (file)
@@ -471,6 +471,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          wb_ping_send, wb_ping_recv },
        { WINBINDD_LOOKUPSID, "LOOKUPSID",
          winbindd_lookupsid_send, winbindd_lookupsid_recv },
+       { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
+         winbindd_lookupsids_send, winbindd_lookupsids_recv },
        { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
          winbindd_lookupname_send, winbindd_lookupname_recv },
        { WINBINDD_SID_TO_UID, "SID_TO_UID",
diff --git a/source3/winbindd/winbindd_lookupsids.c b/source3/winbindd/winbindd_lookupsids.c
new file mode 100644 (file)
index 0000000..aeaf21d
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_LOOKUPSIDS
+   Copyright (C) Volker Lendecke 2011
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "../libcli/security/security.h"
+
+struct winbindd_lookupsids_state {
+       struct dom_sid *sids;
+       uint32_t num_sids;
+       struct lsa_RefDomainList *domains;
+       struct lsa_TransNameArray *names;
+};
+
+static void winbindd_lookupsids_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_lookupsids_send(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                          struct winbindd_cli_state *cli,
+                                          struct winbindd_request *request)
+{
+       struct tevent_req *req, *subreq;
+       struct winbindd_lookupsids_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_lookupsids_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       DEBUG(3, ("lookupsids\n"));
+
+       if (request->extra_len == 0) {
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
+       }
+       if (request->extra_data.data[request->extra_len-1] != '\0') {
+               DEBUG(10, ("Got invalid sids list\n"));
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
+       if (!parse_sidlist(state, request->extra_data.data,
+                          &state->sids, &state->num_sids)) {
+               DEBUG(10, ("parse_sidlist failed\n"));
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
+       subreq = wb_lookupsids_send(state, ev, state->sids, state->num_sids);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_lookupsids_done, req);
+       return req;
+}
+
+static void winbindd_lookupsids_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_lookupsids_state *state = tevent_req_data(
+               req, struct winbindd_lookupsids_state);
+       NTSTATUS status;
+
+       status = wb_lookupsids_recv(subreq, state, &state->domains,
+                                   &state->names);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
+
+NTSTATUS winbindd_lookupsids_recv(struct tevent_req *req,
+                                 struct winbindd_response *response)
+{
+       struct winbindd_lookupsids_state *state = tevent_req_data(
+               req, struct winbindd_lookupsids_state);
+       NTSTATUS status;
+       char *result;
+       uint32_t i;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               DEBUG(5, ("wb_lookupsids failed: %s\n", nt_errstr(status)));
+               return status;
+       }
+
+       result = talloc_asprintf(response, "%d\n", (int)state->domains->count);
+       if (result == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0; i<state->domains->count; i++) {
+               fstring sid_str;
+
+               result = talloc_asprintf_append_buffer(
+                       result, "%s %s\n",
+                       sid_to_fstring(sid_str,
+                                      state->domains->domains[i].sid),
+                       state->domains->domains[i].name.string);
+               if (result == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       result = talloc_asprintf_append_buffer(
+               result, "%d\n", (int)state->names->count);
+       if (result == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0; i<state->names->count; i++) {
+               struct lsa_TranslatedName *name;
+
+               name = &state->names->names[i];
+
+               result = talloc_asprintf_append_buffer(
+                       result, "%d %d %s\n",
+                       (int)name->sid_index, (int)name->sid_type,
+                       name->name.string);
+               if (result == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       response->extra_data.data = result;
+       response->length += talloc_get_size(result);
+       return NT_STATUS_OK;
+}
index 389f8dfb673d311dc30176b962ffe5fd2e64b6f5..3a736699bf1006d4f72e93b34430e5d34bb94efe 100644 (file)
@@ -466,6 +466,13 @@ struct tevent_req *winbindd_lookupsid_send(TALLOC_CTX *mem_ctx,
 NTSTATUS winbindd_lookupsid_recv(struct tevent_req *req,
                                 struct winbindd_response *response);
 
+struct tevent_req *winbindd_lookupsids_send(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                           struct winbindd_cli_state *cli,
+                                           struct winbindd_request *request);
+NTSTATUS winbindd_lookupsids_recv(struct tevent_req *req,
+                                 struct winbindd_response *response);
+
 struct tevent_req *wb_lookupname_send(TALLOC_CTX *mem_ctx,
                                      struct tevent_context *ev,
                                      const char *dom_name, const char *name,