From 855d2a927e7badbc6bfbd358b6e94ec8bb9cb47f Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 26 Dec 2008 11:32:09 +0100 Subject: s4 libnet: Add support for groupinfo by sid lookup --- source4/libnet/libnet_group.c | 96 ++++++++++++++++++++++++++--------- source4/libnet/libnet_group.h | 10 +++- source4/torture/libnet/libnet_group.c | 5 +- source4/winbind/wb_cmd_getgrnam.c | 3 +- 4 files changed, 87 insertions(+), 27 deletions(-) (limited to 'source4') diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c index 9f1060285a..b0669640f3 100644 --- a/source4/libnet/libnet_group.c +++ b/source4/libnet/libnet_group.c @@ -172,7 +172,9 @@ NTSTATUS libnet_CreateGroup(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct group_info_state { struct libnet_context *ctx; const char *domain_name; + enum libnet_GroupInfo_level level; const char *group_name; + const char *sid_string; struct libnet_LookupName lookup; struct libnet_DomainOpen domopen; struct libnet_rpc_groupinfo info; @@ -203,7 +205,7 @@ struct composite_context* libnet_GroupInfo_send(struct libnet_context *ctx, struct composite_context *c; struct group_info_state *s; bool prereq_met = false; - struct composite_context *lookup_req; + struct composite_context *lookup_req, *info_req; /* composite context allocation and setup */ c = composite_create(mem_ctx, ctx->event_ctx); @@ -216,25 +218,54 @@ struct composite_context* libnet_GroupInfo_send(struct libnet_context *ctx, /* store arguments in the state structure */ s->monitor_fn = monitor; - s->ctx = ctx; + s->ctx = ctx; s->domain_name = talloc_strdup(c, io->in.domain_name); - s->group_name = talloc_strdup(c, io->in.group_name); + s->level = io->in.level; + switch(s->level) { + case GROUP_INFO_BY_NAME: + s->group_name = talloc_strdup(c, io->in.data.group_name); + s->sid_string = NULL; + break; + case GROUP_INFO_BY_SID: + s->group_name = NULL; + s->sid_string = dom_sid_string(c, io->in.data.group_sid); + break; + } /* prerequisite: make sure the domain is opened */ prereq_met = samr_domain_opened(ctx, s->domain_name, &c, &s->domopen, continue_domain_open_info, monitor); if (!prereq_met) return c; - - /* prepare arguments for LookupName call */ - s->lookup.in.name = s->group_name; - s->lookup.in.domain_name = s->domain_name; - /* send the request */ - lookup_req = libnet_LookupName_send(s->ctx, c, &s->lookup, s->monitor_fn); - if (composite_nomem(lookup_req, c)) return c; + switch(s->level) { + case GROUP_INFO_BY_NAME: + /* prepare arguments for LookupName call */ + s->lookup.in.name = s->group_name; + s->lookup.in.domain_name = s->domain_name; + + /* send the request */ + lookup_req = libnet_LookupName_send(s->ctx, c, &s->lookup, s->monitor_fn); + if (composite_nomem(lookup_req, c)) return c; + + /* set the next stage */ + composite_continue(c, lookup_req, continue_name_found, c); + break; + case GROUP_INFO_BY_SID: + /* prepare arguments for groupinfo call */ + s->info.in.domain_handle = s->ctx->samr.handle; + s->info.in.sid = s->sid_string; + /* we're looking for all information available */ + s->info.in.level = GROUPINFOALL; + + /* send the request */ + info_req = libnet_rpc_groupinfo_send(s->ctx->samr.pipe, &s->info, s->monitor_fn); + if (composite_nomem(info_req, c)) return c; + + /* set the next stage */ + composite_continue(c, info_req, continue_group_info, c); + break; + } - /* set the next stage */ - composite_continue(c, lookup_req, continue_name_found, c); return c; } @@ -246,7 +277,7 @@ static void continue_domain_open_info(struct composite_context *ctx) { struct composite_context *c; struct group_info_state *s; - struct composite_context *lookup_req; + struct composite_context *lookup_req, *info_req; c = talloc_get_type(ctx->async.private_data, struct composite_context); s = talloc_get_type(c->private_data, struct group_info_state); @@ -255,16 +286,35 @@ static void continue_domain_open_info(struct composite_context *ctx) c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domopen); if (!composite_is_ok(c)) return; - /* prepare arguments for LookupName call */ - s->lookup.in.name = s->group_name; - s->lookup.in.domain_name = s->domain_name; + switch(s->level) { + case GROUP_INFO_BY_NAME: + /* prepare arguments for LookupName call */ + s->lookup.in.name = s->group_name; + s->lookup.in.domain_name = s->domain_name; + + /* send the request */ + lookup_req = libnet_LookupName_send(s->ctx, c, &s->lookup, s->monitor_fn); + if (composite_nomem(lookup_req, c)) return; + + /* set the next stage */ + composite_continue(c, lookup_req, continue_name_found, c); + break; + case GROUP_INFO_BY_SID: + /* prepare arguments for groupinfo call */ + s->info.in.domain_handle = s->ctx->samr.handle; + s->info.in.sid = s->sid_string; + /* we're looking for all information available */ + s->info.in.level = GROUPINFOALL; + + /* send the request */ + info_req = libnet_rpc_groupinfo_send(s->ctx->samr.pipe, &s->info, s->monitor_fn); + if (composite_nomem(info_req, c)) return; + + /* set the next stage */ + composite_continue(c, info_req, continue_group_info, c); + break; - /* send the request */ - lookup_req = libnet_LookupName_send(s->ctx, c, &s->lookup, s->monitor_fn); - if (composite_nomem(lookup_req, c)) return; - - /* set the next stage */ - composite_continue(c, lookup_req, continue_name_found, c); + } } @@ -283,7 +333,7 @@ static void continue_name_found(struct composite_context *ctx) /* receive SID assiociated with name found */ c->status = libnet_LookupName_recv(ctx, c, &s->lookup); if (!composite_is_ok(c)) return; - + /* Is is a group SID actually ? */ if (s->lookup.out.sid_type != SID_NAME_DOM_GRP && s->lookup.out.sid_type != SID_NAME_ALIAS) { diff --git a/source4/libnet/libnet_group.h b/source4/libnet/libnet_group.h index bdd2c04fec..b80d3449c8 100644 --- a/source4/libnet/libnet_group.h +++ b/source4/libnet/libnet_group.h @@ -29,11 +29,19 @@ struct libnet_CreateGroup { } out; }; +enum libnet_GroupInfo_level { + GROUP_INFO_BY_NAME=0, + GROUP_INFO_BY_SID +}; struct libnet_GroupInfo { struct { - const char *group_name; const char *domain_name; + enum libnet_GroupInfo_level level; + union { + const char *group_name; + const struct dom_sid *group_sid; + } data; } in; struct { const char *group_name; diff --git a/source4/torture/libnet/libnet_group.c b/source4/torture/libnet/libnet_group.c index 9c9ecfd525..c7fdfbd10b 100644 --- a/source4/torture/libnet/libnet_group.c +++ b/source4/torture/libnet/libnet_group.c @@ -264,9 +264,10 @@ bool torture_groupinfo_api(struct torture_context *torture) mem_ctx = talloc_init("torture group info"); ZERO_STRUCT(req); - + req.in.domain_name = domain_name.string; - req.in.group_name = name; + req.in.level = GROUP_INFO_BY_NAME; + req.in.data.group_name = name; status = libnet_GroupInfo(ctx, mem_ctx, &req); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/winbind/wb_cmd_getgrnam.c b/source4/winbind/wb_cmd_getgrnam.c index 5da3922c6c..bfc30fc7a6 100644 --- a/source4/winbind/wb_cmd_getgrnam.c +++ b/source4/winbind/wb_cmd_getgrnam.c @@ -92,7 +92,8 @@ static void cmd_getgrnam_recv_domain(struct composite_context *ctx) return; } - group_info->in.group_name = group_name; + group_info->in.level = GROUP_INFO_BY_NAME; + group_info->in.data.group_name = group_name; group_info->in.domain_name = group_dom; state->workgroup_name = talloc_strdup(state, group_dom); if(composite_nomem(state->workgroup_name, state->ctx)) return; -- cgit