@@ -484,6 +484,134 @@ test_mongoc_client_authenticate (void *context)
484
484
}
485
485
486
486
487
+ static void
488
+ test_mongoc_client_speculative_auth_failure (bool pooled )
489
+ {
490
+ mongoc_client_t * admin_client ;
491
+ char * username ;
492
+ bson_t roles ;
493
+ mongoc_database_t * database ;
494
+ char * uri_str_no_auth ;
495
+ char * uri_str_auth ;
496
+ mongoc_collection_t * collection ;
497
+ mongoc_client_t * auth_client ;
498
+ mongoc_client_pool_t * pool ;
499
+ mongoc_uri_t * uri ;
500
+ mongoc_cursor_t * cursor ;
501
+ const bson_t * doc ;
502
+ bson_error_t error ;
503
+ bool r ;
504
+ bson_t q ;
505
+
506
+ /*
507
+ * Log in as admin.
508
+ */
509
+ admin_client = test_framework_client_new ();
510
+
511
+ /*
512
+ * Add a user to the test database.
513
+ */
514
+ username = gen_test_user ();
515
+ database = mongoc_client_get_database (admin_client , "test" );
516
+ (void ) mongoc_database_remove_user (database , username , & error );
517
+ bson_init (& roles );
518
+ BCON_APPEND (& roles , "0" , "{" , "role" , "read" , "db" , "test" , "}" );
519
+
520
+ r = mongoc_database_add_user (database ,
521
+ username ,
522
+ "testpass" ,
523
+ tmp_bson ("[{'role': 'read', 'db': 'test'}]" ),
524
+ NULL ,
525
+ & error );
526
+
527
+ ASSERT_OR_PRINT (r , error );
528
+ mongoc_database_destroy (database );
529
+
530
+ bson_init (& q );
531
+ uri_str_no_auth = test_framework_get_uri_str_no_auth ("test" );
532
+ uri_str_auth =
533
+ test_framework_add_user_password (uri_str_no_auth , username , "testpass" );
534
+
535
+ if (pooled ) {
536
+ uri = mongoc_uri_new (uri_str_auth );
537
+ pool = mongoc_client_pool_new (uri );
538
+ mongoc_uri_destroy (uri );
539
+
540
+ test_framework_set_pool_ssl_opts (pool );
541
+ auth_client = mongoc_client_pool_pop (pool );
542
+ } else {
543
+ auth_client = mongoc_client_new (uri_str_auth );
544
+ test_framework_set_ssl_opts (auth_client );
545
+ }
546
+
547
+ collection = mongoc_client_get_collection (auth_client , "test" , "test" );
548
+
549
+ database = mongoc_client_get_database (admin_client , "admin" );
550
+
551
+ /* Enable failpoint to break saslContinue */
552
+ r = mongoc_database_command_simple (
553
+ database ,
554
+ tmp_bson ("{'configureFailPoint': 'failCommand', "
555
+ "'mode': {'times': 1}, "
556
+ "'data': {'failCommands': ['saslContinue'], 'closeConnection': "
557
+ "true, 'errorCode': 10107}}" ),
558
+ NULL ,
559
+ NULL ,
560
+ & error );
561
+ ASSERT_OR_PRINT (r , error );
562
+ mongoc_database_destroy (database );
563
+
564
+ /* Try authenticating by running a find operation */
565
+ cursor = mongoc_collection_find_with_opts (collection , & q , NULL , NULL );
566
+ r = mongoc_cursor_next (cursor , & doc );
567
+ if (!r ) {
568
+ r = mongoc_cursor_error (cursor , & error );
569
+ BSON_ASSERT (r );
570
+ ASSERT_ERROR_CONTAINS (error ,
571
+ MONGOC_ERROR_CLIENT ,
572
+ MONGOC_ERROR_CLIENT_AUTHENTICATE ,
573
+ "Failed to send \"saslContinue\" command" );
574
+ }
575
+
576
+ mongoc_cursor_destroy (cursor );
577
+ mongoc_collection_destroy (collection );
578
+
579
+ if (pooled ) {
580
+ mongoc_client_pool_push (pool , auth_client );
581
+ mongoc_client_pool_destroy (pool );
582
+ } else {
583
+ mongoc_client_destroy (auth_client );
584
+ }
585
+
586
+ /*
587
+ * Remove all test users.
588
+ */
589
+ database = mongoc_client_get_database (admin_client , "test" );
590
+ r = mongoc_database_remove_all_users (database , & error );
591
+ BSON_ASSERT (r );
592
+
593
+ bson_destroy (& q );
594
+ bson_free (uri_str_no_auth );
595
+ bson_free (uri_str_auth );
596
+ bson_destroy (& roles );
597
+ bson_free (username );
598
+ mongoc_database_destroy (database );
599
+ mongoc_client_destroy (admin_client );
600
+ }
601
+
602
+ static void
603
+ test_mongoc_client_single_speculative_auth_failure (void * context )
604
+ {
605
+ test_mongoc_client_speculative_auth_failure (false);
606
+ }
607
+
608
+ static void
609
+ test_mongoc_client_pooled_speculative_auth_failure (void * context )
610
+ {
611
+ test_mongoc_client_speculative_auth_failure (true);
612
+ }
613
+
614
+
487
615
static void
488
616
test_mongoc_client_authenticate_cached (bool pooled )
489
617
{
@@ -3857,6 +3985,20 @@ test_client_install (TestSuite *suite)
3857
3985
NULL ,
3858
3986
NULL ,
3859
3987
test_framework_skip_if_no_auth );
3988
+ TestSuite_AddFull (suite ,
3989
+ "/Client/speculative_auth_failure/single" ,
3990
+ test_mongoc_client_single_speculative_auth_failure ,
3991
+ NULL ,
3992
+ NULL ,
3993
+ test_framework_skip_if_no_auth ,
3994
+ test_framework_skip_if_no_failpoint );
3995
+ TestSuite_AddFull (suite ,
3996
+ "/Client/speculative_auth_failure/pooled" ,
3997
+ test_mongoc_client_pooled_speculative_auth_failure ,
3998
+ NULL ,
3999
+ NULL ,
4000
+ test_framework_skip_if_no_auth ,
4001
+ test_framework_skip_if_no_failpoint );
3860
4002
TestSuite_AddFull (suite ,
3861
4003
"/Client/authenticate_cached/pool" ,
3862
4004
test_mongoc_client_authenticate_cached_pooled ,
0 commit comments