[GODRIVER-1033] Authenticated connection does not have permissions to execute replSetGetStatus Created: 09/May/19  Updated: 17/Jun/19  Resolved: 17/Jun/19

Status: Closed
Project: Go Driver
Component/s: Authentication
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Jonathan Balsano Assignee: Isabella Siu (Inactive)
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates GODRIVER-1090 Authentication fails against Hidden S... Closed
Related

 Description   

I'm working on a project that automates MongoDB deployments and then attempts to connect to them to check their status using the replSetGetStatus command. In this particular case the code running in a separate goroutine is:

  1. Creating a MongoDB Sharded Cluster with MONGODB-SCRAM-SHA-256 authentication
  2. Creating a user "XXX" with password "YYY"
  3. Assigning that user the clusterMonitor role

The goroutine that concerns me is the code below, and results in two very strange symptoms:

  1. The connection status command returns results showing no users nor roles for the current connection, even though they've been provided in the clientOptions:

    {"authInfo":{"authenticatedUserRoles":[],"authenticatedUsers":[]},"ok":1}
    

  2. The call to replSetGetStatus fails with the error:

    Failure on replSetGetStatus command: Err: not authorized on admin to execute command { replSetGetStatus: 1 }
    

The code (taken out of context)

package main
 
import "fmt"
import "encoding/json"
import "time"
import "context"
import "go.mongodb.org/mongo-driver/bson"
import "go.mongodb.org/mongo-driver/mongo"
import "go.mongodb.org/mongo-driver/mongo/options"
import "go.mongodb.org/mongo-driver/mongo/readpref"
 
func main() {
	credential := options.Credential{
		AuthMechanism:           "",
		AuthSource:              "admin",
		Username:                "XXX",
		Password:                "YYY",
		PasswordSet:             true,
		AuthMechanismProperties: nil,
	}
 
	clientOptions := options.ClientOptions{}
	clientOptions.SetAuth(credential)
	clientOptions.SetReadPreference(readpref.Nearest())
	clientOptions.ApplyURI("mongodb://localhost:28100/?connect=direct")
	clientOptions.SetConnectTimeout(40 * time.Second)
	clientOptions.SetServerSelectionTimeout(40 * time.Second)
	clientOptions.SetSocketTimeout(40 * time.Second)
 
	marshalledJson, err := json.Marshal(clientOptions)
	if err != nil {
		fmt.Printf("Couldn't serialize clientOptions\n")
	} else {
		fmt.Printf("clientOptions: %s\n", string(marshalledJson))
	}
 
	// time.Sleep(30 * time.Second)
 
	client, err := mongo.NewClient(&clientOptions)
	if err != nil {
		fmt.Printf("Failure creating new client")
		return
	}
 
	err = client.Connect(context.TODO())
	if err != nil {
		fmt.Printf("Failure dialing host. Err: `%v`", err)
		return
	}
 
	admin := client.Database("admin")
 
	var connectionStatus bson.M
	if err := admin.RunCommand(context.Background(), bson.D{{"connectionStatus", 1}}).Decode(&connectionStatus); err != nil {
		fmt.Printf("Failed to get connectionStatus\n")
	}
	marshalledClient, err := json.Marshal(connectionStatus)
	if err != nil {
		fmt.Printf("Couldn't serialize the connectionStatus\n")
	} else {
		fmt.Printf("After creation Client has connectionStatus %s\n", string(marshalledClient))
	}
 
	var replSetGetStatus bson.Raw
	if err := admin.RunCommand(context.Background(), bson.D{{"replSetGetStatus", 1}}).Decode(&replSetGetStatus); err != nil {
		fmt.Printf("Failure on replSetGetStatus command: Err: %v", err)
		return
	}
 
}

The above code succeeds if I uncomment the sleep, which leads me to believe I'm catching an intermediary state in MongoDB that is unhandled.

My major concern here is that the go driver doesn't let me know that authentication has failed at any point, the only thing it does tell me is that I'm not authorized to execute the command I'm trying to execute, and that my connection has no users nor roles associated with it.

Additionally, I've confirmed behavior is not what I'm currently getting if:

  1. The user I try to authenticate as does not exist but auth has not been enabled for the cluster
  2. The user I try to authenticate as does not exist but auth has been enabled for the cluster
  3. The user exists but has not been assigned roles
  4. The user and roles exist (everything succeeds)

Because of this, I've worked around this issue by checking connectionStatus for a lack of users/roles and using that to decide whether my connection has been successful. But, given that I've provided authentication credentials I'd expect either a different kind of failure from the runCommand command or for connect to fail altogether.

I'm not sure how to help reproduce this issue further but if anyone on the team wants me to reproduce it for them I can consistently do so. I'm also happy to use a modified version of the go driver to get finer grained debugging output.



 Comments   
Comment by Jonathan Balsano [ 17/Jun/19 ]

Investigated and yes it looks like this was a duplicate of GODRIVER-1090. Marking it as such and closing!

Comment by Jonathan Balsano [ 13/Jun/19 ]

esha.bhargava I haven't had a chance to investigate this issue but it's possible it still exists. Can we leave this open until then?

Comment by Jonathan Balsano [ 29/May/19 ]

jeff.yemin I don't believe so, but will be investigating to see if the solution in GODRIVER-1090 fixes this one. It's a little bit lower on my priorities given we put a workaround in place already.

Comment by Jeffrey Yemin [ 29/May/19 ]

jonathan.balsano is this related (or a duplicate of) GODRIVER-1090?

Comment by Jonathan Balsano [ 23/May/19 ]

Some updates:

  • What I'd expect from connectionStatus is an error of the type:

    Failed to get connectionStatus. Err: `auth error: sasl conversation error: unable to authenticate using mechanism "SCRAM-SHA-1": Authentication failed.`
    

    but instead it goes through and we have the empty users/roles as above

  • I am able to reproduce this in a sharded cluster (2 PSA shards , 3 configs, 1 mongos) and a replica set (PSA), but not in a standalone
  • I have also reproduced without arbiters (PSS shards)
Comment by Jonathan Balsano [ 21/May/19 ]

Hey there! Looping back here to make this ticket a little more clear to what the actual problem was. I was very in the weeds when I wrote it, so adding a little more context to highlight the problem.

Generated at Thu Feb 08 08:35:31 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.