summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in1
-rw-r--r--source3/winbindd/winbindd.c3
-rw-r--r--source3/winbindd/winbindd_getgrnam.c190
-rw-r--r--source3/winbindd/winbindd_group.c252
-rw-r--r--source3/winbindd/winbindd_proto.h6
5 files changed, 199 insertions, 253 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index d96dc2aaf1..f1fac93d5b 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index bbcfede030..554cb0a30a 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -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
index 0000000000..85e60a2757
--- /dev/null
+++ b/source3/winbindd/winbindd_getgrnam.c
@@ -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;
+}
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index f33b52f83f..6520c43f2f 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -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
*/
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index f68cc2ec40..d462d8a6e1 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -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_ */