Example #1
0
UNISTR2* ucs2_to_unistr2(TALLOC_CTX *ctx, UNISTR2* dst, smb_ucs2_t* src)
{
	size_t len;

	if (!src) {
		return NULL;
	}

	len = strlen_w(src);
	
	/* allocate UNISTR2 destination if not given */
	if (!dst) {
		dst = TALLOC_P(ctx, UNISTR2);
		if (!dst)
			return NULL;
	}
	if (!dst->buffer) {
		dst->buffer = TALLOC_ARRAY(ctx, uint16, len + 1);
		if (!dst->buffer)
			return NULL;
	}
	
	/* set UNISTR2 parameters */
	dst->uni_max_len = len + 1;
	dst->offset = 0;
	dst->uni_str_len = len;
	
	/* copy the actual unicode string */
	strncpy_w(dst->buffer, src, dst->uni_max_len);
	
	return dst;
}
Example #2
0
NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la, int count)
{
	int i;

	if ( !old_la )
		return NT_STATUS_OK;

	if (count) {
		*new_la = TALLOC_ARRAY(mem_ctx, LUID_ATTR, count);
		if ( !*new_la ) {
			DEBUG(0,("dup_luid_attr: failed to alloc new LUID_ATTR array [%d]\n", count));
			return NT_STATUS_NO_MEMORY;
		}
	} else {
		*new_la = NULL;
	}

	for (i=0; i<count; i++) {
		(*new_la)[i].luid.high = old_la[i].luid.high;
		(*new_la)[i].luid.low = old_la[i].luid.low;
		(*new_la)[i].attr = old_la[i].attr;
	}

	return NT_STATUS_OK;
}
Example #3
0
static NTSTATUS cli_trans_pull_blob(TALLOC_CTX *mem_ctx,
				    struct trans_recvblob *blob,
				    uint32_t total, uint32_t thistime,
				    uint8_t *buf, uint32_t displacement)
{
	if (blob->data == NULL) {
		if (total > blob->max) {
			return NT_STATUS_INVALID_NETWORK_RESPONSE;
		}
		blob->total = total;
		blob->data = TALLOC_ARRAY(mem_ctx, uint8_t, total);
		if (blob->data == NULL) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	if (total > blob->total) {
		return NT_STATUS_INVALID_NETWORK_RESPONSE;
	}

	if (thistime) {
		memcpy(blob->data + displacement, buf, thistime);
		blob->received += thistime;
	}

	return NT_STATUS_OK;
}
Example #4
0
BOOL svcctl_io_service_fa( const char *desc, SERVICE_FAILURE_ACTIONS *fa, RPC_BUFFER *buffer, int depth )
{
        prs_struct *ps = &buffer->prs;
	int i;

        prs_debug(ps, depth, desc, "svcctl_io_service_description");
        depth++;

	if ( !prs_uint32("reset_period", ps, depth, &fa->reset_period) )
		return False;

	if ( !prs_pointer( desc, ps, depth, (void**)&fa->rebootmsg, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
		return False;
	if ( !prs_pointer( desc, ps, depth, (void**)&fa->command, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
		return False;

	if ( !prs_uint32("num_actions", ps, depth, &fa->num_actions) )
		return False;

	if ( UNMARSHALLING(ps) && fa->num_actions ) {
		if ( !(fa->actions = TALLOC_ARRAY( get_talloc_ctx(), SC_ACTION, fa->num_actions )) ) {
			DEBUG(0,("svcctl_io_service_fa: talloc() failure!\n"));
			return False;
		}
	}

	for ( i=0; i<fa->num_actions; i++ ) {
		if ( !svcctl_io_action( "actions", &fa->actions[i], ps, depth ) )
			return False;
	}

	return True;
} 
Example #5
0
static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, NETDFS_DFS_INFO3* dfs3)
{
	int ii;
	pstring str;
	dfs3->ptr0_path = 1;
	if (j->volume_name[0] == '\0')
		slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s",
			global_myname(), j->service_name);
	else
		slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
			j->service_name, j->volume_name);

	init_unistr2(&dfs3->path, str, UNI_STR_TERMINATE);
	dfs3->ptr0_comment = 1;
	init_unistr2(&dfs3->comment, j->comment, UNI_STR_TERMINATE);
	dfs3->state = 1;
	dfs3->num_stores = dfs3->size_stores = j->referral_count;
    
	/* also enumerate the stores */
	if (j->referral_count) {
		dfs3->stores = TALLOC_ARRAY(ctx, NETDFS_DFS_STORAGEINFO, j->referral_count);
		if (!dfs3->stores)
			return False;
		memset(dfs3->stores, '\0', j->referral_count * sizeof(NETDFS_DFS_STORAGEINFO));
		dfs3->ptr0_stores = 1;
	} else {
		dfs3->stores = NULL;
		dfs3->ptr0_stores = 0;
	}

	for(ii=0;ii<j->referral_count;ii++) {
		char* p; 
		pstring path;
		NETDFS_DFS_STORAGEINFO* stor = &(dfs3->stores[ii]);
		struct referral* ref = &(j->referral_list[ii]);
  
		pstrcpy(path, ref->alternate_path);
		trim_char(path,'\\','\0');
		p = strrchr_m(path,'\\');
		if(p==NULL) {
			DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path));
			continue;
		}
		*p = '\0';
		DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1));
		stor->state = 2; /* set all stores as ONLINE */
		init_unistr2(&stor->server, path, UNI_STR_TERMINATE);
		init_unistr2(&stor->share,  p+1, UNI_STR_TERMINATE);
		stor->ptr0_server = stor->ptr0_share = 1;
	}
	return True;
}
Example #6
0
void _echo_EchoData(struct pipes_struct *p, struct echo_EchoData *r)
{
	DEBUG(10, ("_echo_EchoData\n"));

	if ( r->in.len == 0 ) {
		r->out.out_data = NULL;
		return;
	}

	r->out.out_data = TALLOC_ARRAY(p->mem_ctx, uint8, r->in.len);
	memcpy( r->out.out_data, r->in.in_data, r->in.len );
	return;
}
Example #7
0
NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
				       TALLOC_CTX *mem_ctx,
				       const DOM_SID *domain_sid,
				       const DOM_SID *members,
				       size_t num_members,
				       uint32 **pp_alias_rids,
				       size_t *p_num_alias_rids)
{
	DOM_SID *alias_sids;
	size_t i, num_alias_sids;
	NTSTATUS result;

	if (!init_group_mapping()) {
		DEBUG(0,("failed to initialize group mapping\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	alias_sids = NULL;
	num_alias_sids = 0;

	result = alias_memberships(members, num_members,
				   &alias_sids, &num_alias_sids);

	if (!NT_STATUS_IS_OK(result))
		return result;

	*p_num_alias_rids = 0;

	if (num_alias_sids == 0) {
		TALLOC_FREE(alias_sids);
		return NT_STATUS_OK;
	}

	*pp_alias_rids = TALLOC_ARRAY(mem_ctx, uint32, num_alias_sids);
	if (*pp_alias_rids == NULL)
		return NT_STATUS_NO_MEMORY;

	for (i=0; i<num_alias_sids; i++) {
		if (!sid_peek_check_rid(domain_sid, &alias_sids[i],
					&(*pp_alias_rids)[*p_num_alias_rids]))
			continue;
		*p_num_alias_rids += 1;
	}

	TALLOC_FREE(alias_sids);

	return NT_STATUS_OK;
}
Example #8
0
bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
			     const DOM_SID *dom_sid,
			     const DOM_SID *members,
			     size_t num_members,
			     uint32_t **pp_alias_rids,
			     size_t *p_num_alias_rids)
{
	wbcErr ret;
	struct wbcDomainSid domain_sid;
	struct wbcDomainSid *sid_list = NULL;
	size_t i;
	uint32_t * rids;
	uint32_t num_rids;

	memcpy(&domain_sid, dom_sid, sizeof(*dom_sid));

	sid_list = TALLOC_ARRAY(mem_ctx, struct wbcDomainSid, num_members);

	for (i=0; i < num_members; i++) {
	    memcpy(&sid_list[i], &members[i], sizeof(sid_list[i]));
	}

	ret = wbcGetSidAliases(&domain_sid,
			       sid_list,
			       num_members,
			       &rids,
			       &num_rids);
	if (ret != WBC_ERR_SUCCESS) {
		return false;
	}

	*pp_alias_rids = TALLOC_ARRAY(mem_ctx, uint32_t, num_rids);
	if (*pp_alias_rids == NULL) {
		wbcFreeMemory(rids);
		return false;
	}

	memcpy(*pp_alias_rids, rids, sizeof(uint32_t) * num_rids);

	*p_num_alias_rids = num_rids;
	wbcFreeMemory(rids);

	return true;
}
Example #9
0
void _echo_SourceData(struct pipes_struct *p, struct echo_SourceData *r)
{
	uint32 i;

	DEBUG(10, ("_echo_SourceData\n"));

	if ( r->in.len == 0 ) {
		r->out.data = NULL;
		return;
	}

	r->out.data = TALLOC_ARRAY(p->mem_ctx, uint8, r->in.len );

	for (i = 0; i < r->in.len; i++ ) {
		r->out.data[i] = i & 0xff;
	}

	return;
}
Example #10
0
/****************************************************************************
talloc a bitmap
****************************************************************************/
struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n)
{
    struct bitmap *bm;

    if (!mem_ctx) return NULL;

    bm = TALLOC_P(mem_ctx, struct bitmap);

    if (!bm) return NULL;

    bm->n = n;
    bm->b = TALLOC_ARRAY(mem_ctx, uint32, (n+31)/32);
    if (!bm->b) {
        return NULL;
    }

    memset(bm->b, 0, sizeof(uint32)*((n+31)/32));

    return bm;
}
Example #11
0
bool winbind_get_groups(TALLOC_CTX * mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups)
{
	wbcErr ret;
	uint32_t ngroups;
	gid_t *group_list = NULL;

	ret = wbcGetGroups(account, &ngroups, &group_list);
	if (ret != WBC_ERR_SUCCESS)
		return false;

	*_groups = TALLOC_ARRAY(mem_ctx, gid_t, ngroups);
	if (*_groups == NULL) {
	    wbcFreeMemory(group_list);
	    return false;
	}

	memcpy(*_groups, group_list, ngroups* sizeof(gid_t));
	*num_groups = ngroups;

	wbcFreeMemory(group_list);
	return true;
}
Example #12
0
static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
{
	struct policy_handle pol;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	DOM_SID *sids;
	char **domains;
	char **names;
	enum lsa_SidType *types;
	int i;

	if (argc == 1) {
		printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
		return NT_STATUS_OK;
	}

	result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
				     SEC_FLAG_MAXIMUM_ALLOWED,
				     &pol);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	/* Convert arguments to sids */

	sids = TALLOC_ARRAY(mem_ctx, DOM_SID, argc - 1);

	if (!sids) {
		printf("could not allocate memory for %d sids\n", argc - 1);
		goto done;
	}

	for (i = 0; i < argc - 1; i++) 
		if (!string_to_sid(&sids[i], argv[i + 1])) {
			result = NT_STATUS_INVALID_SID;
			goto done;
		}

	/* Lookup the SIDs */

	result = rpccli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, 
				     &domains, &names, &types);

	if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
	    NT_STATUS_V(STATUS_SOME_UNMAPPED))
		goto done;

	result = NT_STATUS_OK;

	/* Print results */

	for (i = 0; i < (argc - 1); i++) {
		fstring sid_str;

		sid_to_fstring(sid_str, &sids[i]);
		printf("%s %s\\%s (%d)\n", sid_str, 
		       domains[i] ? domains[i] : "*unknown*", 
		       names[i] ? names[i] : "*unknown*", types[i]);
	}

	rpccli_lsa_Close(cli, mem_ctx, &pol);

 done:
	return result;
}
Example #13
0
WERROR _dfs_Enum(pipes_struct *p, NETDFS_Q_DFS_ENUM *q_u, NETDFS_R_DFS_ENUM *r_u)
{
	uint32 level = q_u->level;
	struct junction_map jn[MAX_MSDFS_JUNCTIONS];
	int num_jn = 0;
	int i;

	num_jn = enum_msdfs_links(p->mem_ctx, jn, ARRAY_SIZE(jn));
	vfs_ChDir(p->conn,p->conn->connectpath);
    
	DEBUG(5,("_dfs_Enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));

	r_u->ptr0_info = q_u->ptr0_info;
	r_u->ptr0_total = q_u->ptr0_total;
	r_u->total = num_jn;

	r_u->info = q_u->info;

	/* Create the return array */
	switch (level) {
	case 1:
		r_u->info.e.u.info1.count = num_jn;
		if (num_jn) {
			if ((r_u->info.e.u.info1.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO1, num_jn)) == NULL) {
				return WERR_NOMEM;
			}
			r_u->info.e.u.info1.ptr0_s = 1;
			r_u->info.e.u.info1.size_s = num_jn;
		}
		break;
	case 2:
		r_u->info.e.u.info2.count = num_jn;
		if (num_jn) {
			if ((r_u->info.e.u.info2.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO2, num_jn)) == NULL) {
				return WERR_NOMEM;
			}
			r_u->info.e.u.info2.ptr0_s = 1;
			r_u->info.e.u.info2.size_s = num_jn;
		}
		break;
	case 3:
		r_u->info.e.u.info3.count = num_jn;
		if (num_jn) {
			if ((r_u->info.e.u.info3.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO3, num_jn)) == NULL) {
				return WERR_NOMEM;
			}
			r_u->info.e.u.info3.ptr0_s = 1;
			r_u->info.e.u.info3.size_s = num_jn;
		}
		break;
	default:
		return WERR_INVALID_PARAM;
	}

	for (i = 0; i < num_jn; i++) {
		switch (level) {
		case 1: 
			init_reply_dfs_info_1(&jn[i], &r_u->info.e.u.info1.s[i]);
			break;
		case 2:
			init_reply_dfs_info_2(&jn[i], &r_u->info.e.u.info2.s[i]);
			break;
		case 3:
			init_reply_dfs_info_3(p->mem_ctx, &jn[i], &r_u->info.e.u.info3.s[i]);
			break;
		default:
			return WERR_INVALID_PARAM;
		}
	}
  
	r_u->status = WERR_OK;

	return r_u->status;
}
Example #14
0
NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
					SEC_DESC **ppsd,
					size_t *psize,
					const SEC_DESC *parent_ctr,
					const DOM_SID *owner_sid,
					const DOM_SID *group_sid,
					bool container)
{
	SEC_ACL *new_dacl = NULL, *the_acl = NULL;
	SEC_ACE *new_ace_list = NULL;
	unsigned int new_ace_list_ndx = 0, i;

	*ppsd = NULL;
	*psize = 0;

	/* Currently we only process the dacl when creating the child.  The
	   sacl should also be processed but this is left out as sacls are
	   not implemented in Samba at the moment.*/

	the_acl = parent_ctr->dacl;

	if (the_acl->num_aces) {
		if (2*the_acl->num_aces < the_acl->num_aces) {
			return NT_STATUS_NO_MEMORY;
		}

		if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE,
						2*the_acl->num_aces))) {
			return NT_STATUS_NO_MEMORY;
		}
	} else {
		new_ace_list = NULL;
	}

	for (i = 0; i < the_acl->num_aces; i++) {
		const SEC_ACE *ace = &the_acl->aces[i];
		SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
		const DOM_SID *ptrustee = &ace->trustee;
		const DOM_SID *creator = NULL;
		uint8 new_flags = ace->flags;

		if (!is_inheritable_ace(ace, container)) {
			continue;
		}

		/* see the RAW-ACLS inheritance test for details on these rules */
		if (!container) {
			new_flags = 0;
		} else {
			new_flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;

			if (!(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
				new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
			}
			if (new_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
				new_flags = 0;
			}
		}

		/* The CREATOR sids are special when inherited */
		if (sid_equal(ptrustee, &global_sid_Creator_Owner)) {
			creator = &global_sid_Creator_Owner;
			ptrustee = owner_sid;
		} else if (sid_equal(ptrustee, &global_sid_Creator_Group)) {
			creator = &global_sid_Creator_Group;
			ptrustee = group_sid;
		}

		if (creator && container &&
				(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {

			/* First add the regular ACE entry. */
			init_sec_ace(new_ace, ptrustee, ace->type,
			     	ace->access_mask, 0);

			DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
				" inherited as %s:%d/0x%02x/0x%08x\n",
				sid_string_dbg(&ace->trustee),
				ace->type, ace->flags, ace->access_mask,
				sid_string_dbg(&new_ace->trustee),
				new_ace->type, new_ace->flags,
				new_ace->access_mask));

			new_ace_list_ndx++;

			/* Now add the extra creator ACE. */
			new_ace = &new_ace_list[new_ace_list_ndx];

			ptrustee = creator;
			new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
		} else if (container &&
				!(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
			ptrustee = &ace->trustee;
		}

		init_sec_ace(new_ace, ptrustee, ace->type,
			     ace->access_mask, new_flags);

		DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
			  " inherited as %s:%d/0x%02x/0x%08x\n",
			  sid_string_dbg(&ace->trustee),
			  ace->type, ace->flags, ace->access_mask,
			  sid_string_dbg(&ace->trustee),
			  new_ace->type, new_ace->flags,
			  new_ace->access_mask));

		new_ace_list_ndx++;
	}

	/* Create child security descriptor to return */
	if (new_ace_list_ndx) {
		new_dacl = make_sec_acl(ctx,
				NT4_ACL_REVISION,
				new_ace_list_ndx,
				new_ace_list);

		if (!new_dacl) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	*ppsd = make_sec_desc(ctx,
			SECURITY_DESCRIPTOR_REVISION_1,
			SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
			owner_sid,
			group_sid,
			NULL,
			new_dacl,
			psize);
	if (!*ppsd) {
		return NT_STATUS_NO_MEMORY;
	}
	return NT_STATUS_OK;
}
Example #15
0
File: ear.c Project: AllardJ/Tomato
int main(int argc, char **argv) {
   int i;
   int result;
   char **names;
   int num_names;
   int num_sids;
   CacServerHandle *hnd = NULL;
   POLICY_HND *lsa_pol  = NULL;
   TALLOC_CTX *mem_ctx  = NULL;

   DOM_SID *sid_buf     = NULL;

   BOOL sim_partial     = False;

   if(argc > 1 && strcmp(argv[1], "-p") == 0)
      sim_partial = True;

   mem_ctx = talloc_init("lsaq");

   hnd = cac_NewServerHandle(False);

   fill_conn_info(hnd);

   get_server_names(mem_ctx, &num_names, &names);

   /*connect to the PDC and open a LSA handle*/
   if(!cac_Connect(hnd, NULL)) {
      fprintf(stderr, "Could not connect to server.\n Error %s.\n", nt_errstr(hnd->status));
      cac_FreeHandle(hnd);
      exit(-1);
   }

   fprintf(stdout, "Connected to server: %s\n", hnd->server);

   struct LsaOpenPolicy lop;
   ZERO_STRUCT(lop);

   lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
   lop.in.security_qos = True;

   if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
      fprintf(stderr, "Could not get lsa policy handle.\n Error: %s\n", nt_errstr(hnd->status));
      cac_FreeHandle(hnd);
      exit(-1);
   }

   fprintf(stdout, "Opened Policy Handle\n");

   /*just to make things neater*/
   lsa_pol = lop.out.pol;

   /*fetch the local sid and domain sid for the pdc*/

   struct LsaFetchSid fsop;
   ZERO_STRUCT(fsop);

   fsop.in.pol = lsa_pol;
   fsop.in.info_class = (CAC_LOCAL_INFO|CAC_DOMAIN_INFO);

   fprintf(stdout, "fetching SID info for %s\n", hnd->server);

   result = cac_LsaFetchSid(hnd, mem_ctx, &fsop);
   if(!result) {
      fprintf(stderr, "Could not get sid for server: %s\n. Error: %s\n", hnd->server, nt_errstr(hnd->status));
      cac_FreeHandle(hnd);
      talloc_destroy(mem_ctx);
      exit(-1);
   }

   if(result == CAC_PARTIAL_SUCCESS) {
      fprintf(stdout, "could not retrieve both domain and local information\n");
   }
   

   fprintf(stdout, "Fetched SID info for %s\n", hnd->server);
   if(fsop.out.local_sid != NULL)
      fprintf(stdout, " domain: %s. Local SID: %s\n", fsop.out.local_sid->domain, sid_string_static(&fsop.out.local_sid->sid));

   if(fsop.out.domain_sid != NULL)
      fprintf(stdout, " domain: %s, Domain SID: %s\n", fsop.out.domain_sid->domain, sid_string_static(&fsop.out.domain_sid->sid));

   fprintf(stdout, "Looking up sids\n");

   
   struct LsaGetSidsFromNames gsop;
   ZERO_STRUCT(gsop);
   
   gsop.in.pol       = lsa_pol;
   gsop.in.num_names = num_names;
   gsop.in.names     = names;

   result = cac_LsaGetSidsFromNames(hnd, mem_ctx, &gsop);

   if(!result) {
      fprintf(stderr, "Could not lookup any sids!\n Error: %s\n", nt_errstr(hnd->status));
      goto done;
   }

   if(result == CAC_PARTIAL_SUCCESS) {
      fprintf(stdout, "Not all names could be looked up.\nThe following names were not found:\n");
      
      for(i = 0; i < (num_names - gsop.out.num_found); i++) {
         fprintf(stdout, " %s\n", gsop.out.unknown[i]);
      }
      
      fprintf(stdout, "\n");
   }

   /*buffer the sids so we can look them up back to names*/
   num_sids = (sim_partial) ? gsop.out.num_found + 2: gsop.out.num_found;
   sid_buf = TALLOC_ARRAY(mem_ctx, DOM_SID, num_sids);

   fprintf(stdout, "%d names were resolved: \n", gsop.out.num_found);


   i = 0;
   while(i < gsop.out.num_found) {
      fprintf(stdout, " Name: %s\n SID: %s\n\n", gsop.out.sids[i].name, sid_string_static(&gsop.out.sids[i].sid));

      sid_buf[i] = gsop.out.sids[i].sid;

      printf("Attempting to open account\n");

      struct LsaOpenAccount loa;
      ZERO_STRUCT(loa);

      loa.in.pol    = lsa_pol;
      loa.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
      loa.in.sid    = &gsop.out.sids[i].sid;

      if(!cac_LsaOpenAccount(hnd, mem_ctx, &loa)) {
         fprintf(stderr, "Could not open account.\n Error: %s\n", nt_errstr(hnd->status));
      }

      printf("\nEnumerating privs:");
      struct LsaEnumAccountRights earop;
      ZERO_STRUCT(earop);

      earop.in.pol = lsa_pol;

      earop.in.sid = &gsop.out.sids[i].sid;

      if(!cac_LsaEnumAccountRights(hnd, mem_ctx, &earop)) {
         fprintf(stderr, "Could not enumerate account rights.\n Error: %s\n", nt_errstr(hnd->status));
      }

      int j;
      printf( "Rights: ");
      for(j = 0; j < earop.out.num_privs; j++) {
         printf("  %s\n", earop.out.priv_names[j]);
      }

      printf("\n");


      i++;
   }

   /*if we want a partial success to occur below, then add the server's SIDs to the end of the array*/
   if(sim_partial) {
      sid_buf[i] = fsop.out.local_sid->sid;
      sid_buf[i+1] = fsop.out.domain_sid->sid;
   }

   fprintf(stdout, "Looking up Names from SIDs\n");

   struct LsaGetNamesFromSids gnop;
   ZERO_STRUCT(gnop);

   gnop.in.pol       = lsa_pol;
   gnop.in.num_sids  = num_sids;
   gnop.in.sids      = sid_buf;

   result = cac_LsaGetNamesFromSids(hnd, mem_ctx, &gnop);

   if(!result) {
      fprintf(stderr, "Could not lookup any names!.\n Error: %s\n", nt_errstr(hnd->status));
      goto done;
   }

   if(result == CAC_PARTIAL_SUCCESS) {
      fprintf(stdout, "\nNot all SIDs could be looked up.\n. The following SIDs were not found:\n");

      for(i = 0; i < (num_sids - gnop.out.num_found); i++) {
         fprintf(stdout, "SID: %s\n", sid_string_static(&gnop.out.unknown[i]));
      }

      fprintf(stdout, "\n");
   }

   fprintf(stdout, "%d SIDs were resolved: \n", gnop.out.num_found);
   for(i = 0; i < gnop.out.num_found; i++) {
      fprintf(stdout, " SID: %s\n Name: %s\n", sid_string_static(&gnop.out.sids[i].sid), gsop.out.sids[i].name);
   }
   
done:

   if(!cac_LsaClosePolicy(hnd, mem_ctx, lsa_pol)) {
      fprintf(stderr, "Could not close LSA policy handle.\n Error: %s\n", nt_errstr(hnd->status));
   }
   else {
      fprintf(stdout, "Closed Policy handle.\n");
   }

   cac_FreeHandle(hnd);
   talloc_destroy(mem_ctx);

   return 0;
}
Example #16
0
static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl,
				   SMB_STRUCT_STAT *psbuf,
				   uint32 security_info,
				   struct security_descriptor **ppdesc)
{
	SEC_ACE *nt_ace_list;
	DOM_SID owner_sid, group_sid;
	SEC_ACL *psa = NULL;
	int good_aces;
	size_t sd_size;
	TALLOC_CTX *mem_ctx = talloc_tos();

	struct afs_ace *afs_ace;

	uid_to_sid(&owner_sid, psbuf->st_uid);
	gid_to_sid(&group_sid, psbuf->st_gid);

	if (afs_acl->num_aces) {
		nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces);

		if (nt_ace_list == NULL)
			return 0;
	} else {
		nt_ace_list = NULL;
	}

	afs_ace = afs_acl->acelist;
	good_aces = 0;

	while (afs_ace != NULL) {
		uint32_t nt_rights;
		uint8 flag = SEC_ACE_FLAG_OBJECT_INHERIT |
			SEC_ACE_FLAG_CONTAINER_INHERIT;

		if (afs_ace->type == SID_NAME_UNKNOWN) {
			DEBUG(10, ("Ignoring unknown name %s\n",
				   afs_ace->name));
			afs_ace = afs_ace->next;
			continue;
		}

		if (S_ISDIR(psbuf->st_mode))
			afs_to_nt_dir_rights(afs_ace->rights, &nt_rights,
					     &flag);
		else
			nt_rights = afs_to_nt_file_rights(afs_ace->rights);

		init_sec_ace(&nt_ace_list[good_aces++], &(afs_ace->sid),
			     SEC_ACE_TYPE_ACCESS_ALLOWED, nt_rights, flag);
		afs_ace = afs_ace->next;
	}

	psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION,
			   good_aces, nt_ace_list);
	if (psa == NULL)
		return 0;

	*ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
				SEC_DESC_SELF_RELATIVE,
				(security_info & OWNER_SECURITY_INFORMATION)
				? &owner_sid : NULL,
				(security_info & GROUP_SECURITY_INFORMATION)
				? &group_sid : NULL,
				NULL, psa, &sd_size);

	return sd_size;
}
Example #17
0
static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
{
	struct locking_data *data;
	int i;

	if (dbuf.dsize < sizeof(struct locking_data)) {
		smb_panic("PANIC: parse_share_modes: buffer too short.\n");
	}

	data = (struct locking_data *)dbuf.dptr;

	lck->delete_on_close = data->u.s.delete_on_close;
	lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
	lck->num_share_modes = data->u.s.num_share_mode_entries;

	DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
		   "initial_delete_on_close: %d, "
		   "num_share_modes: %d\n",
		lck->delete_on_close,
		lck->initial_delete_on_close,
		lck->num_share_modes));

	if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
		DEBUG(0, ("invalid number of share modes: %d\n",
			  lck->num_share_modes));
		smb_panic("PANIC: invalid number of share modes");
	}

	lck->share_modes = NULL;
	
	if (lck->num_share_modes != 0) {

		if (dbuf.dsize < (sizeof(struct locking_data) +
				  (lck->num_share_modes *
				   sizeof(struct share_mode_entry)))) {
			smb_panic("PANIC: parse_share_modes: buffer too short.\n");
		}
				  
		lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
						 lck->num_share_modes *
						 sizeof(struct share_mode_entry));

		if (lck->share_modes == NULL) {
			smb_panic("talloc failed\n");
		}
	}

	/* Get any delete token. */
	if (data->u.s.delete_token_size) {
		char *p = dbuf.dptr + sizeof(*data) +
				(lck->num_share_modes *
				sizeof(struct share_mode_entry));

		if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
				((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
			DEBUG(0, ("parse_share_modes: invalid token size %d\n",
				data->u.s.delete_token_size));
			smb_panic("parse_share_modes: invalid token size\n");
		}

		lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
		if (!lck->delete_token) {
			smb_panic("talloc failed\n");
		}

		/* Copy out the uid and gid. */
		memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
		p += sizeof(uid_t);
		memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
		p += sizeof(gid_t);

		/* Any supplementary groups ? */
		lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
					((data->u.s.delete_token_size -
						(sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;

		if (lck->delete_token->ngroups) {
			/* Make this a talloc child of lck->delete_token. */
			lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
							lck->delete_token->ngroups);
			if (!lck->delete_token) {
				smb_panic("talloc failed\n");
			}

			for (i = 0; i < lck->delete_token->ngroups; i++) {
				memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
				p += sizeof(gid_t);
			}
		}

	} else {
		lck->delete_token = NULL;
	}

	/* Save off the associated service path and filename. */
	lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
					(lck->num_share_modes *
					sizeof(struct share_mode_entry)) +
					data->u.s.delete_token_size );

	lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
					(lck->num_share_modes *
					sizeof(struct share_mode_entry)) +
					data->u.s.delete_token_size +
					strlen(lck->servicepath) + 1 );

	/*
	 * Ensure that each entry has a real process attached.
	 */

	for (i = 0; i < lck->num_share_modes; i++) {
		struct share_mode_entry *entry_p = &lck->share_modes[i];
		DEBUG(10,("parse_share_modes: %s\n",
			  share_mode_str(i, entry_p) ));
		if (!process_exists(entry_p->pid)) {
			DEBUG(10,("parse_share_modes: deleted %s\n",
				  share_mode_str(i, entry_p) ));
			entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
			lck->modified = True;
		}
	}

	return True;
}
Example #18
0
WERROR rpccli_svcctl_enumerate_services( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                      POLICY_HND *hSCM, uint32 type, uint32 state, 
				      uint32 *returned, ENUM_SERVICES_STATUS **service_array  )
{
	SVCCTL_Q_ENUM_SERVICES_STATUS in;
	SVCCTL_R_ENUM_SERVICES_STATUS out;
	prs_struct qbuf, rbuf;
	uint32 resume = 0;
	ENUM_SERVICES_STATUS *services;
	int i;

	ZERO_STRUCT(in);
	ZERO_STRUCT(out);
	
	/* setup the request */
	
	memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
	
	in.type        = type;
	in.state       = state;
	in.resume      = &resume;
	
	/* first time is to get the buffer size */
	in.buffer_size = 0;

	CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, 
	            in, out, 
	            qbuf, rbuf,
	            svcctl_io_q_enum_services_status,
	            svcctl_io_r_enum_services_status, 
	            WERR_GENERAL_FAILURE );

	/* second time with correct buffer size...should be ok */
	
	if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
		in.buffer_size = out.needed;

		CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, 
		            in, out, 
		            qbuf, rbuf,
		            svcctl_io_q_enum_services_status,
		            svcctl_io_r_enum_services_status, 
		            WERR_GENERAL_FAILURE );
	}
	
	if ( !W_ERROR_IS_OK(out.status) ) 
		return out.status;
		
	/* pull out the data */
	if (out.returned) {
		if ( !(services = TALLOC_ARRAY( mem_ctx, ENUM_SERVICES_STATUS, out.returned )) ) 
			return WERR_NOMEM;
	} else {
		services = NULL;
	}
		
	for ( i=0; i<out.returned; i++ ) {
		svcctl_io_enum_services_status( "", &services[i], &out.buffer, 0 );
	}
	
	*service_array = services;
	*returned      = out.returned;
	
	return out.status;
}
Example #19
0
BOOL parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd)
{
	size_t s_size = 0;
	const char *pacl = acl_str;
	int num_aces = 0;
	SEC_ACE *ace_list = NULL;
	SEC_ACL *psa = NULL;
	SEC_DESC *psd = NULL;
	size_t sd_size = 0;
	int i;

	*ppsd = NULL;

	/* If the acl string is blank return "Everyone:R" */
	if (!*acl_str) {
		SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
		if (!default_psd) {
			return False;
		}
		*ppsd = default_psd;
		return True;
	}

	num_aces = 1;

	/* Add the number of ',' characters to get the number of aces. */
	num_aces += count_chars(pacl,',');

	ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces);
	if (!ace_list) {
		return False;
	}

	for (i = 0; i < num_aces; i++) {
		SEC_ACCESS sa;
		uint32 g_access;
		uint32 s_access;
		DOM_SID sid;
		fstring sidstr;
		uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED;

		if (!next_token(&pacl, sidstr, ":", sizeof(sidstr))) {
			DEBUG(0,("parse_usershare_acl: malformed usershare acl looking "
				"for ':' in string '%s'\n", pacl));
			return False;
		}

		if (!string_to_sid(&sid, sidstr)) {
			DEBUG(0,("parse_usershare_acl: failed to convert %s to sid.\n",
				sidstr ));
			return False;
		}

		switch (*pacl) {
			case 'F': /* Full Control, ie. R+W */
			case 'f': /* Full Control, ie. R+W */
				s_access = g_access = GENERIC_ALL_ACCESS;
				break;
			case 'R': /* Read only. */
			case 'r': /* Read only. */
				s_access = g_access = GENERIC_READ_ACCESS;
				break;
			case 'D': /* Deny all to this SID. */
			case 'd': /* Deny all to this SID. */
				type = SEC_ACE_TYPE_ACCESS_DENIED;
				s_access = g_access = GENERIC_ALL_ACCESS;
				break;
			default:
				DEBUG(0,("parse_usershare_acl: unknown acl type at %s.\n",
					pacl ));
				return False;
		}

		pacl++;
		if (*pacl && *pacl != ',') {
			DEBUG(0,("parse_usershare_acl: bad acl string at %s.\n",
				pacl ));
			return False;
		}
		pacl++; /* Go past any ',' */

		se_map_generic(&s_access, &file_generic_mapping);
		init_sec_access(&sa, g_access | s_access );
		init_sec_ace(&ace_list[i], &sid, type, sa, 0);
	}

	if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) {
		psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size);
	}

	if (!psd) {
		DEBUG(0,("parse_usershare_acl: Failed to make SEC_DESC.\n"));
		return False;
	}

	*ppsd = psd;
	return True;
}
Example #20
0
SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, 
				      bool child_container)
{
	SEC_DESC_BUF *sdb;
	SEC_DESC *sd;
	SEC_ACL *new_dacl, *the_acl;
	SEC_ACE *new_ace_list = NULL;
	unsigned int new_ace_list_ndx = 0, i;
	size_t size;

	/* Currently we only process the dacl when creating the child.  The
	   sacl should also be processed but this is left out as sacls are
	   not implemented in Samba at the moment.*/

	the_acl = parent_ctr->dacl;

	if (the_acl->num_aces) {
		if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE, the_acl->num_aces))) 
			return NULL;
	} else {
		new_ace_list = NULL;
	}

	for (i = 0; i < the_acl->num_aces; i++) {
		SEC_ACE *ace = &the_acl->aces[i];
		SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
		uint8 new_flags = 0;
		bool inherit = False;

		/* The OBJECT_INHERIT_ACE flag causes the ACE to be
		   inherited by non-container children objects.  Container
		   children objects will inherit it as an INHERIT_ONLY
		   ACE. */

		if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {

			if (!child_container) {
				new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
			} else {
				new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
			}

			inherit = True;
		}

		/* The CONAINER_INHERIT_ACE flag means all child container
		   objects will inherit and use the ACE. */

		if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
			if (!child_container) {
				inherit = False;
			} else {
				new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
			}
		}

		/* The INHERIT_ONLY_ACE is not used by the se_access_check()
		   function for the parent container, but is inherited by
		   all child objects as a normal ACE. */

		if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
			/* Move along, nothing to see here */
		}

		/* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
		   is inherited by child objects but not grandchildren
		   objects.  We clear the object inherit and container
		   inherit flags in the inherited ACE. */

		if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
			new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
				       SEC_ACE_FLAG_CONTAINER_INHERIT);
		}

		/* Add ACE to ACE list */

		if (!inherit)
			continue;

		init_sec_access(&new_ace->access_mask, ace->access_mask);
		init_sec_ace(new_ace, &ace->trustee, ace->type,
			     new_ace->access_mask, new_flags);

		DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
			  " inherited as %s:%d/0x%02x/0x%08x\n",
			  sid_string_dbg(&ace->trustee),
			  ace->type, ace->flags, ace->access_mask,
			  sid_string_dbg(&ace->trustee),
			  new_ace->type, new_ace->flags,
			  new_ace->access_mask));

		new_ace_list_ndx++;
	}

	/* Create child security descriptor to return */
	
	new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);

	/* Use the existing user and group sids.  I don't think this is
	   correct.  Perhaps the user and group should be passed in as
	   parameters by the caller? */

	sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
			   SEC_DESC_SELF_RELATIVE,
			   parent_ctr->owner_sid,
			   parent_ctr->group_sid,
			   parent_ctr->sacl,
			   new_dacl, &size);

	sdb = make_sec_desc_buf(ctx, size, sd);

	return sdb;
}
Example #21
0
static size_t afs_to_nt_acl(struct afs_acl *afs_acl, 
			    struct files_struct *fsp,
			    uint32 security_info,
			    struct security_descriptor **ppdesc)
{
	SEC_ACE *nt_ace_list;
	DOM_SID owner_sid, group_sid;
	SEC_ACCESS mask;
	SMB_STRUCT_STAT sbuf;
	SEC_ACL *psa = NULL;
	int good_aces;
	size_t sd_size;
	TALLOC_CTX *mem_ctx = main_loop_talloc_get();

	struct afs_ace *afs_ace;

	if (fsp->is_directory || fsp->fh->fd == -1) {
		/* Get the stat struct for the owner info. */
		if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
			return 0;
		}
	} else {
		if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
			return 0;
		}
	}

	uid_to_sid(&owner_sid, sbuf.st_uid);
	gid_to_sid(&group_sid, sbuf.st_gid);

	if (afs_acl->num_aces) {
		nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces);

		if (nt_ace_list == NULL)
			return 0;
	} else {
		nt_ace_list = NULL;
	}

	afs_ace = afs_acl->acelist;
	good_aces = 0;

	while (afs_ace != NULL) {
		uint32 nt_rights;
		uint8 flag = SEC_ACE_FLAG_OBJECT_INHERIT |
			SEC_ACE_FLAG_CONTAINER_INHERIT;

		if (afs_ace->type == SID_NAME_UNKNOWN) {
			DEBUG(10, ("Ignoring unknown name %s\n",
				   afs_ace->name));
			afs_ace = afs_ace->next;
			continue;
		}

		if (fsp->is_directory)
			afs_to_nt_dir_rights(afs_ace->rights, &nt_rights,
					     &flag);
		else
			nt_rights = afs_to_nt_file_rights(afs_ace->rights);

		init_sec_access(&mask, nt_rights);
		init_sec_ace(&nt_ace_list[good_aces++], &(afs_ace->sid),
			     SEC_ACE_TYPE_ACCESS_ALLOWED, mask, flag);
		afs_ace = afs_ace->next;
	}

	psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION,
			   good_aces, nt_ace_list);
	if (psa == NULL)
		return 0;

	
	*ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
				SEC_DESC_SELF_RELATIVE,
				(security_info & OWNER_SECURITY_INFORMATION)
				? &owner_sid : NULL,
				(security_info & GROUP_SECURITY_INFORMATION)
				? &group_sid : NULL,
				NULL, psa, &sd_size);

	return sd_size;
}
Example #22
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;
}