[CDRIVER-1928] "Unknown command error" from authentication and misformatted domain socket URI Created: 17/Nov/16  Updated: 17/Dec/16  Resolved: 10/Dec/16

Status: Closed
Project: C Driver
Component/s: libmongoc
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Bug Priority: Major - P3
Reporter: Jeremy Mikola Assignee: A. Jesse Jiryu Davis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

MongoDB 3.2, libmongoc-1.5.0-rc6


Issue Links:
Related
related to CDRIVER-1929 mongoc_uri_parse_database() may overl... Closed
is related to CDRIVER-784 Bring mongoc_uri_t up to spec. Closed
is related to PHPLIB-174 Document that socket paths must be UR... Closed
is related to DOCS-9382 Show URL-escaped domain socket path i... Closed

 Description   

In PHPLIB-174, a user failed to escape the Unix domain socket path in their connection URI and received an odd exception message when database authentication failed.

I extracted the following trace while reproducing the scenario with MongoDB 3.2 and a build of the PHPC linked against libmongoc 1.5.0-rc6:

[2016-11-17T23:40:11+00:00]     stream: TRACE   > ENTRY: mongoc_stream_read():268
[2016-11-17T23:40:11+00:00]     stream: TRACE   > ENTRY: mongoc_stream_readv():226
[2016-11-17T23:40:11+00:00]     stream: TRACE   > ENTRY: _mongoc_stream_socket_readv():139
[2016-11-17T23:40:11+00:00]     socket: TRACE   > ENTRY: mongoc_socket_recv():797
[2016-11-17T23:40:11+00:00]     socket: TRACE   >  EXIT: mongoc_socket_recv():826
[2016-11-17T23:40:11+00:00]     stream: TRACE   >  EXIT: _mongoc_stream_socket_readv():188
[2016-11-17T23:40:11+00:00]     stream: TRACE   > TRACE: mongoc_stream_readv():236 readv = 0x7ffdf48cb8b0 [1]
[2016-11-17T23:40:11+00:00]     stream: TRACE   > 00000:  57 00 00 00 02 24 65 72  72 00 3e 00 00 00 6e 6f  W . . . . $ e r  r . > . . . n o
[2016-11-17T23:40:11+00:00]     stream: TRACE   > 00010:  74 20 61 75 74 68 6f 72  69 7a 65 64 20 66 6f 72  t   a u t h o r  i z e d   f o r
[2016-11-17T23:40:11+00:00]     stream: TRACE   > 00020:  20 71 75 65 72 79 20 6f  6e 20 74 6d 70 2f 6d 6f    q u e r y   o  n   t m p / m o
[2016-11-17T23:40:11+00:00]     stream: TRACE   > 00030:  6e 67 6f 64 62 2d 32 37  30 31 37 2e 73 6f 63 6b  n g o d b - 2 7  0 1 7 . s o c k
[2016-11-17T23:40:11+00:00]     stream: TRACE   > 00040:  2f 61 64 6d 69 6e 2e 24  63 6d 64 00 10 63 6f 64  / a d m i n . $  c m d . . c o d
[2016-11-17T23:40:11+00:00]     stream: TRACE   > 00050:  65 00 0d 00 00 00 00                              e . . . . . .
[2016-11-17T23:40:11+00:00]     stream: TRACE   >  EXIT: mongoc_stream_readv():239
[2016-11-17T23:40:11+00:00]     stream: TRACE   >  EXIT: mongoc_stream_read():280
[2016-11-17T23:40:11+00:00]     mongoc: TRACE   > ENTRY: _mongoc_populate_cmd_error():770
[2016-11-17T23:40:11+00:00]     mongoc: TRACE   >  EXIT: _mongoc_populate_cmd_error():795

This translates to:

{
    "$err" : "not authorized for query on tmp\/mongodb-27017.sock.$cmd",
    "code" : 13
}

From the MongoDB logs, the following command was being executed at the time:

2016-11-17T18:40:11.336-0500 I QUERY    [conn1] assertion 13 not authorized for query on tmp/mongodb-27017.sock/admin.$cmd ns:tmp/mongodb-27017.sock/admin.$cmd query:{ saslStart: 1, mechanism: "SCRAM-SHA-1", payload: BinData(0, 6E2C2C6E3D666F6F2C723D6774713035457335496C70736E456D762B6F55554D76376868666156474F7066), autoAuthorize: 1 }

I consulted the legacy PHP driver and it did consult the "$err" field when checking for cursor errors (see: mongo_connect_send_packet()). Based on the trace data, _mongoc_populate_cmd_error() is being used to populate the bson_error_t. Perhaps _mongoc_populate_query_error(), which does check for "$err" and "code" fields, should be used instead.



 Comments   
Comment by Githook User [ 17/Dec/16 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-1928 "unknown command error" from auth

Auth errors have $err, not the standard errmsg - check for $err instead
of setting the error message to "Unknown command error".
Branch: r1.5
https://github.com/mongodb/mongo-c-driver/commit/e3e9359fbdb8a391cfe6514741439af8174e8830

Comment by Githook User [ 10/Dec/16 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-1928 "unknown command error" from auth

Auth errors have $err, not the standard errmsg - check for $err instead
of setting the error message to "Unknown command error".
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/2bf34185232d6e35454fe2ea25a8a594c4b5a5c3

Comment by Githook User [ 27/Nov/16 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-1928 show URL-encoded Unix sockets in docs
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/60e1e591b1f206d436432f53e7397fed4abfdfc1

Comment by A. Jesse Jiryu Davis [ 27/Nov/16 ]

Authenticating to mongod 2.6.9 or 3.2.9 with URI "mongodb://user:pass@/tmp/mongodb.sock" gets this reply:

{ "$err" : "not authorized for query on tmp\/mongodb-27017.sock.$cmd", "code" : 13 }

The function we currently use, _mongoc_populate_cmd_error, checks for "errmsg" but not for "$err". Let's just extend _mongoc_populate_cmd_error:

diff --git a/src/mongoc/mongoc-rpc.c b/src/mongoc/mongoc-rpc.c
index da33174..e0c0b86 100644
--- a/src/mongoc/mongoc-rpc.c
+++ b/src/mongoc/mongoc-rpc.c
@@ -785,6 +785,9 @@ _mongoc_populate_cmd_error (const bson_t *doc,
    if (bson_iter_init_find (&iter, doc, "errmsg") &&
        BSON_ITER_HOLDS_UTF8 (&iter)) {
       msg = bson_iter_utf8 (&iter, NULL);
+   } else if (bson_iter_init_find (&iter, doc, "$err") &&
+              BSON_ITER_HOLDS_UTF8 (&iter)) {
+      msg = bson_iter_utf8 (&iter, NULL);
    }
 
    bson_set_error (error, domain, code, "%s", msg);

Let's also update the domain socket example in advanced-connections.page to show a properly escaped domain socket path.

CDRIVER-784 will further stamp out this bug by detecting when the URI includes an unescaped domain socket path.

By the way, the Manual shows the old connection string style, not escaped:

mongodb:///tmp/mongodb-27017.sock

https://docs.mongodb.com/manual/reference/connection-string/#unix-domain-socket

I've filed DOCS-9382.

Comment by Hannes Magnusson [ 21/Nov/16 ]

This may be causing Fatal error: Uncaught exception 'MongoDB\Driver\Exception\RuntimeException' with message 'Unknown command error' error in the PHP driver on authentication failure... Which raises the urgency of this ticket.

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