Skip to content

Commit 35c200a

Browse files
committed
CDRIVER-2254 fix hang with "canonicalizeHostname"
The GSSAPI / Kerberos option canonicalizeHostname allows the driver to authenticate when hosts report different hostnames than what is used in the Kerberos database. We had used it both with Cyrus-SASL and with Microsoft's SSPI, and it had an infinite loop. Fix the infinite loop, and ignore the setting with SSPI, since SSPI canonicalizes hostnames itself. The setting is only required for Cyrus.
1 parent 8d12d1a commit 35c200a

File tree

9 files changed

+42
-47
lines changed

9 files changed

+42
-47
lines changed

doc/authentication.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Now authenticate using the MongoDB URI. ``GSSAPI`` authenticates against the ``$
9393

9494
The driver supports these GSSAPI properties:
9595

96-
* ``CANONICALIZE_HOST_NAME``: This might be required when the hosts report different hostnames than what is used in the kerberos database. The default is "false".
96+
* ``CANONICALIZE_HOST_NAME``: This might be required with Cyrus-SASL when the hosts report different hostnames than what is used in the Kerberos database. The default is "false".
9797
* ``SERVICE_NAME``: Use a different service name than the default, "mongodb".
9898

9999
Set properties in the URL:

doc/mongoc_uri_t.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Mechanism Properties
116116
========================================== ================================= =========================================================================================================================================================================================================================
117117
Constant Key Description
118118
========================================== ================================= =========================================================================================================================================================================================================================
119-
MONGOC_URI_CANONICALIZEHOSTNAME canonicalizehostname Use the canonical hostname of the service, rather than configured alias.
119+
MONGOC_URI_CANONICALIZEHOSTNAME canonicalizehostname Use the canonical hostname of the service, rather than its configured alias, when authenticating with Cyrus-SASL Kerberos.
120120
MONGOC_URI_GSSAPISERVICENAME gssapiservicename Use alternative service name. The default is ``mongodb``.
121121
========================================== ================================= =========================================================================================================================================================================================================================
122122

src/mongoc/mongoc-cluster-sspi.c

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -149,36 +149,11 @@ _mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster,
149149
bson_t cmd;
150150
int res = MONGOC_SSPI_AUTH_GSS_CONTINUE;
151151
int step;
152-
bool canonicalize = false;
153152
const bson_t *options;
154-
bson_t properties;
155-
char real_name[BSON_HOST_NAME_MAX + 1];
156153
mongoc_server_stream_t *server_stream;
157154

158155
options = mongoc_uri_get_options (cluster->uri);
159-
160-
if (bson_iter_init_find_case (
161-
&iter, options, MONGOC_URI_CANONICALIZEHOSTNAME) &&
162-
BSON_ITER_HOLDS_UTF8 (&iter)) {
163-
canonicalize = bson_iter_bool (&iter);
164-
}
165-
166-
if (mongoc_uri_get_mechanism_properties (cluster->uri, &properties)) {
167-
if (bson_iter_init_find_case (
168-
&iter, &properties, "CANONICALIZE_HOST_NAME") &&
169-
BSON_ITER_HOLDS_UTF8 (&iter)) {
170-
canonicalize = !strcasecmp (bson_iter_utf8 (&iter, NULL), "true");
171-
}
172-
bson_destroy (&properties);
173-
}
174-
175-
if (canonicalize && _mongoc_sasl_get_canonicalized_name (
176-
stream, real_name, sizeof real_name, error)) {
177-
state = _mongoc_cluster_sspi_new (cluster->uri, real_name);
178-
} else {
179-
state = _mongoc_cluster_sspi_new (cluster->uri, sd->host.host);
180-
}
181-
156+
state = _mongoc_cluster_sspi_new (cluster->uri, sd->host.host);
182157

183158
if (!state) {
184159
bson_set_error (error,

src/mongoc/mongoc-cyrus.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ _mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl,
200200
*/
201201
if (sasl->credentials.canonicalize_host_name &&
202202
_mongoc_sasl_get_canonicalized_name (
203-
stream, real_name, sizeof real_name, error)) {
203+
stream, real_name, sizeof real_name)) {
204204
_mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, real_name);
205205
} else {
206206
_mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, hostname);

src/mongoc/mongoc-sasl-private.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ _mongoc_sasl_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri);
5353
bool
5454
_mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */
5555
char *name, /* OUT */
56-
size_t namelen, /* IN */
57-
bson_error_t *error); /* OUT */
56+
size_t namelen); /* IN */
5857

5958
BSON_END_DECLS
6059

src/mongoc/mongoc-sasl.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "mongoc-util-private.h"
2222

2323
#include "mongoc-trace-private.h"
24+
#include "mongoc-change-stream-private.h"
2425

2526
#undef MONGOC_LOG_DOMAIN
2627
#define MONGOC_LOG_DOMAIN "SASL"
@@ -149,11 +150,9 @@ _mongoc_sasl_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri)
149150
bool
150151
_mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */
151152
char *name, /* OUT */
152-
size_t namelen, /* IN */
153-
bson_error_t *error) /* OUT */
153+
size_t namelen) /* OUT */
154154
{
155155
mongoc_stream_t *stream;
156-
mongoc_stream_t *tmp;
157156
mongoc_socket_t *sock = NULL;
158157
char *canonicalized;
159158

@@ -162,17 +161,7 @@ _mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */
162161
BSON_ASSERT (node_stream);
163162
BSON_ASSERT (name);
164163

165-
/*
166-
* Find the underlying socket used in the stream chain.
167-
*/
168-
for (stream = node_stream; stream;) {
169-
if ((tmp = mongoc_stream_get_base_stream (stream))) {
170-
stream = tmp;
171-
continue;
172-
}
173-
break;
174-
}
175-
164+
stream = mongoc_stream_get_root_stream (node_stream);
176165
BSON_ASSERT (stream);
177166

178167
if (stream->type == MONGOC_STREAM_SOCKET) {

src/mongoc/mongoc-stream-private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ _mongoc_stream_writev_full (mongoc_stream_t *stream,
4444
int32_t timeout_msec,
4545
bson_error_t *error);
4646

47+
mongoc_stream_t *
48+
mongoc_stream_get_root_stream (mongoc_stream_t *stream);
4749

4850
BSON_END_DECLS
4951

src/mongoc/mongoc-stream.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,8 @@ mongoc_stream_get_base_stream (mongoc_stream_t *stream) /* IN */
312312
}
313313

314314

315-
static mongoc_stream_t *
315+
mongoc_stream_t *
316316
mongoc_stream_get_root_stream (mongoc_stream_t *stream)
317-
318317
{
319318
BSON_ASSERT (stream);
320319

tests/test-mongoc-cyrus.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <mongoc-thread-private.h>
1919
#ifdef MONGOC_ENABLE_SASL_CYRUS
2020
#include <mongoc-cyrus-private.h>
21+
#include <mongoc-client-private.h>
22+
2123
#endif
2224

2325
#include "TestSuite.h"
@@ -179,6 +181,28 @@ test_sasl_properties (void)
179181
_mongoc_cyrus_destroy (&sasl);
180182
mongoc_uri_destroy (uri);
181183
}
184+
185+
186+
static void
187+
test_sasl_canonicalize_hostname (void *ctx)
188+
{
189+
mongoc_client_t *client;
190+
mongoc_server_stream_t *ss;
191+
char real_name[BSON_HOST_NAME_MAX + 1] = {'\0'};
192+
bson_error_t error;
193+
194+
client = test_framework_client_new ();
195+
ss = mongoc_cluster_stream_for_reads (&client->cluster, NULL, &error);
196+
ASSERT_OR_PRINT (ss, error);
197+
198+
BSON_ASSERT (_mongoc_sasl_get_canonicalized_name (
199+
ss->stream, real_name, sizeof real_name));
200+
201+
ASSERT_CMPSIZE_T (strlen (real_name), >, (size_t) 0);
202+
203+
mongoc_server_stream_cleanup (ss);
204+
mongoc_client_destroy (client);
205+
}
182206
#endif
183207

184208

@@ -192,6 +216,13 @@ test_sasl_install (TestSuite *suite)
192216
NULL,
193217
should_run_gssapi_kerberos);
194218
#ifdef MONGOC_ENABLE_SASL_CYRUS
219+
TestSuite_AddFull (suite,
220+
"/SASL/canonicalize",
221+
test_sasl_canonicalize_hostname,
222+
NULL,
223+
NULL,
224+
TestSuite_CheckLive,
225+
test_framework_skip_if_offline);
195226
TestSuite_Add (suite, "/SASL/properties", test_sasl_properties);
196227
#endif
197228
}

0 commit comments

Comments
 (0)