示例#1
0
static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli, 
                                        TALLOC_CTX *mem_ctx,
                                        int argc, const char **argv) 
{
	POLICY_HND connect_pol, domain_pol, group_pol;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	uint32 num_members, *group_rids, *group_attrs, group_rid;
	uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
	int i;
	fstring			server;
	
	if ((argc < 2) || (argc > 3)) {
		printf("Usage: %s rid [access mask]\n", argv[0]);
		return NT_STATUS_OK;
	}

	sscanf(argv[1], "%i", &group_rid);
	
	if (argc > 2)
		sscanf(argv[2], "%x", &access_mask);

	slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
	strupper_m(server);

	result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
				   &connect_pol);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
				      MAXIMUM_ALLOWED_ACCESS,
				      &domain_sid, &domain_pol);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
				     access_mask,
				     group_rid, &group_pol);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
					 &num_members, &group_rids,
					 &group_attrs);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	for (i = 0; i < num_members; i++) {
		printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
		       group_attrs[i]);
	}

 done:
	return result;
}
示例#2
0
/* Lookup group membership given a rid.   */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
				TALLOC_CTX *mem_ctx,
				const DOM_SID *group_sid, uint32 *num_names, 
				DOM_SID ***sid_mem, char ***names, 
				uint32 **name_types)
{
        CLI_POLICY_HND *hnd = NULL;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 i, total_names = 0;
        POLICY_HND dom_pol, group_pol;
        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
        BOOL got_dom_pol = False, got_group_pol = False;
	uint32 *rid_mem = NULL;
	uint32 group_rid;
	int retry;
	unsigned int j;
	fstring sid_string;

	DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));

	if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
		goto done;
	}

	*num_names = 0;

	retry = 0;
	do {
	        /* Get sam handle */
		if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
			goto done;

		/* Get domain handle */

		result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
				des_access, &domain->sid, &dom_pol);
	} while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);

        if (!NT_STATUS_IS_OK(result))
                goto done;

        got_dom_pol = True;

        /* Get group handle */

        result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
                                     des_access, group_rid, &group_pol);

        if (!NT_STATUS_IS_OK(result))
                goto done;

        got_group_pol = True;

        /* Step #1: Get a list of user rids that are the members of the
           group. */

        result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
                                         &group_pol, num_names, &rid_mem,
                                         name_types);

        if (!NT_STATUS_IS_OK(result))
                goto done;

	if (!*num_names) {
		names = NULL;
		name_types = NULL;
		sid_mem = NULL;
		goto done;
	}

        /* Step #2: Convert list of rids into list of usernames.  Do this
           in bunches of ~1000 to avoid crashing NT4.  It looks like there
           is a buffer overflow or something like that lurking around
           somewhere. */

#define MAX_LOOKUP_RIDS 900

        *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
        *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
        *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));

	for (j=0;j<(*num_names);j++) {
		(*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
	}
	
	if (*num_names>0 && (!*names || !*name_types)) {
		result = NT_STATUS_NO_MEMORY;
		goto done;
	}

        for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
                int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
                uint32 tmp_num_names = 0;
                char **tmp_names = NULL;
                uint32 *tmp_types = NULL;

                /* Lookup a chunk of rids */

                result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
                                              &dom_pol, 1000, /* flags */
                                              num_lookup_rids,
                                              &rid_mem[i],
                                              &tmp_num_names,
                                              &tmp_names, &tmp_types);

		/* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
		   the one returned from 2k) */
		
                if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
                        goto done;
			
                /* Copy result into array.  The talloc system will take
                   care of freeing the temporary arrays later on. */

                memcpy(&(*names)[i], tmp_names, sizeof(char *) * 
                       tmp_num_names);

                memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
                       tmp_num_names);
		
                total_names += tmp_num_names;
        }

        *num_names = total_names;

 	result = NT_STATUS_OK;
	
done:
        if (got_group_pol)
                cli_samr_close(hnd->cli, mem_ctx, &group_pol);

        if (got_dom_pol)
                cli_samr_close(hnd->cli, mem_ctx, &dom_pol);

        return result;
}