示例#1
0
/*
 * lsarpc_s_GetConnectedUser
 *
 * Return the account name and NetBIOS domain name for the user making
 * the request.  The hostname field should be ignored by the server.
 *
 * Note: MacOS uses this, whether we're a domain member or not.
 */
static int
lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_GetConnectedUser *param = arg;
	smb_netuserinfo_t *user = mxa->pipe->np_user;
	DWORD status = NT_STATUS_SUCCESS;
	int rc1;
	int rc2;

	param->owner = NDR_NEW(mxa, struct mslsa_string_desc);
	param->domain = NDR_NEW(mxa, struct mslsa_DomainName);
	if (param->owner == NULL || param->domain == NULL) {
		status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		param->status = status;
		return (NDR_DRC_OK);
	}

	param->domain->name = NDR_NEW(mxa, struct mslsa_string_desc);
	if (param->domain->name == NULL) {
		status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		param->status = status;
		return (NDR_DRC_OK);
	}

	rc1 = NDR_MSTRING(mxa, user->ui_account,
	    (ndr_mstring_t *)param->owner);
	rc2 = NDR_MSTRING(mxa, user->ui_domain,
	    (ndr_mstring_t *)param->domain->name);

	if (rc1 == -1 || rc2 == -1)
		status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);

	param->status = status;
	return (NDR_DRC_OK);
}
示例#2
0
/*
 * lsarpc_s_PrimaryDomainInfo
 *
 * Service primary domain policy queries.  In domain mode, return the
 * primary domain name and SID.   In workgroup mode, return the local
 * hostname and local domain SID.
 *
 * Note: info is zeroed on entry to ensure the SID and name do not
 * contain spurious values if an error is returned.
 */
static DWORD
lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info,
    ndr_xa_t *mxa)
{
	smb_domain_t di;
	boolean_t found;
	int rc;

	bzero(info, sizeof (struct mslsa_PrimaryDomainInfo));

	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
		found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di);
	else
		found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di);

	if (!found)
		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);

	rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
	info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);

	if ((rc == -1) || (info->sid == NULL))
		return (NT_STATUS_NO_MEMORY);

	return (NT_STATUS_SUCCESS);
}
示例#3
0
/*
 * lsarpc_s_LookupPrivDisplayName
 *
 * This is the server side function for handling requests for account
 * privileges. For now just set the status to not-supported status and
 * return NDR_DRC_OK.
 */
static int
lsarpc_s_LookupPrivDisplayName(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_LookupPrivDisplayName *param = arg;
	smb_privinfo_t *pi;
	int rc;

	if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) {
		bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
		param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
		return (NDR_DRC_OK);
	}

	param->display_name = NDR_NEW(mxa, mslsa_string_t);
	if (param->display_name == NULL) {
		bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		return (NDR_DRC_OK);
	}

	rc = NDR_MSTRING(mxa, pi->display_name,
	    (ndr_mstring_t *)param->display_name);
	if (rc == -1) {
		bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		return (NDR_DRC_OK);
	}

	param->language_ret = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
	param->status = NT_STATUS_SUCCESS;
	return (NDR_DRC_OK);
}
示例#4
0
/*
 * lsarpc_s_LookupPrivName
 *
 * Server side function used to map a locally unique identifier (LUID)
 * to the appropriate privilege name string.
 */
static int
lsarpc_s_LookupPrivName(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_LookupPrivName *param = arg;
	smb_privinfo_t *pi;
	int rc;

	if ((pi = smb_priv_getbyvalue(param->luid.low_part)) == NULL) {
		bzero(param, sizeof (struct mslsa_LookupPrivName));
		param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
		return (NDR_DRC_OK);
	}

	param->name = NDR_NEW(mxa, mslsa_string_t);
	if (param->name == NULL) {
		bzero(param, sizeof (struct mslsa_LookupPrivName));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		return (NDR_DRC_OK);
	}

	rc = NDR_MSTRING(mxa, pi->name, (ndr_mstring_t *)param->name);
	if (rc == -1) {
		bzero(param, sizeof (struct mslsa_LookupPrivName));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		return (NDR_DRC_OK);
	}

	param->status = NT_STATUS_SUCCESS;
	return (NDR_DRC_OK);
}
示例#5
0
/*
 * lsarpc_s_UpdateDomainTable
 *
 * This routine is responsible for maintaining the domain table which
 * will be returned from a SID lookup. Whenever a name is added to the
 * name table, this function should be called with the corresponding
 * domain name. If the domain information is not already in the table,
 * it is added. On success return 0; Otherwise -1 is returned.
 */
static int
lsarpc_s_UpdateDomainTable(ndr_xa_t *mxa,
    smb_account_t *account, struct mslsa_domain_table *domain_table,
    DWORD *domain_idx)
{
	struct mslsa_domain_entry *dentry;
	DWORD n_entry;
	DWORD i;
	int rc;

	if (account->a_type == SidTypeUnknown ||
	    account->a_type == SidTypeInvalid) {
		/*
		 * These types don't need to reference an entry in the
		 * domain table. So return -1.
		 */
		*domain_idx = (DWORD)-1;
		return (0);
	}

	if ((dentry = domain_table->entries) == NULL)
		return (-1);

	if ((n_entry = domain_table->n_entry) >= MLSVC_DOMAIN_MAX)
		return (-1);

	for (i = 0; i < n_entry; ++i) {
		if (smb_sid_cmp((smb_sid_t *)dentry[i].domain_sid,
		    account->a_domsid)) {
			*domain_idx = i;
			return (0);
		}
	}

	if (i == MLSVC_DOMAIN_MAX)
		return (-1);

	rc = NDR_MSTRING(mxa, account->a_domain,
	    (ndr_mstring_t *)&dentry[i].domain_name);
	dentry[i].domain_sid =
	    (struct mslsa_sid *)NDR_SIDDUP(mxa, account->a_domsid);

	if (rc == -1 || dentry[i].domain_sid == NULL)
		return (-1);

	++domain_table->n_entry;
	*domain_idx = i;
	return (0);
}
示例#6
0
/*
 * lsarpc_s_AccountDomainInfo
 *
 * Service account domain policy queries.  We return our local domain
 * information so that the client knows who to query for information
 * on local names and SIDs.  The domain name is the local hostname.
 *
 * Note: info is zeroed on entry to ensure the SID and name do not
 * contain spurious values if an error is returned.
 */
static DWORD
lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info,
    ndr_xa_t *mxa)
{
	smb_domain_t di;
	int rc;

	bzero(info, sizeof (struct mslsa_AccountDomainInfo));

	if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);

	rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
	info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);

	if ((rc == -1) || (info->sid == NULL))
		return (NT_STATUS_NO_MEMORY);

	return (NT_STATUS_SUCCESS);
}
示例#7
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);
}
示例#8
0
/*
 * lsarpc_s_LookupNames
 *
 * This is the service side function for handling name lookup requests.
 * Currently, we only support lookups of a single name. This is also a
 * pass through interface so all we do is act as a proxy between the
 * client and the DC.
 */
static int
lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_LookupNames *param = arg;
	struct mslsa_rid_entry *rids;
	struct mslsa_domain_table *domain_table;
	struct mslsa_domain_entry *domain_entry;
	smb_account_t account;
	uint32_t status;
	char *accname;
	int rc = 0;

	if (param->name_table->n_entry != 1)
		return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);

	rids = NDR_NEW(mxa, struct mslsa_rid_entry);
	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
	domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);

	if (rids == NULL || domain_table == NULL || domain_entry == NULL) {
		bzero(param, sizeof (struct mslsa_LookupNames));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		return (NDR_DRC_OK);
	}

	accname = (char *)param->name_table->names->str;
	status = lsa_lookup_name(accname, SidTypeUnknown, &account);
	if (status != NT_STATUS_SUCCESS) {
		bzero(param, sizeof (struct mslsa_LookupNames));
		param->status = NT_SC_ERROR(status);
		return (NDR_DRC_OK);
	}

	/*
	 * Set up the rid table.
	 */
	rids[0].sid_name_use = account.a_type;
	rids[0].rid = account.a_rid;
	rids[0].domain_index = 0;
	param->translated_sids.n_entry = 1;
	param->translated_sids.rids = rids;

	/*
	 * Set up the domain table.
	 */
	domain_table->entries = domain_entry;
	domain_table->n_entry = 1;
	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;

	rc = NDR_MSTRING(mxa, account.a_domain,
	    (ndr_mstring_t *)&domain_entry->domain_name);
	domain_entry->domain_sid =
	    (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);

	if (rc == -1 || domain_entry->domain_sid == NULL) {
		smb_account_free(&account);
		bzero(param, sizeof (struct mslsa_LookupNames));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
		return (NDR_DRC_OK);
	}

	param->domain_table = domain_table;
	param->mapped_count = 1;
	param->status = NT_STATUS_SUCCESS;

	smb_account_free(&account);
	return (NDR_DRC_OK);
}