s3:winbind: Convert WINBINDD_GETGRNAM to the new API
authorVolker Lendecke <vl@samba.org>
Sun, 16 Aug 2009 10:23:31 +0000 (12:23 +0200)
committerVolker Lendecke <vl@samba.org>
Sun, 16 Aug 2009 10:39:08 +0000 (12:39 +0200)
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_getgrnam.c [new file with mode: 0644]
source3/winbindd/winbindd_group.c
source3/winbindd/winbindd_proto.h

index d96dc2aaf18dcefd47e1e266c253e00eb7f5e43e..f1fac93d5b7778015a8467c9e458b0da68ba619e 100644 (file)
@@ -1183,6 +1183,7 @@ WINBINDD_OBJ1 = \
                winbindd/winbindd_getgroups.o \
                winbindd/winbindd_show_sequence.o \
                winbindd/winbindd_getgrgid.o \
+               winbindd/winbindd_getgrnam.o \
                auth/token_util.o \
                ../nsswitch/libwbclient/wb_reqtrans.o \
                smbd/connection.o
index bbcfede030b217a8da934d76be561801495a6e9c..554cb0a30a614007b2a79756f12527afae4689ba 100644 (file)
@@ -435,7 +435,6 @@ static struct winbindd_dispatch_table {
 
        /* Group functions */
 
-       { WINBINDD_GETGRNAM, winbindd_getgrnam, "GETGRNAM" },
        { WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" },
        { WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" },
        { WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" },
@@ -536,6 +535,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          winbindd_show_sequence_send, winbindd_show_sequence_recv },
        { WINBINDD_GETGRGID, "GETGRGID",
          winbindd_getgrgid_send, winbindd_getgrgid_recv },
+       { WINBINDD_GETGRNAM, "GETGRNAM",
+         winbindd_getgrnam_send, winbindd_getgrnam_recv },
 
        { 0, NULL, NULL, NULL }
 };
diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c
new file mode 100644 (file)
index 0000000..85e60a2
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_GETGRNAM
+   Copyright (C) Volker Lendecke 2009
+
+   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"
+
+struct winbindd_getgrnam_state {
+       struct tevent_context *ev;
+       fstring name_domain, name_group;
+       struct dom_sid sid;
+       const char *domname;
+       const char *name;
+       gid_t gid;
+       struct talloc_dict *members;
+};
+
+static void winbindd_getgrnam_lookupsid_done(struct tevent_req *subreq);
+static void winbindd_getgrnam_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx,
+                                         struct tevent_context *ev,
+                                         struct winbindd_request *request)
+{
+       struct tevent_req *req, *subreq;
+       struct winbindd_getgrnam_state *state;
+       struct winbindd_domain *domain;
+       char *tmp;
+       NTSTATUS nt_status;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_getgrnam_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+
+       /* Ensure null termination */
+       request->data.groupname[sizeof(request->data.groupname)-1]='\0';
+
+       DEBUG(3, ("getgrnam %s\n", request->data.groupname));
+
+       nt_status = normalize_name_unmap(state, request->data.groupname, &tmp);
+       /* If we didn't map anything in the above call, just reset the
+          tmp pointer to the original string */
+       if (!NT_STATUS_IS_OK(nt_status) &&
+           !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
+       {
+               tmp = request->data.groupname;
+       }
+
+       /* Parse domain and groupname */
+
+       parse_domain_user(tmp, state->name_domain, state->name_group);
+
+       /* if no domain or our local domain and no local tdb group, default to
+        * our local domain for aliases */
+
+       if ( !*(state->name_domain) || strequal(state->name_domain,
+                                               get_global_sam_name()) ) {
+               fstrcpy(state->name_domain, get_global_sam_name());
+       }
+
+       /* Get info for the domain */
+
+       domain = find_domain_from_name_noinit(state->name_domain);
+       if (domain == NULL) {
+               DEBUG(3, ("could not get domain sid for domain %s\n",
+                         state->name_domain));
+               tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP);
+               return tevent_req_post(req, ev);
+       }
+
+       /* should we deal with users for our domain? */
+
+       if ( lp_winbind_trusted_domains_only() && domain->primary) {
+               DEBUG(7,("winbindd_getgrnam: My domain -- rejecting "
+                        "getgrnam() for %s\\%s.\n", state->name_domain,
+                        state->name_group));
+               tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP);
+               return tevent_req_post(req, ev);
+       }
+
+       subreq = wb_lookupname_send(state, ev, domain->name, state->name_group,
+                                   0);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_getgrnam_lookupsid_done,
+                               req);
+       return req;
+}
+
+static void winbindd_getgrnam_lookupsid_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_getgrnam_state *state = tevent_req_data(
+               req, struct winbindd_getgrnam_state);
+       enum lsa_SidType type;
+       NTSTATUS status;
+
+       status = wb_lookupname_recv(subreq, &state->sid, &type);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+
+       if ( (type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) ) {
+               DEBUG(5,("getgrnam_recv: not a group!\n"));
+               tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP);
+               return;
+       }
+
+       subreq = wb_getgrsid_send(state, state->ev, &state->sid,
+                                 lp_winbind_expand_groups());
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, winbindd_getgrnam_done, req);
+}
+
+static void winbindd_getgrnam_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_getgrnam_state *state = tevent_req_data(
+               req, struct winbindd_getgrnam_state);
+       NTSTATUS status;
+
+       status = wb_getgrsid_recv(subreq, state, &state->domname, &state->name,
+                                 &state->gid, &state->members);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
+
+NTSTATUS winbindd_getgrnam_recv(struct tevent_req *req,
+                               struct winbindd_response *response)
+{
+       struct winbindd_getgrnam_state *state = tevent_req_data(
+               req, struct winbindd_getgrnam_state);
+       NTSTATUS status;
+       int num_members;
+       char *buf;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               DEBUG(5, ("Could not convert sid %s: %s\n",
+                         sid_string_dbg(&state->sid), nt_errstr(status)));
+               return status;
+       }
+
+       if (!fill_grent(talloc_tos(), &response->data.gr, state->domname,
+                       state->name, state->gid)) {
+               DEBUG(5, ("fill_grent failed\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = winbindd_print_groupmembers(state->members, response,
+                                            &num_members, &buf);
+
+       response->data.gr.num_gr_mem = (uint32)num_members;
+
+       /* Group membership lives at start of extra data */
+
+       response->data.gr.gr_mem_ofs = 0;
+       response->extra_data.data = buf;
+       response->length += talloc_get_size(response->extra_data.data);
+
+       return NT_STATUS_OK;
+}
index f33b52f83fe15115622b1a056db9585463d9eb65..6520c43f2f76073e4e1638aed6b2c526a168a2a8 100644 (file)
@@ -755,258 +755,6 @@ done:
        return result;
 }
 
-static void winbindd_getgrsid(struct winbindd_cli_state *state, DOM_SID group_sid);
-
-static void getgrnam_recv( void *private_data, bool success, const DOM_SID *sid,
-                          enum lsa_SidType type )
-{
-       struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data;
-
-       if (!success) {
-               DEBUG(5,("getgrnam_recv: lookupname failed!\n"));
-               request_error(state);
-               return;
-       }
-
-       if ( (type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) ) {
-               DEBUG(5,("getgrnam_recv: not a group!\n"));
-               request_error(state);
-               return;
-       }
-
-       winbindd_getgrsid( state, *sid );
-}
-
-
-/* Return a group structure from a group name */
-
-void winbindd_getgrnam(struct winbindd_cli_state *state)
-{
-       struct winbindd_domain *domain;
-       fstring name_domain, name_group;
-       char *tmp;
-       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
-       /* Ensure null termination */
-       state->request->data.groupname[sizeof(state->request->data.groupname)-1]='\0';
-
-       DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid,
-                 state->request->data.groupname));
-
-       nt_status = normalize_name_unmap(state->mem_ctx,
-                                        state->request->data.groupname,
-                                        &tmp);
-       /* If we didn't map anything in the above call, just reset the
-          tmp pointer to the original string */
-       if (!NT_STATUS_IS_OK(nt_status) &&
-           !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
-       {
-               tmp = state->request->data.groupname;
-       }
-
-       /* Parse domain and groupname */
-
-       memset(name_group, 0, sizeof(name_group));
-
-       name_domain[0] = '\0';
-       name_group[0] = '\0';
-
-       parse_domain_user(tmp, name_domain, name_group);
-
-       /* if no domain or our local domain and no local tdb group, default to
-        * our local domain for aliases */
-
-       if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) {
-               fstrcpy(name_domain, get_global_sam_name());
-       }
-
-       /* Get info for the domain */
-
-       if ((domain = find_domain_from_name_noinit(name_domain)) == NULL) {
-               DEBUG(3, ("could not get domain sid for domain %s\n",
-                         name_domain));
-               request_error(state);
-               return;
-       }
-       /* should we deal with users for our domain? */
-
-       if ( lp_winbind_trusted_domains_only() && domain->primary) {
-               DEBUG(7,("winbindd_getgrnam: My domain -- rejecting "
-                        "getgrnam() for %s\\%s.\n", name_domain, name_group));
-               request_error(state);
-               return;
-       }
-
-       /* Get rid and name type from name */
-
-       fstrcpy( name_group, tmp );
-
-       winbindd_lookupname_async( state->mem_ctx, domain->name, name_group,
-                                  getgrnam_recv, WINBINDD_GETGRNAM, state );
-}
-
-struct getgrsid_state {
-       struct winbindd_cli_state *state;
-       struct winbindd_domain *domain;
-       char *group_name;
-       enum lsa_SidType group_type;
-       uid_t gid;
-       DOM_SID group_sid;
-};
-
-static void getgrsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
-{
-       struct getgrsid_state *s =
-               (struct getgrsid_state *)private_data;
-       struct winbindd_domain *domain;
-       size_t gr_mem_len;
-       size_t num_gr_mem;
-       char *gr_mem;
-       fstring dom_name, group_name;
-
-       if (!success) {
-               DEBUG(5,("getgrsid_sid2gid_recv: sid2gid failed!\n"));
-               request_error(s->state);
-               return;
-       }
-
-       s->gid = gid;
-
-       if ( !parse_domain_user( s->group_name, dom_name, group_name ) ) {
-               DEBUG(5,("getgrsid_sid2gid_recv: parse_domain_user() failed!\n"));
-               request_error(s->state);
-               return;
-       }
-
-
-       /* Fill in group structure */
-
-       if ( (domain = find_domain_from_name_noinit(dom_name)) == NULL ) {
-               DEBUG(1,("Can't find domain from name (%s)\n", dom_name));
-               request_error(s->state);
-               return;
-       }
-
-       if (!fill_grent(s->state->mem_ctx, &s->state->response->data.gr,
-                       dom_name, group_name, gid) ||
-           !fill_grent_mem(domain, s->state, &s->group_sid, s->group_type,
-                           &num_gr_mem, &gr_mem, &gr_mem_len))
-       {
-               request_error(s->state);
-               return;
-       }
-
-       s->state->response->data.gr.num_gr_mem = (uint32)num_gr_mem;
-
-       /* Group membership lives at start of extra data */
-
-       s->state->response->data.gr.gr_mem_ofs = 0;
-
-       s->state->response->length += gr_mem_len;
-       s->state->response->extra_data.data = talloc_memdup(
-               s->state->mem_ctx, gr_mem, gr_mem_len);
-       if (s->state->response->extra_data.data == NULL) {
-               request_error(s->state);
-               return;
-       }
-
-       request_ok(s->state);
-}
-
-static void getgrsid_lookupsid_recv( void *private_data, bool success,
-                                    const char *dom_name, const char *name,
-                                    enum lsa_SidType name_type )
-{
-       struct getgrsid_state *s = (struct getgrsid_state *)private_data;
-       char *mapped_name = NULL;
-       fstring raw_name;
-       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
-       if (!success) {
-               DEBUG(5,("getgrsid_lookupsid_recv: lookupsid failed!\n"));
-               request_error(s->state);
-               return;
-       }
-
-       /* either it's a domain group, a domain local group, or a
-          local group in an internal domain */
-
-       if ( !( (name_type==SID_NAME_DOM_GRP) ||
-               ((name_type==SID_NAME_ALIAS) &&
-                (s->domain->primary || s->domain->internal)) ) )
-       {
-               DEBUG(1, ("name '%s\\%s' is not a local or domain group: %d\n",
-                         dom_name, name, name_type));
-               request_error(s->state);
-               return;
-       }
-
-       /* normalize the name and ensure that we have the DOM\name
-         coming out of here */
-
-       fstrcpy(raw_name, name);
-
-       nt_status = normalize_name_unmap(s->state->mem_ctx, raw_name,
-                                        &mapped_name);
-
-       /* basic whitespace reversal */
-       if (NT_STATUS_IS_OK(nt_status)) {
-               s->group_name = talloc_asprintf(s->state->mem_ctx,
-                                               "%s%c%s",
-                                               dom_name,
-                                               *lp_winbind_separator(),
-                                               mapped_name);
-       }
-       /* mapped from alias */
-       else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
-               s->group_name = mapped_name;
-       }
-       /* no mapping at all.  use original string */
-       else {
-               s->group_name = talloc_asprintf(s->state->mem_ctx,
-                                               "%s%c%s",
-                                               dom_name,
-                                               *lp_winbind_separator(),
-                                               raw_name);
-       }
-
-       if (s->group_name == NULL) {
-               DEBUG(1, ("getgrsid_lookupsid_recv: group_name is NULL!\n"));
-               request_error(s->state);
-               return;
-       }
-
-       s->group_type = name_type;
-
-       winbindd_sid2gid_async(s->state->mem_ctx, &s->group_sid,
-                              getgrsid_sid2gid_recv, s);
-}
-
-static void winbindd_getgrsid( struct winbindd_cli_state *state, const DOM_SID group_sid )
-{
-       struct getgrsid_state *s;
-
-       if ( (s = TALLOC_ZERO_P(state->mem_ctx, struct getgrsid_state)) == NULL ) {
-               DEBUG(0, ("talloc failed\n"));
-               request_error(state);
-               return;
-       }
-
-       s->state = state;
-
-       if ( (s->domain = find_domain_from_sid_noinit(&group_sid)) == NULL ) {
-               DEBUG(3, ("Could not find domain for sid %s\n",
-                         sid_string_dbg(&group_sid)));
-               request_error(state);
-               return;
-       }
-
-       sid_copy(&s->group_sid, &group_sid);
-
-       winbindd_lookupsid_async( s->state->mem_ctx,  &group_sid,
-                                 getgrsid_lookupsid_recv, s );
-}
-
 /*
  * set/get/endgrent functions
  */
index f68cc2ec40f56b26cc36ba9def3114758851dfd1..d462d8a6e1e7633dfca9f7e94241455690739a0c 100644 (file)
@@ -817,4 +817,10 @@ struct tevent_req *winbindd_getgrgid_send(TALLOC_CTX *mem_ctx,
 NTSTATUS winbindd_getgrgid_recv(struct tevent_req *req,
                                struct winbindd_response *response);
 
+struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx,
+                                         struct tevent_context *ev,
+                                         struct winbindd_request *request);
+NTSTATUS winbindd_getgrnam_recv(struct tevent_req *req,
+                               struct winbindd_response *response);
+
 #endif /*  _WINBINDD_PROTO_H_  */