auth.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/ceph/ceph_debug.h>
  3. #include <linux/module.h>
  4. #include <linux/err.h>
  5. #include <linux/slab.h>
  6. #include <linux/ceph/types.h>
  7. #include <linux/ceph/decode.h>
  8. #include <linux/ceph/libceph.h>
  9. #include <linux/ceph/messenger.h>
  10. #include "auth_none.h"
  11. #include "auth_x.h"
  12. /*
  13. * get protocol handler
  14. */
  15. static u32 supported_protocols[] = {
  16. CEPH_AUTH_NONE,
  17. CEPH_AUTH_CEPHX
  18. };
  19. static int init_protocol(struct ceph_auth_client *ac, int proto)
  20. {
  21. dout("%s proto %d\n", __func__, proto);
  22. switch (proto) {
  23. case CEPH_AUTH_NONE:
  24. return ceph_auth_none_init(ac);
  25. case CEPH_AUTH_CEPHX:
  26. return ceph_x_init(ac);
  27. default:
  28. pr_err("bad auth protocol %d\n", proto);
  29. return -EINVAL;
  30. }
  31. }
  32. void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id)
  33. {
  34. dout("%s global_id %llu\n", __func__, global_id);
  35. if (!global_id)
  36. pr_err("got zero global_id\n");
  37. if (ac->global_id && global_id != ac->global_id)
  38. pr_err("global_id changed from %llu to %llu\n", ac->global_id,
  39. global_id);
  40. ac->global_id = global_id;
  41. }
  42. /*
  43. * setup, teardown.
  44. */
  45. struct ceph_auth_client *ceph_auth_init(const char *name,
  46. const struct ceph_crypto_key *key,
  47. const int *con_modes)
  48. {
  49. struct ceph_auth_client *ac;
  50. ac = kzalloc_obj(*ac, GFP_NOFS);
  51. if (!ac)
  52. return ERR_PTR(-ENOMEM);
  53. mutex_init(&ac->mutex);
  54. ac->negotiating = true;
  55. if (name)
  56. ac->name = name;
  57. else
  58. ac->name = CEPH_AUTH_NAME_DEFAULT;
  59. ac->key = key;
  60. ac->preferred_mode = con_modes[0];
  61. ac->fallback_mode = con_modes[1];
  62. dout("%s name '%s' preferred_mode %d fallback_mode %d\n", __func__,
  63. ac->name, ac->preferred_mode, ac->fallback_mode);
  64. return ac;
  65. }
  66. void ceph_auth_destroy(struct ceph_auth_client *ac)
  67. {
  68. dout("auth_destroy %p\n", ac);
  69. if (ac->ops)
  70. ac->ops->destroy(ac);
  71. kfree(ac);
  72. }
  73. /*
  74. * Reset occurs when reconnecting to the monitor.
  75. */
  76. void ceph_auth_reset(struct ceph_auth_client *ac)
  77. {
  78. mutex_lock(&ac->mutex);
  79. dout("auth_reset %p\n", ac);
  80. if (ac->ops && !ac->negotiating)
  81. ac->ops->reset(ac);
  82. ac->negotiating = true;
  83. mutex_unlock(&ac->mutex);
  84. }
  85. /*
  86. * EntityName, not to be confused with entity_name_t
  87. */
  88. int ceph_auth_entity_name_encode(const char *name, void **p, void *end)
  89. {
  90. int len = strlen(name);
  91. if (*p + 2*sizeof(u32) + len > end)
  92. return -ERANGE;
  93. ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
  94. ceph_encode_32(p, len);
  95. ceph_encode_copy(p, name, len);
  96. return 0;
  97. }
  98. /*
  99. * Initiate protocol negotiation with monitor. Include entity name
  100. * and list supported protocols.
  101. */
  102. int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
  103. {
  104. struct ceph_mon_request_header *monhdr = buf;
  105. void *p = monhdr + 1, *end = buf + len, *lenp;
  106. int i, num;
  107. int ret;
  108. mutex_lock(&ac->mutex);
  109. dout("auth_build_hello\n");
  110. monhdr->have_version = 0;
  111. monhdr->session_mon = cpu_to_le16(-1);
  112. monhdr->session_mon_tid = 0;
  113. ceph_encode_32(&p, CEPH_AUTH_UNKNOWN); /* no protocol, yet */
  114. lenp = p;
  115. p += sizeof(u32);
  116. ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
  117. ceph_encode_8(&p, 1);
  118. num = ARRAY_SIZE(supported_protocols);
  119. ceph_encode_32(&p, num);
  120. ceph_decode_need(&p, end, num * sizeof(u32), bad);
  121. for (i = 0; i < num; i++)
  122. ceph_encode_32(&p, supported_protocols[i]);
  123. ret = ceph_auth_entity_name_encode(ac->name, &p, end);
  124. if (ret < 0)
  125. goto out;
  126. ceph_decode_need(&p, end, sizeof(u64), bad);
  127. ceph_encode_64(&p, ac->global_id);
  128. ceph_encode_32(&lenp, p - lenp - sizeof(u32));
  129. ret = p - buf;
  130. out:
  131. mutex_unlock(&ac->mutex);
  132. return ret;
  133. bad:
  134. ret = -ERANGE;
  135. goto out;
  136. }
  137. static int build_request(struct ceph_auth_client *ac, bool add_header,
  138. void *buf, int buf_len)
  139. {
  140. void *end = buf + buf_len;
  141. void *p;
  142. int ret;
  143. p = buf;
  144. if (add_header) {
  145. /* struct ceph_mon_request_header + protocol */
  146. ceph_encode_64_safe(&p, end, 0, e_range);
  147. ceph_encode_16_safe(&p, end, -1, e_range);
  148. ceph_encode_64_safe(&p, end, 0, e_range);
  149. ceph_encode_32_safe(&p, end, ac->protocol, e_range);
  150. }
  151. ceph_encode_need(&p, end, sizeof(u32), e_range);
  152. ret = ac->ops->build_request(ac, p + sizeof(u32), end);
  153. if (ret < 0) {
  154. pr_err("auth protocol '%s' building request failed: %d\n",
  155. ceph_auth_proto_name(ac->protocol), ret);
  156. return ret;
  157. }
  158. dout(" built request %d bytes\n", ret);
  159. ceph_encode_32(&p, ret);
  160. return p + ret - buf;
  161. e_range:
  162. return -ERANGE;
  163. }
  164. /*
  165. * Handle auth message from monitor.
  166. */
  167. int ceph_handle_auth_reply(struct ceph_auth_client *ac,
  168. void *buf, size_t len,
  169. void *reply_buf, size_t reply_len)
  170. {
  171. void *p = buf;
  172. void *end = buf + len;
  173. int protocol;
  174. s32 result;
  175. u64 global_id;
  176. void *payload, *payload_end;
  177. u32 payload_len;
  178. char *result_msg;
  179. u32 result_msg_len;
  180. int ret = -EINVAL;
  181. mutex_lock(&ac->mutex);
  182. dout("handle_auth_reply %p %p\n", p, end);
  183. ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
  184. protocol = ceph_decode_32(&p);
  185. result = ceph_decode_32(&p);
  186. global_id = ceph_decode_64(&p);
  187. payload_len = ceph_decode_32(&p);
  188. ceph_decode_need(&p, end, payload_len, bad);
  189. payload = p;
  190. p += payload_len;
  191. ceph_decode_need(&p, end, sizeof(u32), bad);
  192. result_msg_len = ceph_decode_32(&p);
  193. ceph_decode_need(&p, end, result_msg_len, bad);
  194. result_msg = p;
  195. p += result_msg_len;
  196. if (p != end)
  197. goto bad;
  198. dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len,
  199. result_msg, global_id, payload_len);
  200. payload_end = payload + payload_len;
  201. if (ac->negotiating) {
  202. /* server does not support our protocols? */
  203. if (!protocol && result < 0) {
  204. ret = result;
  205. goto out;
  206. }
  207. /* set up (new) protocol handler? */
  208. if (ac->protocol && ac->protocol != protocol) {
  209. ac->ops->destroy(ac);
  210. ac->protocol = 0;
  211. ac->ops = NULL;
  212. }
  213. if (ac->protocol != protocol) {
  214. ret = init_protocol(ac, protocol);
  215. if (ret) {
  216. pr_err("auth protocol '%s' init failed: %d\n",
  217. ceph_auth_proto_name(protocol), ret);
  218. goto out;
  219. }
  220. }
  221. ac->negotiating = false;
  222. }
  223. if (result) {
  224. pr_err("auth protocol '%s' mauth authentication failed: %d\n",
  225. ceph_auth_proto_name(ac->protocol), result);
  226. ret = result;
  227. goto out;
  228. }
  229. ret = ac->ops->handle_reply(ac, global_id, payload, payload_end,
  230. NULL, NULL, NULL, NULL);
  231. if (ret == -EAGAIN) {
  232. ret = build_request(ac, true, reply_buf, reply_len);
  233. goto out;
  234. } else if (ret) {
  235. goto out;
  236. }
  237. out:
  238. mutex_unlock(&ac->mutex);
  239. return ret;
  240. bad:
  241. pr_err("failed to decode auth msg\n");
  242. ret = -EINVAL;
  243. goto out;
  244. }
  245. int ceph_build_auth(struct ceph_auth_client *ac,
  246. void *msg_buf, size_t msg_len)
  247. {
  248. int ret = 0;
  249. mutex_lock(&ac->mutex);
  250. if (ac->ops->should_authenticate(ac))
  251. ret = build_request(ac, true, msg_buf, msg_len);
  252. mutex_unlock(&ac->mutex);
  253. return ret;
  254. }
  255. int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
  256. {
  257. int ret = 0;
  258. mutex_lock(&ac->mutex);
  259. if (ac->ops)
  260. ret = ac->ops->is_authenticated(ac);
  261. mutex_unlock(&ac->mutex);
  262. return ret;
  263. }
  264. EXPORT_SYMBOL(ceph_auth_is_authenticated);
  265. int __ceph_auth_get_authorizer(struct ceph_auth_client *ac,
  266. struct ceph_auth_handshake *auth,
  267. int peer_type, bool force_new,
  268. int *proto, int *pref_mode, int *fallb_mode)
  269. {
  270. int ret;
  271. mutex_lock(&ac->mutex);
  272. if (force_new && auth->authorizer) {
  273. ceph_auth_destroy_authorizer(auth->authorizer);
  274. auth->authorizer = NULL;
  275. }
  276. if (!auth->authorizer)
  277. ret = ac->ops->create_authorizer(ac, peer_type, auth);
  278. else if (ac->ops->update_authorizer)
  279. ret = ac->ops->update_authorizer(ac, peer_type, auth);
  280. else
  281. ret = 0;
  282. if (ret)
  283. goto out;
  284. *proto = ac->protocol;
  285. if (pref_mode && fallb_mode) {
  286. *pref_mode = ac->preferred_mode;
  287. *fallb_mode = ac->fallback_mode;
  288. }
  289. out:
  290. mutex_unlock(&ac->mutex);
  291. return ret;
  292. }
  293. EXPORT_SYMBOL(__ceph_auth_get_authorizer);
  294. void ceph_auth_destroy_authorizer(struct ceph_authorizer *a)
  295. {
  296. a->destroy(a);
  297. }
  298. EXPORT_SYMBOL(ceph_auth_destroy_authorizer);
  299. int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac,
  300. struct ceph_authorizer *a,
  301. void *challenge_buf,
  302. int challenge_buf_len)
  303. {
  304. int ret = 0;
  305. mutex_lock(&ac->mutex);
  306. if (ac->ops && ac->ops->add_authorizer_challenge)
  307. ret = ac->ops->add_authorizer_challenge(ac, a, challenge_buf,
  308. challenge_buf_len);
  309. mutex_unlock(&ac->mutex);
  310. return ret;
  311. }
  312. EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);
  313. int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
  314. struct ceph_authorizer *a,
  315. void *reply, int reply_len,
  316. u8 *session_key, int *session_key_len,
  317. u8 *con_secret, int *con_secret_len)
  318. {
  319. int ret = 0;
  320. mutex_lock(&ac->mutex);
  321. if (ac->ops && ac->ops->verify_authorizer_reply)
  322. ret = ac->ops->verify_authorizer_reply(ac, a,
  323. reply, reply_len, session_key, session_key_len,
  324. con_secret, con_secret_len);
  325. mutex_unlock(&ac->mutex);
  326. return ret;
  327. }
  328. EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
  329. void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
  330. {
  331. mutex_lock(&ac->mutex);
  332. if (ac->ops && ac->ops->invalidate_authorizer)
  333. ac->ops->invalidate_authorizer(ac, peer_type);
  334. mutex_unlock(&ac->mutex);
  335. }
  336. EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
  337. /*
  338. * msgr2 authentication
  339. */
  340. static bool contains(const int *arr, int cnt, int val)
  341. {
  342. int i;
  343. for (i = 0; i < cnt; i++) {
  344. if (arr[i] == val)
  345. return true;
  346. }
  347. return false;
  348. }
  349. static int encode_con_modes(void **p, void *end, int pref_mode, int fallb_mode)
  350. {
  351. WARN_ON(pref_mode == CEPH_CON_MODE_UNKNOWN);
  352. if (fallb_mode != CEPH_CON_MODE_UNKNOWN) {
  353. ceph_encode_32_safe(p, end, 2, e_range);
  354. ceph_encode_32_safe(p, end, pref_mode, e_range);
  355. ceph_encode_32_safe(p, end, fallb_mode, e_range);
  356. } else {
  357. ceph_encode_32_safe(p, end, 1, e_range);
  358. ceph_encode_32_safe(p, end, pref_mode, e_range);
  359. }
  360. return 0;
  361. e_range:
  362. return -ERANGE;
  363. }
  364. /*
  365. * Similar to ceph_auth_build_hello().
  366. */
  367. int ceph_auth_get_request(struct ceph_auth_client *ac, void *buf, int buf_len)
  368. {
  369. int proto = ac->key ? CEPH_AUTH_CEPHX : CEPH_AUTH_NONE;
  370. void *end = buf + buf_len;
  371. void *lenp;
  372. void *p;
  373. int ret;
  374. mutex_lock(&ac->mutex);
  375. if (ac->protocol == CEPH_AUTH_UNKNOWN) {
  376. ret = init_protocol(ac, proto);
  377. if (ret) {
  378. pr_err("auth protocol '%s' init failed: %d\n",
  379. ceph_auth_proto_name(proto), ret);
  380. goto out;
  381. }
  382. } else {
  383. WARN_ON(ac->protocol != proto);
  384. ac->ops->reset(ac);
  385. }
  386. p = buf;
  387. ceph_encode_32_safe(&p, end, ac->protocol, e_range);
  388. ret = encode_con_modes(&p, end, ac->preferred_mode, ac->fallback_mode);
  389. if (ret)
  390. goto out;
  391. lenp = p;
  392. p += 4; /* space for len */
  393. ceph_encode_8_safe(&p, end, CEPH_AUTH_MODE_MON, e_range);
  394. ret = ceph_auth_entity_name_encode(ac->name, &p, end);
  395. if (ret)
  396. goto out;
  397. ceph_encode_64_safe(&p, end, ac->global_id, e_range);
  398. ceph_encode_32(&lenp, p - lenp - 4);
  399. ret = p - buf;
  400. out:
  401. mutex_unlock(&ac->mutex);
  402. return ret;
  403. e_range:
  404. ret = -ERANGE;
  405. goto out;
  406. }
  407. int ceph_auth_handle_reply_more(struct ceph_auth_client *ac, void *reply,
  408. int reply_len, void *buf, int buf_len)
  409. {
  410. int ret;
  411. mutex_lock(&ac->mutex);
  412. ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
  413. NULL, NULL, NULL, NULL);
  414. if (ret == -EAGAIN)
  415. ret = build_request(ac, false, buf, buf_len);
  416. else
  417. WARN_ON(ret >= 0);
  418. mutex_unlock(&ac->mutex);
  419. return ret;
  420. }
  421. int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
  422. u64 global_id, void *reply, int reply_len,
  423. u8 *session_key, int *session_key_len,
  424. u8 *con_secret, int *con_secret_len)
  425. {
  426. int ret;
  427. mutex_lock(&ac->mutex);
  428. ret = ac->ops->handle_reply(ac, global_id, reply, reply + reply_len,
  429. session_key, session_key_len,
  430. con_secret, con_secret_len);
  431. WARN_ON(ret == -EAGAIN || ret > 0);
  432. mutex_unlock(&ac->mutex);
  433. return ret;
  434. }
  435. bool ceph_auth_handle_bad_method(struct ceph_auth_client *ac,
  436. int used_proto, int result,
  437. const int *allowed_protos, int proto_cnt,
  438. const int *allowed_modes, int mode_cnt)
  439. {
  440. mutex_lock(&ac->mutex);
  441. WARN_ON(used_proto != ac->protocol);
  442. if (result == -EOPNOTSUPP) {
  443. if (!contains(allowed_protos, proto_cnt, ac->protocol)) {
  444. pr_err("auth protocol '%s' not allowed\n",
  445. ceph_auth_proto_name(ac->protocol));
  446. goto not_allowed;
  447. }
  448. if (!contains(allowed_modes, mode_cnt, ac->preferred_mode) &&
  449. (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN ||
  450. !contains(allowed_modes, mode_cnt, ac->fallback_mode))) {
  451. pr_err("preferred mode '%s' not allowed\n",
  452. ceph_con_mode_name(ac->preferred_mode));
  453. if (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN)
  454. pr_err("no fallback mode\n");
  455. else
  456. pr_err("fallback mode '%s' not allowed\n",
  457. ceph_con_mode_name(ac->fallback_mode));
  458. goto not_allowed;
  459. }
  460. }
  461. WARN_ON(result == -EOPNOTSUPP || result >= 0);
  462. pr_err("auth protocol '%s' msgr authentication failed: %d\n",
  463. ceph_auth_proto_name(ac->protocol), result);
  464. mutex_unlock(&ac->mutex);
  465. return true;
  466. not_allowed:
  467. mutex_unlock(&ac->mutex);
  468. return false;
  469. }
  470. int ceph_auth_get_authorizer(struct ceph_auth_client *ac,
  471. struct ceph_auth_handshake *auth,
  472. int peer_type, void *buf, int *buf_len)
  473. {
  474. void *end = buf + *buf_len;
  475. int pref_mode, fallb_mode;
  476. int proto;
  477. void *p;
  478. int ret;
  479. ret = __ceph_auth_get_authorizer(ac, auth, peer_type, true, &proto,
  480. &pref_mode, &fallb_mode);
  481. if (ret)
  482. return ret;
  483. p = buf;
  484. ceph_encode_32_safe(&p, end, proto, e_range);
  485. ret = encode_con_modes(&p, end, pref_mode, fallb_mode);
  486. if (ret)
  487. return ret;
  488. ceph_encode_32_safe(&p, end, auth->authorizer_buf_len, e_range);
  489. *buf_len = p - buf;
  490. return 0;
  491. e_range:
  492. return -ERANGE;
  493. }
  494. EXPORT_SYMBOL(ceph_auth_get_authorizer);
  495. int ceph_auth_handle_svc_reply_more(struct ceph_auth_client *ac,
  496. struct ceph_auth_handshake *auth,
  497. void *reply, int reply_len,
  498. void *buf, int *buf_len)
  499. {
  500. void *end = buf + *buf_len;
  501. void *p;
  502. int ret;
  503. ret = ceph_auth_add_authorizer_challenge(ac, auth->authorizer,
  504. reply, reply_len);
  505. if (ret)
  506. return ret;
  507. p = buf;
  508. ceph_encode_32_safe(&p, end, auth->authorizer_buf_len, e_range);
  509. *buf_len = p - buf;
  510. return 0;
  511. e_range:
  512. return -ERANGE;
  513. }
  514. EXPORT_SYMBOL(ceph_auth_handle_svc_reply_more);
  515. int ceph_auth_handle_svc_reply_done(struct ceph_auth_client *ac,
  516. struct ceph_auth_handshake *auth,
  517. void *reply, int reply_len,
  518. u8 *session_key, int *session_key_len,
  519. u8 *con_secret, int *con_secret_len)
  520. {
  521. return ceph_auth_verify_authorizer_reply(ac, auth->authorizer,
  522. reply, reply_len, session_key, session_key_len,
  523. con_secret, con_secret_len);
  524. }
  525. EXPORT_SYMBOL(ceph_auth_handle_svc_reply_done);
  526. bool ceph_auth_handle_bad_authorizer(struct ceph_auth_client *ac,
  527. int peer_type, int used_proto, int result,
  528. const int *allowed_protos, int proto_cnt,
  529. const int *allowed_modes, int mode_cnt)
  530. {
  531. mutex_lock(&ac->mutex);
  532. WARN_ON(used_proto != ac->protocol);
  533. if (result == -EOPNOTSUPP) {
  534. if (!contains(allowed_protos, proto_cnt, ac->protocol)) {
  535. pr_err("auth protocol '%s' not allowed by %s\n",
  536. ceph_auth_proto_name(ac->protocol),
  537. ceph_entity_type_name(peer_type));
  538. goto not_allowed;
  539. }
  540. if (!contains(allowed_modes, mode_cnt, ac->preferred_mode) &&
  541. (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN ||
  542. !contains(allowed_modes, mode_cnt, ac->fallback_mode))) {
  543. pr_err("preferred mode '%s' not allowed by %s\n",
  544. ceph_con_mode_name(ac->preferred_mode),
  545. ceph_entity_type_name(peer_type));
  546. if (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN)
  547. pr_err("no fallback mode\n");
  548. else
  549. pr_err("fallback mode '%s' not allowed by %s\n",
  550. ceph_con_mode_name(ac->fallback_mode),
  551. ceph_entity_type_name(peer_type));
  552. goto not_allowed;
  553. }
  554. }
  555. WARN_ON(result == -EOPNOTSUPP || result >= 0);
  556. pr_err("auth protocol '%s' authorization to %s failed: %d\n",
  557. ceph_auth_proto_name(ac->protocol),
  558. ceph_entity_type_name(peer_type), result);
  559. if (ac->ops->invalidate_authorizer)
  560. ac->ops->invalidate_authorizer(ac, peer_type);
  561. mutex_unlock(&ac->mutex);
  562. return true;
  563. not_allowed:
  564. mutex_unlock(&ac->mutex);
  565. return false;
  566. }
  567. EXPORT_SYMBOL(ceph_auth_handle_bad_authorizer);