Skip to content
Snippets Groups Projects
Commit 9219c029 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Allow GUEST user to pass authentication request without a password.

If no password is set for GUEST user, allow a client
to authenticate to GUEST.

For all other users, no password means that it's only possible to become
such user with session.su() or inside a setuid function.

The exception for GUEST user is useful for connection
pooling, where we would like to "reset" a connection to its
default, non-authenticated state, when returning it to the pool.
parent 18c4a79f
No related branches found
No related tags found
No related merge requests found
...@@ -30,21 +30,35 @@ ...@@ -30,21 +30,35 @@
#include "user_def.h" #include "user_def.h"
#include "session.h" #include "session.h"
static char zero_hash[SCRAMBLE_SIZE];
void void
authenticate(const char *user_name, uint32_t len, authenticate(const char *user_name, uint32_t len,
const char *tuple, const char * /* tuple_end */) const char *tuple, const char * /* tuple_end */)
{ {
struct user_def *user = user_cache_find_by_name(user_name, len); struct user_def *user = user_cache_find_by_name(user_name, len);
struct session *session = current_session(); struct session *session = current_session();
uint32_t part_count = mp_decode_array(&tuple); uint32_t part_count;
uint32_t scramble_len;
const char *scramble;
/*
* Allow authenticating back to GUEST user without
* checking a password. This is useful for connection
* pooling.
*/
if (user->uid == GUEST && memcmp(user->hash2, zero_hash, SCRAMBLE_SIZE)) {
/* No password is set for GUEST, OK. */
goto ok;
}
part_count = mp_decode_array(&tuple);
if (part_count < 2) { if (part_count < 2) {
/* Expected at least: authentication mechanism and data. */ /* Expected at least: authentication mechanism and data. */
tnt_raise(ClientError, ER_INVALID_MSGPACK, tnt_raise(ClientError, ER_INVALID_MSGPACK,
"authentication request body"); "authentication request body");
} }
mp_next(&tuple); /* Skip authentication mechanism. */ mp_next(&tuple); /* Skip authentication mechanism. */
uint32_t scramble_len; scramble = mp_decode_str(&tuple, &scramble_len);
const char *scramble = mp_decode_str(&tuple, &scramble_len);
if (scramble_len != SCRAMBLE_SIZE) { if (scramble_len != SCRAMBLE_SIZE) {
/* Authentication mechanism, data. */ /* Authentication mechanism, data. */
tnt_raise(ClientError, ER_INVALID_MSGPACK, tnt_raise(ClientError, ER_INVALID_MSGPACK,
...@@ -54,6 +68,7 @@ authenticate(const char *user_name, uint32_t len, ...@@ -54,6 +68,7 @@ authenticate(const char *user_name, uint32_t len,
if (scramble_check(scramble, session->salt, user->hash2)) if (scramble_check(scramble, session->salt, user->hash2))
tnt_raise(ClientError, ER_PASSWORD_MISMATCH, user->name); tnt_raise(ClientError, ER_PASSWORD_MISMATCH, user->name);
ok:
current_user_init(&session->user, user); current_user_init(&session->user, user);
} }
...@@ -37,7 +37,7 @@ struct user_def; ...@@ -37,7 +37,7 @@ struct user_def;
* in session->auth_token. This way it's easy to quickly find * in session->auth_token. This way it's easy to quickly find
* the current user of the session. * the current user of the session.
* An auth token, instead of a direct pointer, is stored in the * An auth token, instead of a direct pointer, is stored in the
* session because it make dropping of a signed in user safe. * session because it makes dropping of a signed in user safe.
* The same auth token (index in an array) * The same auth token (index in an array)
* is also used to find out user privileges when accessing stored * is also used to find out user privileges when accessing stored
* objects, such as spaces and functions. * objects, such as spaces and functions.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment