/*
  convert a domain SID to a user or group name
*/
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
			    TALLOC_CTX *mem_ctx,
			    const DOM_SID *sid,
			    char **domain_name,
			    char **name,
			    enum lsa_SidType *type)
{
	const char *dom, *nam;

	DEBUG(10, ("Converting SID %s\n", sid_string_static(sid)));

	/* Paranoia check */
	if (!sid_check_is_in_builtin(sid) &&
	    !sid_check_is_in_our_domain(sid)) {
		DEBUG(0, ("Possible deadlock: Trying to lookup SID %s with "
			  "passdb backend\n", sid_string_static(sid)));
		return NT_STATUS_NONE_MAPPED;
	}

	if (!lookup_sid(mem_ctx, sid, &dom, &nam, type)) {
		return NT_STATUS_NONE_MAPPED;
	}

	*domain_name = talloc_strdup(mem_ctx, dom);
	*name = talloc_strdup(mem_ctx, nam);

	return NT_STATUS_OK;
}
Exemple #2
0
/* Lookup user information from a rid or username. */
static NTSTATUS sam_query_user(struct winbindd_domain *domain,
			       TALLOC_CTX *mem_ctx,
			       const struct dom_sid *user_sid,
			       struct wbint_userinfo *user_info)
{
	struct rpc_pipe_client *samr_pipe;
	struct policy_handle dom_pol;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS status, result;
	struct dcerpc_binding_handle *b = NULL;

	DEBUG(3,("sam_query_user\n"));

	ZERO_STRUCT(dom_pol);

	/* Paranoia check */
	if (!sid_check_is_in_our_domain(user_sid)) {
		return NT_STATUS_NO_SUCH_USER;
	}

	if (user_info) {
		user_info->homedir = NULL;
		user_info->shell = NULL;
		user_info->primary_gid = (gid_t) -1;
	}

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	b = samr_pipe->binding_handle;

	status = rpc_query_user(tmp_ctx,
				samr_pipe,
				&dom_pol,
				&domain->sid,
				user_sid,
				user_info);

done:
	if (b && is_valid_policy_hnd(&dom_pol)) {
		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}
Exemple #3
0
static int net_groupmap_cleanup(struct net_context *c, int argc, const char **argv)
{
	GROUP_MAP **maps = NULL;
	size_t i, entries;

	if (c->display_usage) {
		d_printf(  "%s\n"
			   "net groupmap cleanup\n"
			   "    %s\n",
			 _("Usage:"),
			 _("Delete all group mappings"));
		return 0;
	}

	if (!pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &maps, &entries,
				    ENUM_ALL_MAPPED)) {
		d_fprintf(stderr, _("Could not list group mappings\n"));
		return -1;
	}

	for (i=0; i<entries; i++) {

		if (maps[i]->gid == -1)
			printf(_("Group %s is not mapped\n"),
				maps[i]->nt_name);

		if (!sid_check_is_in_our_domain(&maps[i]->sid)) {
			printf(_("Deleting mapping for NT Group %s, sid %s\n"),
				maps[i]->nt_name,
				sid_string_tos(&maps[i]->sid));
			pdb_delete_group_mapping_entry(maps[i]->sid);
		}
	}

	TALLOC_FREE(maps);
	return 0;
}
Exemple #4
0
/* convert a domain SID to a user or group name */
static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
				TALLOC_CTX *mem_ctx,
				const struct dom_sid *sid,
				char **pdomain_name,
				char **pname,
				enum lsa_SidType *ptype)
{
	struct rpc_pipe_client *lsa_pipe;
	struct policy_handle lsa_policy;
	char *domain_name = NULL;
	char *name = NULL;
	enum lsa_SidType type;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS status, result;
	struct dcerpc_binding_handle *b = NULL;

	DEBUG(3,("sam_sid_to_name\n"));

	ZERO_STRUCT(lsa_policy);

	/* Paranoia check */
	if (!sid_check_is_in_builtin(sid) &&
	    !sid_check_is_in_our_domain(sid) &&
	    !sid_check_is_in_unix_users(sid) &&
	    !sid_check_is_unix_users(sid) &&
	    !sid_check_is_in_unix_groups(sid) &&
	    !sid_check_is_unix_groups(sid) &&
	    !sid_check_is_in_wellknown_domain(sid)) {
		DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
			  "lookup SID %s\n", sid_string_dbg(sid)));
		return NT_STATUS_NONE_MAPPED;
	}

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	b = lsa_pipe->binding_handle;

	status = rpc_sid_to_name(tmp_ctx,
				 lsa_pipe,
				 &lsa_policy,
				 domain,
				 sid,
				 &domain_name,
				 &name,
				 &type);

	if (ptype) {
		*ptype = type;
	}

	if (pname) {
		*pname = talloc_move(mem_ctx, &name);
	}

	if (pdomain_name) {
		*pdomain_name = talloc_move(mem_ctx, &domain_name);
	}

done:
	if (b && is_valid_policy_hnd(&lsa_policy)) {
		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}
Exemple #5
0
/*******************************************************************
 gets a domain user's groups
 ********************************************************************/
BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass)
{
	GROUP_MAP *map=NULL;
	int i, num, num_entries, cur_gid=0;
	struct group *grp;
	DOM_GID *gids;
	fstring user_name;
	uint32 grid;
	uint32 tmp_rid;
	BOOL ret;

	*numgroups= 0;

	fstrcpy(user_name, pdb_get_username(sam_pass));
	grid=pdb_get_group_rid(sam_pass);

	DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name));

	/* we must wrap this is become/unbecome root for ldap backends */
	
	become_root();
	/* first get the list of the domain groups */
	ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
	
	unbecome_root();

	/* end wrapper for group enumeration */

	
	if ( !ret )
		return False;
		
	DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries));


	/* 
	 * alloc memory. In the worse case, we alloc memory for nothing.
	 * but I prefer to alloc for nothing
	 * than reallocing everytime.
	 */
	gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) *  num_entries);	

	/* for each group, check if the user is a member of.  Only include groups 
	   from this domain */
	
	for(i=0; i<num_entries; i++) {
	
		if ( !sid_check_is_in_our_domain(&map[i].sid) ) {
			DEBUG(10,("get_domain_user_groups: skipping check of %s since it is not in our domain\n",
				map[i].nt_name));
			continue;
		}
			
		if ((grp=sys_getgrgid(map[i].gid)) == NULL) {
			/* very weird !!! */
			DEBUG(5,("get_domain_user_groups: gid %d doesn't exist anymore !\n", (int)map[i].gid));
			continue;
		}

		for(num=0; grp->gr_mem[num]!=NULL; num++) {
			if(strcmp(grp->gr_mem[num], user_name)==0) {
				/* we found the user, add the group to the list */
				sid_peek_rid(&map[i].sid, &(gids[cur_gid].g_rid));
				gids[cur_gid].attr=7;
				DEBUG(10,("get_domain_user_groups: user found in group %s\n", map[i].nt_name));
				cur_gid++;
				break;
			}
		}
	}

	/* we have checked the groups */
	/* we must now check the gid of the user or the primary group rid, that's the same */
	for (i=0; i<cur_gid && grid!=gids[i].g_rid; i++)
		;
	
	/* the user's gid is already there */
	if (i!=cur_gid) {
		/* 
		 * the primary group of the user but be the first one in the list
		 * don't ask ! JFM.
		 */
		gids[i].g_rid=gids[0].g_rid;
		gids[0].g_rid=grid;
		goto done;
	}

	for(i=0; i<num_entries; i++) {
		sid_peek_rid(&map[i].sid, &tmp_rid);
		if (tmp_rid==grid) {
			/* 
			 * the primary group of the user but be the first one in the list
			 * don't ask ! JFM.
			 */
			gids[cur_gid].g_rid=gids[0].g_rid;
			gids[0].g_rid=tmp_rid;
			gids[cur_gid].attr=7;
			DEBUG(10,("get_domain_user_groups: primary gid of user found in group %s\n", map[i].nt_name));
			cur_gid++;
			goto done; /* leave the loop early */
		}
	}

	DEBUG(0,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", user_name));
	DEBUGADD(0,("get_domain_user_groups: You should fix it, NT doesn't like that\n"));


 done:
	*pgids=gids;
	*numgroups=cur_gid;
	SAFE_FREE(map);

	return True;
}
Exemple #6
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)
{
	size_t i, num_members, num_mapped;
	uint32 *rids;
	NTSTATUS result;
	const DOM_SID **sids;
	struct lsa_dom_info *lsa_domains;
	struct lsa_name_info *lsa_names;
	TALLOC_CTX *tmp_ctx;

	if (!sid_check_is_in_our_domain(group_sid)) {
		/* There's no groups, only aliases in BUILTIN */
		return NT_STATUS_NO_SUCH_GROUP;
	}

	if (!(tmp_ctx = talloc_init("lookup_groupmem"))) {
		return NT_STATUS_NO_MEMORY;
	}

	result = pdb_enum_group_members(tmp_ctx, group_sid, &rids,
					&num_members);
	if (!NT_STATUS_IS_OK(result)) {
		TALLOC_FREE(tmp_ctx);
		return result;
	}

	if (num_members == 0) {
		*num_names = 0;
		*sid_mem = NULL;
		*names = NULL;
		*name_types = NULL;
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_OK;
	}

	*sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members);
	*names = TALLOC_ARRAY(mem_ctx, char *, num_members);
	*name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members);
	sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members);

	if (((*sid_mem) == NULL) || ((*names) == NULL) ||
	    ((*name_types) == NULL) || (sids == NULL)) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/*
	 * Prepare an array of sid pointers for the lookup_sids calling
	 * convention.
	 */

	for (i=0; i<num_members; i++) {
		DOM_SID *sid = &((*sid_mem)[i]);
		if (!sid_compose(sid, &domain->sid, rids[i])) {
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_INTERNAL_ERROR;
		}
		sids[i] = sid;
	}

	result = lookup_sids(tmp_ctx, num_members, sids, 1,
			     &lsa_domains, &lsa_names);
	if (!NT_STATUS_IS_OK(result)) {
		TALLOC_FREE(tmp_ctx);
		return result;
	}

	num_mapped = 0;
	for (i=0; i<num_members; i++) {
		if (lsa_names[i].type != SID_NAME_USER) {
			DEBUG(2, ("Got %s as group member -- ignoring\n",
				  sid_type_lookup(lsa_names[i].type)));
			continue;
		}
		if (!((*names)[i] = talloc_strdup((*names),
						  lsa_names[i].name))) {
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		(*name_types)[i] = lsa_names[i].type;

		num_mapped += 1;
	}

	*num_names = num_mapped;

	TALLOC_FREE(tmp_ctx);
	return NT_STATUS_OK;
}