NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *samr_pipe, struct policy_handle *samr_policy, uint32_t *pnum_info, struct wb_acct_info **pinfo) { struct wb_acct_info *info = NULL; uint32_t num_info = 0; NTSTATUS status, result; struct dcerpc_binding_handle *b = samr_pipe->binding_handle; *pnum_info = 0; do { struct samr_SamArray *sam_array = NULL; uint32_t count = 0; uint32_t start = num_info; uint32_t g; status = dcerpc_samr_EnumDomainAliases(b, mem_ctx, samr_policy, &start, &sam_array, 0xFFFF, /* buffer size? */ &count, &result); if (!NT_STATUS_IS_OK(status)) { return status; } if (!NT_STATUS_IS_OK(result)) { if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { return result; } } info = TALLOC_REALLOC_ARRAY(mem_ctx, info, struct wb_acct_info, num_info + count); if (info == NULL) { return NT_STATUS_NO_MEMORY; } for (g = 0; g < count; g++) { fstrcpy(info[num_info + g].acct_name, sam_array->entries[g].name.string); info[num_info + g].rid = sam_array->entries[g].idx; } num_info += count; } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); *pnum_info = num_info; *pinfo = info; return NT_STATUS_OK; }
WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx, struct NetLocalGroupEnum *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status, result; WERROR werr; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; uint32_t entries_read = 0; union samr_DomainInfo *domain_info = NULL; union samr_DomainInfo *builtin_info = NULL; struct samr_SamArray *domain_sam_array = NULL; struct samr_SamArray *builtin_sam_array = NULL; int i; struct dcerpc_binding_handle *b = NULL; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 1: break; default: return WERR_UNKNOWN_LEVEL; } if (r->out.total_entries) { *r->out.total_entries = 0; } if (r->out.entries_read) { *r->out.entries_read = 0; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(), &builtin_handle, 2, &builtin_info, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } if (r->out.total_entries) { *r->out.total_entries += builtin_info->general.num_aliases; } status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(), &domain_handle, 2, &domain_info, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } if (r->out.total_entries) { *r->out.total_entries += domain_info->general.num_aliases; } status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(), &builtin_handle, r->in.resume_handle, &builtin_sam_array, r->in.prefmaxlen, &entries_read, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } for (i=0; i<builtin_sam_array->count; i++) { union samr_AliasInfo *alias_info = NULL; if (r->in.level == 1) { status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli, &builtin_handle, builtin_sam_array->entries[i].idx, SAMR_ALIAS_ACCESS_LOOKUP_INFO, ALIASINFOALL, &alias_info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } werr = map_alias_info_to_buffer(ctx, builtin_sam_array->entries[i].name.string, alias_info ? &alias_info->all : NULL, r->in.level, r->out.entries_read, r->out.buffer); } status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(), &domain_handle, r->in.resume_handle, &domain_sam_array, r->in.prefmaxlen, &entries_read, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } for (i=0; i<domain_sam_array->count; i++) { union samr_AliasInfo *alias_info = NULL; if (r->in.level == 1) { status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli, &domain_handle, domain_sam_array->entries[i].idx, SAMR_ALIAS_ACCESS_LOOKUP_INFO, ALIASINFOALL, &alias_info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } werr = map_alias_info_to_buffer(ctx, domain_sam_array->entries[i].name.string, alias_info ? &alias_info->all : NULL, r->in.level, r->out.entries_read, r->out.buffer); } done: if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }