Example #1
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);
}
Example #2
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);
}
Example #3
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);
}
Example #4
0
/*
 * lsarpc_s_QueryInfoPolicy
 *
 * This is the server side function for handling LSA information policy
 * queries. Currently, we only support primary domain and account
 * domain queries. This is just a front end to switch on the request
 * and hand it off to the appropriate function to actually deal with
 * obtaining and building the response.
 */
static int
lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_QueryInfoPolicy *param = arg;
	union mslsa_PolicyInfoResUnion *ru = &param->ru;
	int security_mode;
	DWORD status;

	param->switch_value = param->info_class;

	switch (param->info_class) {
	case MSLSA_POLICY_AUDIT_EVENTS_INFO:
		ru->audit_events.enabled = 0;
		ru->audit_events.count = 1;
		ru->audit_events.settings
		    = NDR_MALLOC(mxa, sizeof (DWORD));
		bzero(ru->audit_events.settings, sizeof (DWORD));
		status = NT_STATUS_SUCCESS;
		break;

	case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
		status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa);
		break;

	case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
		status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa);
		break;

	case MSLSA_POLICY_SERVER_ROLE_INFO:
		security_mode = smb_config_get_secmode();

		if (security_mode == SMB_SECMODE_DOMAIN)
			ru->server_role.role = LSA_ROLE_MEMBER_SERVER;
		else
			ru->server_role.role = LSA_ROLE_STANDALONE_SERVER;

		ru->server_role.pad = 0;
		status = NT_STATUS_SUCCESS;
		break;

	default:
		bzero(param, sizeof (struct mslsa_QueryInfoPolicy));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS);
		return (NDR_DRC_OK);
	}

	if (status != NT_STATUS_SUCCESS)
		param->status = NT_SC_ERROR(status);
	else
		param->status = NT_STATUS_SUCCESS;
	param->address = (DWORD)(uintptr_t)ru;

	return (NDR_DRC_OK);
}
Example #5
0
static int
lsarpc_s_OpenSecret(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_OpenSecret *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	ndr_handle_t *hd;

	hd = ndr_hdlookup(mxa, id);
	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
		bzero(param, sizeof (struct mslsa_OpenAccount));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
		return (NDR_DRC_OK);
	}

	bzero(&param->secret_handle, sizeof (mslsa_handle_t));
	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
	return (NDR_DRC_OK);
}
Example #6
0
/*ARGSUSED*/
static int
lsarpc_s_EnumPrivsAccount(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_EnumPrivsAccount *param = arg;

	bzero(param, sizeof (struct mslsa_EnumPrivsAccount));
	param->status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
	return (NDR_DRC_OK);
}
Example #7
0
/*ARGSUSED*/
static int
lsarpc_s_LookupNames4(void *arg, ndr_xa_t *mxa)
{
	struct lsar_LookupNames4 *param = arg;

	bzero(param, sizeof (struct lsar_LookupNames4));
	param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE);
	return (NDR_DRC_OK);
}
Example #8
0
/*
 * lsarpc_s_EnumTrustedDomainsEx
 *
 * This is the server side function for handling requests to enumerate
 * the list of trusted domains: currently held in the NT domain database.
 * This call requires an OpenPolicy2 handle. The enum_context is used to
 * support multiple enumeration calls to obtain the complete list.
 * It should be set to 0 on the first call and passed unchanged on
 * subsequent calls until there are no more accounts - the server will
 * return STATUS_NO_MORE_ENTRIES.
 *
 * For now just set the status to access-denied. Note that we still have
 * to provide a valid address for enum_buf because it's a reference and
 * the marshalling rules require that references must not be null.
 */
static int
lsarpc_s_EnumTrustedDomainsEx(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_EnumTrustedDomainEx *param = arg;
	struct mslsa_EnumTrustedDomainBufEx *enum_buf;

	bzero(param, sizeof (struct mslsa_EnumTrustedDomainEx));

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

	bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBufEx));
	param->enum_buf = enum_buf;
	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
	return (NDR_DRC_OK);
}
Example #9
0
/*
 * lsarpc_s_EnumAccounts
 *
 * Enumerate the list of local accounts SIDs. The client should supply
 * a valid OpenPolicy2 handle. The enum_context is used to support
 * multiple enumeration calls to obtain the complete list of SIDs.
 * It should be set to 0 on the first call and passed unchanged on
 * subsequent calls until there are no more accounts - the server will
 * return STATUS_NO_MORE_ENTRIES.
 *
 * For now just set the status to access-denied. Note that we still have
 * to provide a valid address for enum_buf because it's a reference and
 * the marshalling rules require that references must not be null.
 * The enum_context is used to support multiple
 */
static int
lsarpc_s_EnumAccounts(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_EnumerateAccounts *param = arg;
	struct mslsa_EnumAccountBuf *enum_buf;

	bzero(param, sizeof (struct mslsa_EnumerateAccounts));

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

	bzero(enum_buf, sizeof (struct mslsa_EnumAccountBuf));
	param->enum_buf = enum_buf;
	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
	return (NDR_DRC_OK);
}
Example #10
0
/*ARGSUSED*/
static int
lsarpc_s_QuerySecurityObject(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_QuerySecurityObject *param = arg;

	bzero(param, sizeof (struct mslsa_QuerySecurityObject));
	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);

	return (NDR_DRC_OK);
}
Example #11
0
/*
 * lsarpc_s_OpenAccount
 *
 * This is a request to open an account handle.
 */
static int
lsarpc_s_OpenAccount(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_OpenAccount *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	ndr_handle_t *hd;

	hd = ndr_hdlookup(mxa, id);
	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
		bzero(param, sizeof (struct mslsa_OpenAccount));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
		return (NDR_DRC_OK);
	}

	if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) {
		bcopy(id, &param->account_handle, sizeof (mslsa_handle_t));
		param->status = NT_STATUS_SUCCESS;
	} else {
		bzero(&param->account_handle, sizeof (mslsa_handle_t));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
	}

	return (NDR_DRC_OK);
}
Example #12
0
/*
 * lsarpc_s_OpenDomainHandle opnum=0x06
 *
 * This is a request to open the LSA (OpenPolicy and OpenPolicy2).
 * The client is looking for an LSA domain handle.
 */
static int
lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_OpenPolicy2 *param = arg;
	ndr_hdid_t *id;

	if ((id = ndr_hdalloc(mxa, &lsarpc_key_domain)) != NULL) {
		bcopy(id, &param->domain_handle, sizeof (mslsa_handle_t));
		param->status = NT_STATUS_SUCCESS;
	} else {
		bzero(&param->domain_handle, sizeof (mslsa_handle_t));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
	}

	return (NDR_DRC_OK);
}
Example #13
0
/*ARGSUSED*/
static int
lsarpc_s_LookupPrivValue(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_LookupPrivValue *param = arg;
	smb_privinfo_t *pi;

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

	param->luid.low_part = pi->id;
	param->luid.high_part = 0;
	param->status = NT_STATUS_SUCCESS;
	return (NDR_DRC_OK);
}
Example #14
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);
}