18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <linux/ceph/ceph_debug.h>
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <linux/module.h>
58c2ecf20Sopenharmony_ci#include <linux/err.h>
68c2ecf20Sopenharmony_ci#include <linux/slab.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/ceph/types.h>
98c2ecf20Sopenharmony_ci#include <linux/ceph/decode.h>
108c2ecf20Sopenharmony_ci#include <linux/ceph/libceph.h>
118c2ecf20Sopenharmony_ci#include <linux/ceph/messenger.h>
128c2ecf20Sopenharmony_ci#include "auth_none.h"
138c2ecf20Sopenharmony_ci#include "auth_x.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/*
178c2ecf20Sopenharmony_ci * get protocol handler
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_cistatic u32 supported_protocols[] = {
208c2ecf20Sopenharmony_ci	CEPH_AUTH_NONE,
218c2ecf20Sopenharmony_ci	CEPH_AUTH_CEPHX
228c2ecf20Sopenharmony_ci};
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistatic int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	switch (protocol) {
278c2ecf20Sopenharmony_ci	case CEPH_AUTH_NONE:
288c2ecf20Sopenharmony_ci		return ceph_auth_none_init(ac);
298c2ecf20Sopenharmony_ci	case CEPH_AUTH_CEPHX:
308c2ecf20Sopenharmony_ci		return ceph_x_init(ac);
318c2ecf20Sopenharmony_ci	default:
328c2ecf20Sopenharmony_ci		return -ENOENT;
338c2ecf20Sopenharmony_ci	}
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/*
378c2ecf20Sopenharmony_ci * setup, teardown.
388c2ecf20Sopenharmony_ci */
398c2ecf20Sopenharmony_cistruct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	struct ceph_auth_client *ac;
428c2ecf20Sopenharmony_ci	int ret;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	dout("auth_init name '%s'\n", name);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	ret = -ENOMEM;
478c2ecf20Sopenharmony_ci	ac = kzalloc(sizeof(*ac), GFP_NOFS);
488c2ecf20Sopenharmony_ci	if (!ac)
498c2ecf20Sopenharmony_ci		goto out;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	mutex_init(&ac->mutex);
528c2ecf20Sopenharmony_ci	ac->negotiating = true;
538c2ecf20Sopenharmony_ci	if (name)
548c2ecf20Sopenharmony_ci		ac->name = name;
558c2ecf20Sopenharmony_ci	else
568c2ecf20Sopenharmony_ci		ac->name = CEPH_AUTH_NAME_DEFAULT;
578c2ecf20Sopenharmony_ci	dout("auth_init name %s\n", ac->name);
588c2ecf20Sopenharmony_ci	ac->key = key;
598c2ecf20Sopenharmony_ci	return ac;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciout:
628c2ecf20Sopenharmony_ci	return ERR_PTR(ret);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_civoid ceph_auth_destroy(struct ceph_auth_client *ac)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	dout("auth_destroy %p\n", ac);
688c2ecf20Sopenharmony_ci	if (ac->ops)
698c2ecf20Sopenharmony_ci		ac->ops->destroy(ac);
708c2ecf20Sopenharmony_ci	kfree(ac);
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/*
748c2ecf20Sopenharmony_ci * Reset occurs when reconnecting to the monitor.
758c2ecf20Sopenharmony_ci */
768c2ecf20Sopenharmony_civoid ceph_auth_reset(struct ceph_auth_client *ac)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
798c2ecf20Sopenharmony_ci	dout("auth_reset %p\n", ac);
808c2ecf20Sopenharmony_ci	if (ac->ops && !ac->negotiating)
818c2ecf20Sopenharmony_ci		ac->ops->reset(ac);
828c2ecf20Sopenharmony_ci	ac->negotiating = true;
838c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci/*
878c2ecf20Sopenharmony_ci * EntityName, not to be confused with entity_name_t
888c2ecf20Sopenharmony_ci */
898c2ecf20Sopenharmony_ciint ceph_auth_entity_name_encode(const char *name, void **p, void *end)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	int len = strlen(name);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	if (*p + 2*sizeof(u32) + len > end)
948c2ecf20Sopenharmony_ci		return -ERANGE;
958c2ecf20Sopenharmony_ci	ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
968c2ecf20Sopenharmony_ci	ceph_encode_32(p, len);
978c2ecf20Sopenharmony_ci	ceph_encode_copy(p, name, len);
988c2ecf20Sopenharmony_ci	return 0;
998c2ecf20Sopenharmony_ci}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci/*
1028c2ecf20Sopenharmony_ci * Initiate protocol negotiation with monitor.  Include entity name
1038c2ecf20Sopenharmony_ci * and list supported protocols.
1048c2ecf20Sopenharmony_ci */
1058c2ecf20Sopenharmony_ciint ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	struct ceph_mon_request_header *monhdr = buf;
1088c2ecf20Sopenharmony_ci	void *p = monhdr + 1, *end = buf + len, *lenp;
1098c2ecf20Sopenharmony_ci	int i, num;
1108c2ecf20Sopenharmony_ci	int ret;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
1138c2ecf20Sopenharmony_ci	dout("auth_build_hello\n");
1148c2ecf20Sopenharmony_ci	monhdr->have_version = 0;
1158c2ecf20Sopenharmony_ci	monhdr->session_mon = cpu_to_le16(-1);
1168c2ecf20Sopenharmony_ci	monhdr->session_mon_tid = 0;
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	ceph_encode_32(&p, CEPH_AUTH_UNKNOWN);  /* no protocol, yet */
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	lenp = p;
1218c2ecf20Sopenharmony_ci	p += sizeof(u32);
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
1248c2ecf20Sopenharmony_ci	ceph_encode_8(&p, 1);
1258c2ecf20Sopenharmony_ci	num = ARRAY_SIZE(supported_protocols);
1268c2ecf20Sopenharmony_ci	ceph_encode_32(&p, num);
1278c2ecf20Sopenharmony_ci	ceph_decode_need(&p, end, num * sizeof(u32), bad);
1288c2ecf20Sopenharmony_ci	for (i = 0; i < num; i++)
1298c2ecf20Sopenharmony_ci		ceph_encode_32(&p, supported_protocols[i]);
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	ret = ceph_auth_entity_name_encode(ac->name, &p, end);
1328c2ecf20Sopenharmony_ci	if (ret < 0)
1338c2ecf20Sopenharmony_ci		goto out;
1348c2ecf20Sopenharmony_ci	ceph_decode_need(&p, end, sizeof(u64), bad);
1358c2ecf20Sopenharmony_ci	ceph_encode_64(&p, ac->global_id);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	ceph_encode_32(&lenp, p - lenp - sizeof(u32));
1388c2ecf20Sopenharmony_ci	ret = p - buf;
1398c2ecf20Sopenharmony_ciout:
1408c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
1418c2ecf20Sopenharmony_ci	return ret;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cibad:
1448c2ecf20Sopenharmony_ci	ret = -ERANGE;
1458c2ecf20Sopenharmony_ci	goto out;
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic int ceph_build_auth_request(struct ceph_auth_client *ac,
1498c2ecf20Sopenharmony_ci				   void *msg_buf, size_t msg_len)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	struct ceph_mon_request_header *monhdr = msg_buf;
1528c2ecf20Sopenharmony_ci	void *p = monhdr + 1;
1538c2ecf20Sopenharmony_ci	void *end = msg_buf + msg_len;
1548c2ecf20Sopenharmony_ci	int ret;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	monhdr->have_version = 0;
1578c2ecf20Sopenharmony_ci	monhdr->session_mon = cpu_to_le16(-1);
1588c2ecf20Sopenharmony_ci	monhdr->session_mon_tid = 0;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	ceph_encode_32(&p, ac->protocol);
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	ret = ac->ops->build_request(ac, p + sizeof(u32), end);
1638c2ecf20Sopenharmony_ci	if (ret < 0) {
1648c2ecf20Sopenharmony_ci		pr_err("error %d building auth method %s request\n", ret,
1658c2ecf20Sopenharmony_ci		       ac->ops->name);
1668c2ecf20Sopenharmony_ci		goto out;
1678c2ecf20Sopenharmony_ci	}
1688c2ecf20Sopenharmony_ci	dout(" built request %d bytes\n", ret);
1698c2ecf20Sopenharmony_ci	ceph_encode_32(&p, ret);
1708c2ecf20Sopenharmony_ci	ret = p + ret - msg_buf;
1718c2ecf20Sopenharmony_ciout:
1728c2ecf20Sopenharmony_ci	return ret;
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci/*
1768c2ecf20Sopenharmony_ci * Handle auth message from monitor.
1778c2ecf20Sopenharmony_ci */
1788c2ecf20Sopenharmony_ciint ceph_handle_auth_reply(struct ceph_auth_client *ac,
1798c2ecf20Sopenharmony_ci			   void *buf, size_t len,
1808c2ecf20Sopenharmony_ci			   void *reply_buf, size_t reply_len)
1818c2ecf20Sopenharmony_ci{
1828c2ecf20Sopenharmony_ci	void *p = buf;
1838c2ecf20Sopenharmony_ci	void *end = buf + len;
1848c2ecf20Sopenharmony_ci	int protocol;
1858c2ecf20Sopenharmony_ci	s32 result;
1868c2ecf20Sopenharmony_ci	u64 global_id;
1878c2ecf20Sopenharmony_ci	void *payload, *payload_end;
1888c2ecf20Sopenharmony_ci	int payload_len;
1898c2ecf20Sopenharmony_ci	char *result_msg;
1908c2ecf20Sopenharmony_ci	int result_msg_len;
1918c2ecf20Sopenharmony_ci	int ret = -EINVAL;
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
1948c2ecf20Sopenharmony_ci	dout("handle_auth_reply %p %p\n", p, end);
1958c2ecf20Sopenharmony_ci	ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
1968c2ecf20Sopenharmony_ci	protocol = ceph_decode_32(&p);
1978c2ecf20Sopenharmony_ci	result = ceph_decode_32(&p);
1988c2ecf20Sopenharmony_ci	global_id = ceph_decode_64(&p);
1998c2ecf20Sopenharmony_ci	payload_len = ceph_decode_32(&p);
2008c2ecf20Sopenharmony_ci	payload = p;
2018c2ecf20Sopenharmony_ci	p += payload_len;
2028c2ecf20Sopenharmony_ci	ceph_decode_need(&p, end, sizeof(u32), bad);
2038c2ecf20Sopenharmony_ci	result_msg_len = ceph_decode_32(&p);
2048c2ecf20Sopenharmony_ci	result_msg = p;
2058c2ecf20Sopenharmony_ci	p += result_msg_len;
2068c2ecf20Sopenharmony_ci	if (p != end)
2078c2ecf20Sopenharmony_ci		goto bad;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len,
2108c2ecf20Sopenharmony_ci	     result_msg, global_id, payload_len);
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	payload_end = payload + payload_len;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	if (global_id && ac->global_id != global_id) {
2158c2ecf20Sopenharmony_ci		dout(" set global_id %lld -> %lld\n", ac->global_id, global_id);
2168c2ecf20Sopenharmony_ci		ac->global_id = global_id;
2178c2ecf20Sopenharmony_ci	}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	if (ac->negotiating) {
2208c2ecf20Sopenharmony_ci		/* server does not support our protocols? */
2218c2ecf20Sopenharmony_ci		if (!protocol && result < 0) {
2228c2ecf20Sopenharmony_ci			ret = result;
2238c2ecf20Sopenharmony_ci			goto out;
2248c2ecf20Sopenharmony_ci		}
2258c2ecf20Sopenharmony_ci		/* set up (new) protocol handler? */
2268c2ecf20Sopenharmony_ci		if (ac->protocol && ac->protocol != protocol) {
2278c2ecf20Sopenharmony_ci			ac->ops->destroy(ac);
2288c2ecf20Sopenharmony_ci			ac->protocol = 0;
2298c2ecf20Sopenharmony_ci			ac->ops = NULL;
2308c2ecf20Sopenharmony_ci		}
2318c2ecf20Sopenharmony_ci		if (ac->protocol != protocol) {
2328c2ecf20Sopenharmony_ci			ret = ceph_auth_init_protocol(ac, protocol);
2338c2ecf20Sopenharmony_ci			if (ret) {
2348c2ecf20Sopenharmony_ci				pr_err("error %d on auth protocol %d init\n",
2358c2ecf20Sopenharmony_ci				       ret, protocol);
2368c2ecf20Sopenharmony_ci				goto out;
2378c2ecf20Sopenharmony_ci			}
2388c2ecf20Sopenharmony_ci		}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci		ac->negotiating = false;
2418c2ecf20Sopenharmony_ci	}
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci	ret = ac->ops->handle_reply(ac, result, payload, payload_end);
2448c2ecf20Sopenharmony_ci	if (ret == -EAGAIN) {
2458c2ecf20Sopenharmony_ci		ret = ceph_build_auth_request(ac, reply_buf, reply_len);
2468c2ecf20Sopenharmony_ci	} else if (ret) {
2478c2ecf20Sopenharmony_ci		pr_err("auth method '%s' error %d\n", ac->ops->name, ret);
2488c2ecf20Sopenharmony_ci	}
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ciout:
2518c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
2528c2ecf20Sopenharmony_ci	return ret;
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_cibad:
2558c2ecf20Sopenharmony_ci	pr_err("failed to decode auth msg\n");
2568c2ecf20Sopenharmony_ci	ret = -EINVAL;
2578c2ecf20Sopenharmony_ci	goto out;
2588c2ecf20Sopenharmony_ci}
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ciint ceph_build_auth(struct ceph_auth_client *ac,
2618c2ecf20Sopenharmony_ci		    void *msg_buf, size_t msg_len)
2628c2ecf20Sopenharmony_ci{
2638c2ecf20Sopenharmony_ci	int ret = 0;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
2668c2ecf20Sopenharmony_ci	if (ac->ops->should_authenticate(ac))
2678c2ecf20Sopenharmony_ci		ret = ceph_build_auth_request(ac, msg_buf, msg_len);
2688c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
2698c2ecf20Sopenharmony_ci	return ret;
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ciint ceph_auth_is_authenticated(struct ceph_auth_client *ac)
2738c2ecf20Sopenharmony_ci{
2748c2ecf20Sopenharmony_ci	int ret = 0;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
2778c2ecf20Sopenharmony_ci	if (ac->ops)
2788c2ecf20Sopenharmony_ci		ret = ac->ops->is_authenticated(ac);
2798c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
2808c2ecf20Sopenharmony_ci	return ret;
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_is_authenticated);
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ciint ceph_auth_create_authorizer(struct ceph_auth_client *ac,
2858c2ecf20Sopenharmony_ci				int peer_type,
2868c2ecf20Sopenharmony_ci				struct ceph_auth_handshake *auth)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	int ret = 0;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
2918c2ecf20Sopenharmony_ci	if (ac->ops && ac->ops->create_authorizer)
2928c2ecf20Sopenharmony_ci		ret = ac->ops->create_authorizer(ac, peer_type, auth);
2938c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
2948c2ecf20Sopenharmony_ci	return ret;
2958c2ecf20Sopenharmony_ci}
2968c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_create_authorizer);
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_civoid ceph_auth_destroy_authorizer(struct ceph_authorizer *a)
2998c2ecf20Sopenharmony_ci{
3008c2ecf20Sopenharmony_ci	a->destroy(a);
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_destroy_authorizer);
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ciint ceph_auth_update_authorizer(struct ceph_auth_client *ac,
3058c2ecf20Sopenharmony_ci				int peer_type,
3068c2ecf20Sopenharmony_ci				struct ceph_auth_handshake *a)
3078c2ecf20Sopenharmony_ci{
3088c2ecf20Sopenharmony_ci	int ret = 0;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
3118c2ecf20Sopenharmony_ci	if (ac->ops && ac->ops->update_authorizer)
3128c2ecf20Sopenharmony_ci		ret = ac->ops->update_authorizer(ac, peer_type, a);
3138c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
3148c2ecf20Sopenharmony_ci	return ret;
3158c2ecf20Sopenharmony_ci}
3168c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_update_authorizer);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ciint ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac,
3198c2ecf20Sopenharmony_ci				       struct ceph_authorizer *a,
3208c2ecf20Sopenharmony_ci				       void *challenge_buf,
3218c2ecf20Sopenharmony_ci				       int challenge_buf_len)
3228c2ecf20Sopenharmony_ci{
3238c2ecf20Sopenharmony_ci	int ret = 0;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
3268c2ecf20Sopenharmony_ci	if (ac->ops && ac->ops->add_authorizer_challenge)
3278c2ecf20Sopenharmony_ci		ret = ac->ops->add_authorizer_challenge(ac, a, challenge_buf,
3288c2ecf20Sopenharmony_ci							challenge_buf_len);
3298c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
3308c2ecf20Sopenharmony_ci	return ret;
3318c2ecf20Sopenharmony_ci}
3328c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ciint ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
3358c2ecf20Sopenharmony_ci				      struct ceph_authorizer *a)
3368c2ecf20Sopenharmony_ci{
3378c2ecf20Sopenharmony_ci	int ret = 0;
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
3408c2ecf20Sopenharmony_ci	if (ac->ops && ac->ops->verify_authorizer_reply)
3418c2ecf20Sopenharmony_ci		ret = ac->ops->verify_authorizer_reply(ac, a);
3428c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
3438c2ecf20Sopenharmony_ci	return ret;
3448c2ecf20Sopenharmony_ci}
3458c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_civoid ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	mutex_lock(&ac->mutex);
3508c2ecf20Sopenharmony_ci	if (ac->ops && ac->ops->invalidate_authorizer)
3518c2ecf20Sopenharmony_ci		ac->ops->invalidate_authorizer(ac, peer_type);
3528c2ecf20Sopenharmony_ci	mutex_unlock(&ac->mutex);
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
355