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