示例#1
0
static void
lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf,
    smb_trusted_domains_t *list)
{
	char	sidstr[SMB_SID_STRSZ];
	int	i;

	if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0)
		return;

	list->td_num = 0;
	list->td_domains = calloc(enum_buf->entries_read,
	    sizeof (smb_domain_t));

	if (list->td_domains == NULL)
		return;

	list->td_num = enum_buf->entries_read;
	for (i = 0; i < list->td_num; i++) {
		smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr);
		smb_domain_set_trust_info(
		    sidstr, (char *)enum_buf->info[i].name.str,
		    "", 0, 0, 0, &list->td_domains[i]);
	}
}
示例#2
0
/*
 * Lookup a sid and obtain the domain sid and account name.
 * This is a wrapper for the various lookup sid RPCs.
 */
uint32_t
lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid,
    smb_account_t *account)
{
	char		sidbuf[SMB_SID_STRSZ];
	uint32_t	status;

	if (lsa_handle == NULL || sid == NULL || account == NULL)
		return (NT_STATUS_INVALID_PARAMETER);

	bzero(account, sizeof (smb_account_t));
	bzero(sidbuf, SMB_SID_STRSZ);
	smb_sid_tostr(sid, sidbuf);
	smb_tracef("%s", sidbuf);

	if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
		status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid,
		    account);
	else
		status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid,
		    account);

	if (status == NT_STATUS_SUCCESS) {
		if (!smb_account_validate(account)) {
			smb_account_free(account);
			status = NT_STATUS_NO_MEMORY;
		} else {
			smb_account_trace(account);
		}
	}

	return (status);
}
示例#3
0
/*
 * smbadm_group_dump_members
 *
 * Dump group members details.
 */
static void
smbadm_group_dump_members(smb_gsid_t *members, int num)
{
	char		sidstr[SMB_SID_STRSZ];
	lsa_account_t	acct;
	int		i;

	if (num == 0) {
		(void) printf(gettext("\tNo members\n"));
		return;
	}

	(void) printf(gettext("\tMembers:\n"));
	for (i = 0; i < num; i++) {
		smb_sid_tostr(members[i].gs_sid, sidstr);

		if (smb_lookup_sid(sidstr, &acct) == 0) {
			if (acct.a_status == NT_STATUS_SUCCESS)
				smbadm_group_show_name(acct.a_domain,
				    acct.a_name);
			else
				(void) printf(gettext("\t\t%s [%s]\n"),
				    sidstr, xlate_nt_status(acct.a_status));
		} else {
			(void) printf(gettext("\t\t%s\n"), sidstr);
		}
	}
}
示例#4
0
static void
smb_account_trace(const smb_account_t *info)
{
	char	sidbuf[SMB_SID_STRSZ];

	bzero(sidbuf, SMB_SID_STRSZ);
	smb_sid_tostr(info->a_sid, sidbuf);

	smb_tracef("%s %s %s %lu %s", info->a_domain, info->a_name,
	    sidbuf, info->a_rid, smb_sid_type2str(info->a_type));
}
示例#5
0
/*
 * smbadm_group_dump
 *
 * Dump group details.
 */
static void
smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs)
{
	char sidstr[SMB_SID_STRSZ];

	(void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt);

	smb_sid_tostr(grp->sg_id.gs_sid, sidstr);
	(void) printf(gettext("\tSID: %s\n"), sidstr);

	if (show_privs)
		smbadm_group_dump_privs(grp->sg_privs);

	if (show_mem)
		smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers);
}
示例#6
0
/*
 * Initialize the ksid based on the given smb_id_t.
 */
static void
smb_cred_set_sid(smb_id_t *id, ksid_t *ksid)
{
	char sidstr[SMB_SID_STRSZ];
	int rc;

	ASSERT(id);
	ASSERT(id->i_sid);

	ksid->ks_id = id->i_id;
	smb_sid_tostr(id->i_sid, sidstr);
	rc = smb_sid_splitstr(sidstr, &ksid->ks_rid);
	ASSERT(rc == 0);

	ksid->ks_attr = id->i_attrs;
	ksid->ks_domain = ksid_lookupdomain(sidstr);
}
示例#7
0
/*
 * lsar_query_info_policy
 *
 * The general purpose of this function is to allow various pieces of
 * information to be queried on the domain controller. The only
 * information queries supported are MSLSA_POLICY_PRIMARY_DOMAIN_INFO
 * and MSLSA_POLICY_ACCOUNT_DOMAIN_INFO.
 *
 * On success, the return code will be 0 and the user_info structure
 * will be set up. The sid_name_use field will be set to SidTypeDomain
 * indicating that the domain name and domain sid fields are vaild. If
 * the infoClass returned from the server is not one of the supported
 * values, the sid_name_use willbe set to SidTypeUnknown. If the RPC
 * fails, a negative error code will be returned, in which case the
 * user_info will not have been updated.
 */
DWORD
lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
    smb_domain_t *info)
{
	struct mslsa_QueryInfoPolicy	arg;
	struct mslsa_PrimaryDomainInfo	*pd_info;
	struct mslsa_AccountDomainInfo	*ad_info;
	struct mslsa_DnsDomainInfo	*dns_info;
	char	guid_str[UUID_PRINTABLE_STRING_LENGTH];
	char	sidstr[SMB_SID_STRSZ];
	int	opnum;
	DWORD	status;

	if (lsa_handle == NULL || info == NULL)
		return (NT_STATUS_INVALID_PARAMETER);

	opnum = LSARPC_OPNUM_QueryInfoPolicy;

	bzero(info, sizeof (smb_domain_t));
	bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy));
	(void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));

	arg.info_class = infoClass;

	if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else if (arg.status != 0) {
		ndr_rpc_status(lsa_handle, opnum, arg.status);
		status = NT_SC_VALUE(arg.status);
	} else {

		switch (infoClass) {
		case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
			pd_info = &arg.ru.pd_info;

			smb_sid_tostr((smb_sid_t *)pd_info->sid, sidstr);
			info->di_type = SMB_DOMAIN_PRIMARY;
			smb_domain_set_basic_info(sidstr,
			    (char *)pd_info->name.str, "", info);

			status = NT_STATUS_SUCCESS;
			break;

		case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
			ad_info = &arg.ru.ad_info;

			smb_sid_tostr((smb_sid_t *)ad_info->sid, sidstr);
			info->di_type = SMB_DOMAIN_ACCOUNT;
			smb_domain_set_basic_info(sidstr,
			    (char *)ad_info->name.str, "", info);

			status = NT_STATUS_SUCCESS;
			break;

		case MSLSA_POLICY_DNS_DOMAIN_INFO:
			dns_info = &arg.ru.dns_info;
			ndr_uuid_unparse((ndr_uuid_t *)&dns_info->guid,
			    guid_str);
			smb_sid_tostr((smb_sid_t *)dns_info->sid, sidstr);

			info->di_type = SMB_DOMAIN_PRIMARY;
			smb_domain_set_dns_info(sidstr,
			    (char *)dns_info->nb_domain.str,
			    (char *)dns_info->dns_domain.str,
			    (char *)dns_info->forest.str,
			    guid_str, info);
			status = NT_STATUS_SUCCESS;
			break;

		default:
			status = NT_STATUS_INVALID_INFO_CLASS;
			break;
		}
	}

	ndr_rpc_release(lsa_handle);
	return (status);
}
示例#8
0
/*
 * smb_acl_to_zfs
 *
 * Converts given Windows ACL to a ZFS ACL.
 *
 * fs_acl will contain a pointer to the created ZFS ACL.
 * The allocated memory should be freed by calling
 * smb_fsacl_free().
 *
 * Since the output parameter, fs_acl, is allocated in this
 * function, the caller has to make sure *fs_acl is NULL which
 * means it's not pointing to any memory.
 */
uint32_t
smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
{
	smb_ace_t *ace;
	acl_t *zacl;
	ace_t *zace;
	smb_idmap_batch_t sib;
	smb_idmap_t *sim;
	idmap_stat idm_stat;
	char *sidstr;
	int i;

	ASSERT(fs_acl);
	ASSERT(*fs_acl == NULL);

	if (acl && !smb_acl_isvalid(acl, which_acl))
		return (NT_STATUS_INVALID_ACL);

	if ((acl == NULL) || (acl->sl_acecnt == 0)) {
		if (which_acl == SMB_DACL_SECINFO) {
			*fs_acl = smb_fsacl_null_empty(acl == NULL);
		}

		return (NT_STATUS_SUCCESS);
	}

	idm_stat = smb_idmap_batch_create(&sib, acl->sl_acecnt,
	    SMB_IDMAP_SID2ID);
	if (idm_stat != IDMAP_SUCCESS)
		return (NT_STATUS_INTERNAL_ERROR);

	sidstr = kmem_alloc(SMB_SID_STRSZ, KM_SLEEP);
	zacl = smb_fsacl_alloc(acl->sl_acecnt, flags);

	zace = zacl->acl_aclp;
	ace = acl->sl_aces;
	sim = sib.sib_maps;

	for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) {
		zace->a_type = ace->se_hdr.se_type & ACE_ALL_TYPES;
		zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask);
		zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags);
		zace->a_who = (uid_t)-1;

		smb_sid_tostr(ace->se_sid, sidstr);

		if (!smb_ace_wellknown_update(sidstr, zace)) {
			sim->sim_id = &zace->a_who;
			idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim,
			    ace->se_sid, SMB_IDMAP_UNKNOWN);

			if (idm_stat != IDMAP_SUCCESS) {
				kmem_free(sidstr, SMB_SID_STRSZ);
				smb_fsacl_free(zacl);
				smb_idmap_batch_destroy(&sib);
				return (NT_STATUS_INTERNAL_ERROR);
			}
		}
	}

	kmem_free(sidstr, SMB_SID_STRSZ);

	idm_stat = smb_idmap_batch_getmappings(&sib);
	if (idm_stat != IDMAP_SUCCESS) {
		smb_fsacl_free(zacl);
		smb_idmap_batch_destroy(&sib);
		return (NT_STATUS_NONE_MAPPED);
	}

	/*
	 * Set the ACEs group flag based on the type of ID returned.
	 */
	zace = zacl->acl_aclp;
	ace = acl->sl_aces;
	sim = sib.sib_maps;
	for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) {
		if (zace->a_who == (uid_t)-1)
			continue;

		if (sim->sim_idtype == SMB_IDMAP_GROUP)
			zace->a_flags |= ACE_IDENTIFIER_GROUP;
	}

	smb_idmap_batch_destroy(&sib);

	*fs_acl = zacl;
	return (NT_STATUS_SUCCESS);
}
示例#9
0
/*
 * lsarpc_s_LookupSids2
 *
 * Other than the use of lsar_lookup_sids2 and lsar_name_entry2, this
 * is identical to lsarpc_s_LookupSids.
 *
 * Ignore lookup_level, it is reserved and should be zero.
 */
static int
lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa)
{
	struct lsar_lookup_sids2 *param = arg;
	struct lsar_name_entry2 *names;
	struct lsar_name_entry2 *name;
	struct mslsa_domain_table *domain_table;
	struct mslsa_domain_entry *domain_entry;
	smb_account_t account;
	smb_sid_t *sid;
	DWORD n_entry;
	DWORD n_mapped;
	char sidstr[SMB_SID_STRSZ];
	int result;
	int i;

	bzero(&account, sizeof (smb_account_t));
	n_mapped = 0;
	n_entry = param->lup_sid_table.n_entry;

	names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry);
	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
	domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
	    MLSVC_DOMAIN_MAX);

	if (names == NULL || domain_table == NULL || domain_entry == NULL)
		goto lookup_sid_failed;

	domain_table->entries = domain_entry;
	domain_table->n_entry = 0;
	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;

	name = names;
	for (i = 0; i < n_entry; ++i, name++) {
		bzero(name, sizeof (struct lsar_name_entry2));
		sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;

		result = lsa_lookup_sid(sid, &account);
		if ((result != NT_STATUS_SUCCESS) ||
		    (account.a_name == NULL) || (*account.a_name == '\0')) {
			account.a_type = SidTypeUnknown;
			smb_sid_tostr(sid, sidstr);

			if (NDR_MSTRING(mxa, sidstr,
			    (ndr_mstring_t *)&name->name) == -1)
				goto lookup_sid_failed;

		} else {
			if (NDR_MSTRING(mxa, account.a_name,
			    (ndr_mstring_t *)&name->name) == -1)
				goto lookup_sid_failed;

			++n_mapped;
		}

		name->sid_name_use = account.a_type;

		result = lsarpc_s_UpdateDomainTable(mxa, &account,
		    domain_table, &name->domain_ix);
		if (result == -1)
			goto lookup_sid_failed;

		smb_account_free(&account);
	}

	param->domain_table = domain_table;
	param->name_table.n_entry = n_entry;
	param->name_table.entries = names;
	param->mapped_count = n_mapped;

	if (n_mapped == n_entry)
		param->status = NT_STATUS_SUCCESS;
	else if (n_mapped == 0)
		param->status = NT_STATUS_NONE_MAPPED;
	else
		param->status = NT_STATUS_SOME_NOT_MAPPED;

	return (NDR_DRC_OK);

lookup_sid_failed:
	smb_account_free(&account);
	bzero(param, sizeof (struct lsar_lookup_sids2));
	return (NDR_DRC_FAULT_OUT_OF_MEMORY);
}