[CXX-601] exception during auth Created: 13/May/15  Updated: 11/Sep/19  Resolved: 15/May/15

Status: Closed
Project: C++ Driver
Component/s: None
Affects Version/s: legacy-1.0.0-rc4, legacy-1.0.0
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Judy Han [X] Assignee: Unassigned
Resolution: Done Votes: 0
Labels: legacy-cxx
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Red Hat Enterprise Linux Server release 6.6 (Santiago)
Compiler and Version:
g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
Scons invocation:
v2.0.1.r5134, 2010/08/16 23:02:40, by bdeegan on cooldog
Boost Version:
Version 1.55.0
client library compiled with --ssl --use-sasl-client



 Description   

I recently added auth to my application.
I got following exception:
Exception's what()=nsToCollectionSubstring: no .

The related code is:
100 mongoPtr_ = new mongo::DBClientConnection();
101 if (!mongoPtr_->connect(mongoHostAndPort, errString))

{ 112 return false; 113 }

;
104 if (!mongoPtr_->auth(db, user, pwd, errString))

{ 105 return false; 106 }

;
Line 104 throws the exception.

From shell I am able to call auth using the above db, user, pwd:
%mongo
>use EventAuthDatabase
switched to db EventAuthDatabase
> db.auth("eventLoader","12345678")
1

Thanks!
Judy



 Comments   
Comment by Judy Han [X] [ 15/May/15 ]

Hi Andrew,
Sorry my bad, the exception is actually not from auth, it is from subsequent call createIndex() because I fed an invalid parameter.
It's working now. Please close the ticket.
Thanks a lot for your help!
Judy

Comment by Judy Han [X] [ 15/May/15 ]

Hi Andrew,

Thanks for reading through my code and giving precise suggestions. Sorry I made a embarassing mistake.
After I made the changes you recommanded I got the same exception as previous time. i.e.

what()=nsToCollectionSubstring: no .

It seems as if it is expecting a collection substring in the URL.

I printed URL before connect:
mongodb://eventLoader:12345678@localhost:27017/EventAuthDatabase
and from shell provided with same informat I have:

> use EventAuthDatabase
switched to db EventAuthDatabase
> db.auth("eventLoader", "12345678")
1

Please advice. Thanks!
Judy

p.s. I had a small change to your code: "cs.connect(&errString)" to "cs.connect(errString)" because input parameter expect passing by reference:

DBClientBase * 	connect (std::string &errmsg, double socketTimeout=0) const 

p.s. Thanks for the forum link. I just got a solution to my question from
http://stackoverflow.com/questions/23943651/mongodb-admin-user-not-authorized
thx.

Comment by Andrew Morrow (Inactive) [ 14/May/15 ]

Hi Judy.Han

FYI, questions like you have here are better answered by posting your questions to the mongodb-user group. You can find the group here:

https://groups.google.com/forum/#!forum/mongodb-user

The C++ driver team monitors that group and will respond to questions. If your question turns out to indicate a bug in the driver after discussion with us, then it makes sense to file an issue in the bug tracker.

I recommend that you ask your question about authentication and roles there. It doesn't really pertain directly to the C++ driver.

Comment by Andrew Morrow (Inactive) [ 14/May/15 ]

Hi Judy -

The return value of DBClientConnection::connect is already a DBClientBase pointer. By passing it to the constructor of DBClientConnection, you are converting that pointer to bool. The constructor of DBClientConnection then runs, but 'connect' is never called on it. As a result, the DBClientConnection you are calling _auth on is not connected.

Additionally, when using ConnectionString::parse in the legacy-1.0x driver you must use MongoDB URL syntax, not the old connection string format. If you wish to use the deprecated connection string format you must call ConnectionString::parseDeprecated.

The proper setup to connect vi a URL looks like:

std::string URL = "mongodb://...";
ConnectionString cs = ConnectionString::parse(URL);
std::string errString;
DBClientBase* connection = cs.connect(&errString);

In this case, the auth parameters can be set in the URL (see http://docs.mongodb.org/manual/reference/connection-string/), and you do not need to make a subsequent call to auth.

The proper setup to connect via an old style connection string is:

std::string hostPortStr = ...;
ConnectionString cs = ConnectionString::parseDeprecated(hostPortStr);
std::string errString;
DBClientBase* connection = cs.connect(&errString)
connection->auth(...);

Note that with the old mechanism, you must explicitly call auth since there is no way to provide auth parameters to parseDeprecated.

Comment by Judy Han [X] [ 14/May/15 ]

While we are on the topic of authorization and authentication. I have a question on authorization.
Once I enable authorization for the server, I am not able to do: "db.serverStatus()" anymore, I tried to created a user with "userAdminAnyDatabase" or "dbAdminAnyDatabase" role, the user does not seem to have privilege to call "db.serverStatus()". I got:

> db.serverStatus()
{
	"ok" : 0,
	"errmsg" : "not authorized on admin to execute command { serverStatus: 1.0 }",
	"code" : 13
}

I tried to create a user with "__system" role but failed with syntax error:

> db.createUser(
... {
... user: "system"
... pwd: "password"
... roles: [{role: "__system", db: "admin"}]
... }
... )
2015-05-14T14:40:16.398-0700 E QUERY    SyntaxError: Unexpected identifier

How do I access db.serverStatus() when server authorization is enabled?

Thanks!
Judy

Comment by Judy Han [X] [ 14/May/15 ]

Hi Andrew,
Thanks for the information. I modified the code a bit to use ConnectionString, now the exception is different:

Exception's what()=assertion src/mongo/client/dbclientinterface.h:1630

here is the code snippet:

  1         std::string errString; // NOLINT
  2         mongo::ConnectionString mongoConnectionString = mongo::ConnectionString::parse(hostAndPortStr_, errString);
  3 
  4         if (!mongoConnectionString.isValid()) {
  5             return false;
  6         }
  7 
  8         mongoPtr_ = new mongo::DBClientConnection(mongoConnectionString.connect(errString));
  9         if (!mongoPtr_) {
 10             return false;
 11         };
 12 
 13         std::string db("EventAuthDatabase");  // NOLINT
 14         std::string user("eventLoader");  // NOLINT
 15         std::string pwd("12345678");  // NOLINT
 16         if (!mongoPtr_->auth(db, user, pwd, errString)) {
 17             return false;
 18         };

The exception is from line 16.
MongoDB server: mongodb-linux-x86_64-rhel62-3.0.0
authentication mechanism on the mongDB server: I tried to start the server serveral times with various options, they all have the same exceptions.

mongod --fork --setParameter authenticationMechanisms=PLAIN --auth --config ./mongodb.conf
mongod --fork --setParameter authenticationMechanisms=PLAIN --auth --config ./mongodb.conf
mongod --fork --setParameter authenticationMechanisms=SCRAM-SHA-1 --auth --config ./mongodb.conf

my mongodb.conf is:

fork = true
bind_ip = 127.0.0.1
port = 27017
quiet = true
dbpath = ./data
logpath = ./mongod.log
logappend = true
journal = true
storageEngine = wiredTiger

Both client and server are on the same host for current test.
The exception information I reported are from "what" output.

Comment by Andrew Morrow (Inactive) [ 14/May/15 ]

Hi Judy.Han -

Thanks for the detailed bug report. I do have some additional questions:

  • What version of the MongoDB server are you running?
  • What authentication mechanism are the users on the MongoDB server using (i.e. MONGODB-CR, MONGODB-SCRAM-SHA1, etc.).
  • Are you connecting over SSL?
  • Can you provide any additional information about the returned exception, like its runtime type, and/or the result of calling 'what' on it?

Also, please note that the legacy-1.0.0 driver offers support for connection URLs. Please see the documentation for the 'ConnectionString' class in dbclientinterface.h. In particular, the static function ConnectionString::parse, and the factory function ConnectionString::connect. You may find that it is easier to connect properly when using a connection URL.

Comment by Judy Han [X] [ 13/May/15 ]

sorry the format is messed up, try again:

100         mongoPtr_ = new mongo::DBClientConnection();
101         if (!mongoPtr_->connect(mongoHostAndPort, errString)) {
112             return false;
113         };
104         if (!mongoPtr_->auth(db, user, pwd, errString)) {
105             return false;
106         };

Line 104 throws the exception.

From shell I am able to call auth using the same db, user, pwd:

%mongo
>use EventAuthDatabase
switched to db EventAuthDatabase
> db.auth("eventLoader","12345678")
1

Thanks!
Judy

Generated at Wed Feb 07 21:59:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.