Style fixes, comments for 4.1.1 authorization
Now special 1-byte packet is used for request of old password Fixed bug with --skip-grant-tables and acl_getroot include/mysql.h: removed scramble_323 member as now scramble_323 function does not count on trailing zero for scramble include/mysql_com.h: updated declarations libmysql/libmysql.c: now server sends special 1-byte packet instead of old scramble to re-request password. mysql->scramble_323 replaced with mysql->scramble sql-common/client.c: now server sends special 1-byte packet instead of old scramble to re-request password. mysql->scramble_323 replaces with mysql->scramble sql/password.c: comments beautified hash_password now accepts password length sql/protocol.cc: added send_old_password_request function sql/protocol.h: added send_old_password_request function sql/sql_acl.cc: style fixes, bug with --skip-grant-tables and acl_getroot fixed sql/sql_class.h: thd->scramble_323 removed as now old functions accept not null-terminated scrambles sql/sql_crypt.cc: fixed with new hash_password proto sql/sql_parse.cc: style fixes few comments added
This commit is contained in:
parent
84afd56e69
commit
30ced7f7f6
@ -228,8 +228,8 @@ typedef struct st_mysql
|
||||
my_bool free_me; /* If free in mysql_close */
|
||||
my_bool reconnect; /* set to 1 if automatic reconnect */
|
||||
|
||||
char scramble[SCRAMBLE_LENGTH+1]; /* for new servers */
|
||||
char scramble_323[SCRAMBLE_LENGTH_323+1]; /* for old servers */
|
||||
/* session-wide random string */
|
||||
char scramble[max(SCRAMBLE_LENGTH,SCRAMBLE_LENGTH_323)+1];
|
||||
|
||||
/*
|
||||
Set if this is the original connection, not a master or a slave we have
|
||||
|
@ -318,9 +318,9 @@ void randominit(struct rand_struct *, unsigned long seed1,
|
||||
double my_rnd(struct rand_struct *);
|
||||
void create_random_string(char *to, uint length, struct rand_struct *rand_st);
|
||||
|
||||
void hash_password(ulong *to, const char *password);
|
||||
void hash_password(ulong *to, const char *password, uint password_len);
|
||||
void make_scrambled_password_323(char *to, const char *password);
|
||||
char *scramble_323(char *to, const char *message, const char *password);
|
||||
void scramble_323(char *to, const char *message, const char *password);
|
||||
my_bool check_scramble_323(const char *, const char *message,
|
||||
unsigned long *salt);
|
||||
void get_salt_from_password_323(unsigned long *res, const char *password);
|
||||
|
@ -626,7 +626,10 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
end+= SCRAMBLE_LENGTH;
|
||||
}
|
||||
else
|
||||
end= scramble_323(end, mysql->scramble_323, passwd);
|
||||
{
|
||||
scramble_323(end, mysql->scramble, passwd);
|
||||
end+= SCRAMBLE_LENGTH_323 + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
*end++= '\0'; // empty password
|
||||
@ -642,15 +645,14 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
if (pkt_length == packet_error)
|
||||
goto error;
|
||||
|
||||
if (net->read_pos[0] == mysql->scramble_323[0] &&
|
||||
pkt_length == SCRAMBLE_LENGTH_323 + 1 &&
|
||||
if (pkt_length == 1 && net->read_pos[0] == 254 &&
|
||||
mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||
{
|
||||
/*
|
||||
By sending this very specific reply server asks us to send scrambled
|
||||
password in old format. The reply contains scramble_323.
|
||||
*/
|
||||
scramble_323(buff, mysql->scramble_323, passwd);
|
||||
scramble_323(buff, mysql->scramble, passwd);
|
||||
if (my_net_write(net, buff, SCRAMBLE_LENGTH_323 + 1) || net_flush(net))
|
||||
{
|
||||
net->last_errno= CR_SERVER_LOST;
|
||||
|
@ -1641,9 +1641,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
Scramble is split into two parts because old clients does not understand
|
||||
long scrambles; here goes the first part.
|
||||
*/
|
||||
strmake(mysql->scramble_323, end, SCRAMBLE_LENGTH_323);
|
||||
strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323);
|
||||
end+= SCRAMBLE_LENGTH_323+1;
|
||||
memcpy(mysql->scramble, mysql->scramble_323, SCRAMBLE_LENGTH_323);
|
||||
|
||||
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
|
||||
mysql->server_capabilities=uint2korr(end);
|
||||
@ -1842,7 +1841,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
end+= SCRAMBLE_LENGTH;
|
||||
}
|
||||
else
|
||||
end= scramble_323(end, mysql->scramble_323, passwd) + 1;
|
||||
{
|
||||
scramble_323(end, mysql->scramble, passwd);
|
||||
end+= SCRAMBLE_LENGTH_323 + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
*end++= '\0'; /* empty password */
|
||||
@ -1871,15 +1873,14 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
||||
goto error;
|
||||
|
||||
if (net->read_pos[0] == mysql->scramble_323[0] &&
|
||||
pkt_length == SCRAMBLE_LENGTH_323 + 1 &&
|
||||
if (pkt_length == 1 && net->read_pos[0] == 254 &&
|
||||
mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||
{
|
||||
/*
|
||||
By sending this very specific reply server asks us to send scrambled
|
||||
password in old format. The reply contains scramble_323.
|
||||
*/
|
||||
scramble_323(buff, mysql->scramble_323, passwd);
|
||||
scramble_323(buff, mysql->scramble, passwd);
|
||||
if (my_net_write(net, buff, SCRAMBLE_LENGTH_323 + 1) || net_flush(net))
|
||||
{
|
||||
net->last_errno= CR_SERVER_LOST;
|
||||
|
@ -110,15 +110,17 @@ double my_rnd(struct rand_struct *rand_st)
|
||||
Used for Pre-4.1 password handling
|
||||
SYNOPSIS
|
||||
hash_password()
|
||||
result OUT store hash in this location
|
||||
password IN plain text password to build hash
|
||||
result OUT store hash in this location
|
||||
password IN plain text password to build hash
|
||||
password_len IN password length (password may be not null-terminated)
|
||||
*/
|
||||
|
||||
void hash_password(ulong *result, const char *password)
|
||||
void hash_password(ulong *result, const char *password, uint password_len)
|
||||
{
|
||||
register ulong nr=1345345333L, add=7, nr2=0x12345671L;
|
||||
ulong tmp;
|
||||
for (; *password ; password++)
|
||||
const char *password_end= password + password_len;
|
||||
for (; password < password_end; password++)
|
||||
{
|
||||
if (*password == ' ' || *password == '\t')
|
||||
continue; /* skip space in password */
|
||||
@ -129,7 +131,6 @@ void hash_password(ulong *result, const char *password)
|
||||
}
|
||||
result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
|
||||
result[1]=nr2 & (((ulong) 1L << 31) -1L);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +146,7 @@ void hash_password(ulong *result, const char *password)
|
||||
void make_scrambled_password_323(char *to, const char *password)
|
||||
{
|
||||
ulong hash_res[2];
|
||||
hash_password(hash_res, password);
|
||||
hash_password(hash_res, password, strlen(password));
|
||||
sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]);
|
||||
}
|
||||
|
||||
@ -157,14 +158,12 @@ void make_scrambled_password_323(char *to, const char *password)
|
||||
scramble_323()
|
||||
to OUT Store scrambled message here. Buffer must be at least
|
||||
SCRAMBLE_LENGTH_323+1 bytes long
|
||||
message IN Message to scramble. Message must be exactly
|
||||
SRAMBLE_LENGTH_323 long and NULL terminated.
|
||||
message IN Message to scramble. Message must be at least
|
||||
SRAMBLE_LENGTH_323 bytes long.
|
||||
password IN Password to use while scrambling
|
||||
RETURN
|
||||
End of scrambled string
|
||||
*/
|
||||
|
||||
char *scramble_323(char *to, const char *message, const char *password)
|
||||
void scramble_323(char *to, const char *message, const char *password)
|
||||
{
|
||||
struct rand_struct rand_st;
|
||||
ulong hash_pass[2], hash_message[2];
|
||||
@ -172,18 +171,18 @@ char *scramble_323(char *to, const char *message, const char *password)
|
||||
if (password && password[0])
|
||||
{
|
||||
char *to_start=to;
|
||||
hash_password(hash_pass,password);
|
||||
hash_password(hash_message, message);
|
||||
hash_password(hash_pass,password, strlen(password));
|
||||
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||
hash_pass[1] ^ hash_message[1]);
|
||||
while (*message++)
|
||||
const char *message_end= message + SCRAMBLE_LENGTH_323;
|
||||
for (; message < message_end; message++)
|
||||
*to++= (char) (floor(my_rnd(&rand_st)*31)+64);
|
||||
char extra=(char) (floor(my_rnd(&rand_st)*31));
|
||||
while (to_start != to)
|
||||
*(to_start++)^=extra;
|
||||
}
|
||||
*to= 0;
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
@ -192,11 +191,13 @@ char *scramble_323(char *to, const char *message, const char *password)
|
||||
Used in pre 4.1 password handling
|
||||
SYNOPSIS
|
||||
check_scramble_323()
|
||||
scrambled IN scrambled message to check.
|
||||
message IN original random message which was used for scrambling; must
|
||||
be exactly SCRAMBLED_LENGTH_323 bytes long and
|
||||
NULL-terminated.
|
||||
hash_pass IN password which should be used for scrambling
|
||||
scrambled scrambled message to check.
|
||||
message original random message which was used for scrambling; must
|
||||
be exactly SCRAMBLED_LENGTH_323 bytes long and
|
||||
NULL-terminated.
|
||||
hash_pass password which should be used for scrambling
|
||||
All params are IN.
|
||||
|
||||
RETURN VALUE
|
||||
0 - password correct
|
||||
!0 - password invalid
|
||||
@ -211,11 +212,7 @@ check_scramble_323(const char *scrambled, const char *message,
|
||||
char buff[16],*to,extra; /* Big enough for check */
|
||||
const char *pos;
|
||||
|
||||
/* Check if this exactly N bytes. Overwise this is something fishy */
|
||||
if (strlen(message) != SCRAMBLE_LENGTH_323)
|
||||
return 1; /* Wrong password */
|
||||
|
||||
hash_password(hash_message,message);
|
||||
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||
hash_pass[1] ^ hash_message[1]);
|
||||
to=buff;
|
||||
@ -231,7 +228,7 @@ check_scramble_323(const char *scrambled, const char *message,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8 char_val(uint8 X)
|
||||
static inline uint8 char_val(uint8 X)
|
||||
{
|
||||
return (uint) (X >= '0' && X <= '9' ? X-'0' :
|
||||
X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
|
||||
@ -280,7 +277,10 @@ void make_password_from_salt_323(char *to, const ulong *salt)
|
||||
}
|
||||
|
||||
|
||||
/******************* MySQL 4.1.1 authentification routines ******************/
|
||||
/*
|
||||
**************** MySQL 4.1.1 authentification routines *************
|
||||
*/
|
||||
|
||||
/*
|
||||
Generate string of printable random characters of requested length
|
||||
SYNOPSIS
|
||||
@ -315,19 +315,16 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st)
|
||||
str, len IN the beginning and the length of the input string
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
static void
|
||||
octet2hex(char *to, const uint8 *str, uint len)
|
||||
{
|
||||
static const char alphabet[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
const uint8 *str_end= str + len;
|
||||
for (; str != str_end; ++str)
|
||||
{
|
||||
*to++= alphabet[(*str & 0xF0) >> 4];
|
||||
*to++= alphabet[*str & 0x0F];
|
||||
*to++= _dig_vec[(*str & 0xF0) >> 4];
|
||||
*to++= _dig_vec[*str & 0x0F];
|
||||
}
|
||||
*to++= '\0';
|
||||
*to= '\0';
|
||||
}
|
||||
|
||||
|
||||
@ -341,15 +338,14 @@ octet2hex(char *to, const uint8 *str, uint len)
|
||||
overlap; len % 2 == 0
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
static void
|
||||
hex2octet(uint8 *to, const char *str, uint len)
|
||||
{
|
||||
const char *str_end= str + len;
|
||||
while (str < str_end)
|
||||
{
|
||||
*to= char_val(*str++) << 4;
|
||||
*to++|= char_val(*str++);
|
||||
register char tmp= char_val(*str++);
|
||||
*to++= (tmp << 4) | char_val(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,9 +362,8 @@ hex2octet(uint8 *to, const char *str, uint len)
|
||||
len IN length of s1 and s2
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
my_crypt(char *to, const uint8 *s1, const uint8 *s2, uint len)
|
||||
static void
|
||||
my_crypt(char *to, const uchar *s1, const uchar *s2, uint len)
|
||||
{
|
||||
const uint8 *s1_end= s1 + len;
|
||||
while (s1 < s1_end)
|
||||
@ -447,7 +442,7 @@ scramble(char *to, const char *message, const char *password)
|
||||
sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
|
||||
/* xor allows 'from' and 'to' overlap: lets take advantage of it */
|
||||
sha1_result(&sha1_context, (uint8 *) to);
|
||||
my_crypt(to, (const uint8 *) to, hash_stage1, SCRAMBLE_LENGTH);
|
||||
my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
@ -459,11 +454,13 @@ scramble(char *to, const char *message, const char *password)
|
||||
long (if not, something fishy is going on).
|
||||
SYNOPSIS
|
||||
check_scramble()
|
||||
scramble IN clients' reply, presumably produced by scramble()
|
||||
message IN original random string, previously sent to client
|
||||
(presumably second argument of scramble()), must be
|
||||
exactly SCRAMBLE_LENGTH long and NULL-terminated.
|
||||
hash_stage2 IN hex2octet-decoded database entry
|
||||
scramble clients' reply, presumably produced by scramble()
|
||||
message original random string, previously sent to client
|
||||
(presumably second argument of scramble()), must be
|
||||
exactly SCRAMBLE_LENGTH long and NULL-terminated.
|
||||
hash_stage2 hex2octet-decoded database entry
|
||||
All params are IN.
|
||||
|
||||
RETURN VALUE
|
||||
0 password is correct
|
||||
!0 password is invalid
|
||||
@ -483,7 +480,7 @@ check_scramble(const char *scramble, const char *message,
|
||||
sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
|
||||
sha1_result(&sha1_context, buf);
|
||||
/* encrypt scramble */
|
||||
my_crypt((char *) buf, buf, (const uint8 *) scramble, SCRAMBLE_LENGTH);
|
||||
my_crypt((char *) buf, buf, (const uchar *) scramble, SCRAMBLE_LENGTH);
|
||||
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
|
||||
sha1_reset(&sha1_context);
|
||||
sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
|
||||
|
@ -348,6 +348,25 @@ send_eof(THD *thd, bool no_flush)
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Please client to send scrambled_password in old format.
|
||||
SYNOPSYS
|
||||
send_old_password_request()
|
||||
thd thread handle
|
||||
|
||||
RETURN VALUE
|
||||
0 ok
|
||||
!0 error
|
||||
*/
|
||||
|
||||
bool send_old_password_request(THD *thd)
|
||||
{
|
||||
static char buff[1]= { (char) 254 };
|
||||
NET *net= &thd->net;
|
||||
return my_net_write(net, buff, 1) || net_flush(net);
|
||||
}
|
||||
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
|
@ -164,6 +164,7 @@ void net_printf(THD *thd,uint sql_errno, ...);
|
||||
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
|
||||
const char *info=0);
|
||||
void send_eof(THD *thd, bool no_flush=0);
|
||||
bool send_old_password_request(THD *thd);
|
||||
char *net_store_length(char *packet,ulonglong length);
|
||||
char *net_store_length(char *packet,uint length);
|
||||
char *net_store_data(char *to,const char *from, uint length);
|
||||
|
@ -264,10 +264,11 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
||||
{
|
||||
switch (password_len) {
|
||||
case 45: /* 4.1: to be removed */
|
||||
sql_print_error("Found 4.1 style password for user '%s'. "
|
||||
sql_print_error("Found 4.1 style password for user '%s@%s'. "
|
||||
"Ignoring user. "
|
||||
"You should change password for this user.",
|
||||
user.user ? user.user : "");
|
||||
user.user ? user.user : "",
|
||||
user.host.hostname ? user.host.hostname : "");
|
||||
break;
|
||||
default:
|
||||
sql_print_error("Found invalid password for user: '%s@%s'; "
|
||||
@ -526,23 +527,30 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
||||
/*
|
||||
Seek ACL entry for a user, check password, SSL cypher, and if
|
||||
everything is OK, update THD user data and USER_RESOURCES struct.
|
||||
|
||||
IMPLEMENTATION
|
||||
This function does not check if the user has any sensible privileges:
|
||||
only user's existence and validity is checked.
|
||||
Note, that entire operation is protected by acl_cache_lock.
|
||||
|
||||
SYNOPSIS
|
||||
thd INOUT thread handle. If all checks are OK,
|
||||
thd->priv_user, thd->master_access are updated.
|
||||
thd->host, thd->ip, thd->user are used for checks.
|
||||
mqh OUT user resources; on success mqh is reset, else
|
||||
unchanged
|
||||
passwd IN scrambled & crypted password, recieved from client
|
||||
(to check): thd->scramble or thd->scramble_323 is
|
||||
used to decrypt passwd, so they must contain
|
||||
original random string,
|
||||
passwd_len IN length of passwd, must be one of 0, 8,
|
||||
SCRAMBLE_LENGTH_323, SCRAMBLE_LENGTH
|
||||
acl_getroot()
|
||||
thd thread handle. If all checks are OK,
|
||||
thd->priv_user, thd->master_access are updated.
|
||||
thd->host, thd->ip, thd->user are used for checks.
|
||||
mqh user resources; on success mqh is reset, else
|
||||
unchanged
|
||||
passwd scrambled & crypted password, recieved from client
|
||||
(to check): thd->scramble or thd->scramble_323 is
|
||||
used to decrypt passwd, so they must contain
|
||||
original random string,
|
||||
passwd_len length of passwd, must be one of 0, 8,
|
||||
SCRAMBLE_LENGTH_323, SCRAMBLE_LENGTH
|
||||
'thd' and 'mqh' are updated on success; other params are IN.
|
||||
|
||||
RETURN VALUE
|
||||
0 success: thread data and mqh are updated
|
||||
0 success: thd->priv_user, thd->priv_host, thd->master_access, mqh are
|
||||
updated
|
||||
1 user not found or authentification failure
|
||||
2 user found, has long (4.1.1) salt, but passwd is in old (3.23) format.
|
||||
-1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format.
|
||||
@ -553,9 +561,16 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
|
||||
{
|
||||
DBUG_ENTER("acl_getroot");
|
||||
|
||||
if (!initialized) /* if no data allow anything */
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
if (!initialized)
|
||||
{
|
||||
/*
|
||||
here if mysqld's been started with --skip-grant-tables option.
|
||||
*/
|
||||
thd->priv_user= (char *) ""; // privileges for
|
||||
*thd->priv_host= '\0'; // the user are unknown
|
||||
thd->master_access= ~NO_ACCESS; // everything is allowed
|
||||
bzero(mqh, sizeof(*mqh));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int res= 1;
|
||||
@ -582,7 +597,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
|
||||
if (user_i->salt_len == 0 ||
|
||||
user_i->salt_len == SCRAMBLE_LENGTH &&
|
||||
check_scramble(passwd, thd->scramble, user_i->salt) == 0 ||
|
||||
check_scramble_323(passwd, thd->scramble_323,
|
||||
check_scramble_323(passwd, thd->scramble,
|
||||
(ulong *) user_i->salt) == 0)
|
||||
{
|
||||
acl_user= user_i;
|
||||
@ -1346,8 +1361,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
{
|
||||
int error = -1;
|
||||
bool old_row_exists=0;
|
||||
char empty_string[]= { '\0' };
|
||||
char *password= empty_string;
|
||||
const char *password= "";
|
||||
uint password_len= 0;
|
||||
char what= (revoke_grant) ? 'N' : 'Y';
|
||||
DBUG_ENTER("replace_user_table");
|
||||
|
@ -547,13 +547,7 @@ public:
|
||||
DYNAMIC_ARRAY user_var_events;
|
||||
|
||||
/* scramble - random string sent to client on handshake */
|
||||
char scramble[SCRAMBLE_LENGTH+1];
|
||||
/*
|
||||
The same as scramble but for old password checking routines. It always
|
||||
contains first N bytes of scramble.
|
||||
See check_connection() at sql_parse.cc for authentification details.
|
||||
*/
|
||||
char scramble_323[SCRAMBLE_LENGTH_323+1];
|
||||
char scramble[max(SCRAMBLE_LENGTH, SCRAMBLE_LENGTH_323)+1];
|
||||
|
||||
uint8 query_cache_type; // type of query cache processing
|
||||
bool slave_thread;
|
||||
|
@ -32,7 +32,7 @@
|
||||
SQL_CRYPT::SQL_CRYPT(const char *password)
|
||||
{
|
||||
ulong rand_nr[2];
|
||||
hash_password(rand_nr,password);
|
||||
hash_password(rand_nr,password, strlen(password));
|
||||
crypt_init(rand_nr);
|
||||
}
|
||||
|
||||
|
@ -181,17 +181,20 @@ end:
|
||||
Check if user exist and password supplied is correct.
|
||||
SYNOPSIS
|
||||
check_user()
|
||||
thd INOUT thread handle, thd->{host,user,ip} are used
|
||||
command IN originator of the check: now check_user is called
|
||||
during connect and change user procedures; used for
|
||||
logging.
|
||||
passwd IN scrambled password recieved from client
|
||||
passwd_len IN length of scrambled password
|
||||
db IN database name to connect to, may be NULL
|
||||
check_count IN dont know exactly
|
||||
thd thread handle, thd->{host,user,ip} are used
|
||||
command originator of the check: now check_user is called
|
||||
during connect and change user procedures; used for
|
||||
logging.
|
||||
passwd scrambled password recieved from client
|
||||
passwd_len length of scrambled password
|
||||
db database name to connect to, may be NULL
|
||||
check_count dont know exactly
|
||||
|
||||
Note, that host, user and passwd may point to communication buffer.
|
||||
Current implementation does not depened on that, but future changes
|
||||
should be done with this in mind.
|
||||
should be done with this in mind; 'thd' is INOUT, all other params
|
||||
are 'IN'.
|
||||
|
||||
RETURN VALUE
|
||||
0 OK; thd->user, thd->master_access, thd->priv_user, thd->db and
|
||||
thd->db_access are updated; OK is sent to client;
|
||||
@ -226,8 +229,10 @@ static int check_user(THD *thd, enum enum_server_command command,
|
||||
DBUG_RETURN(ER_HANDSHAKE_ERROR);
|
||||
|
||||
/*
|
||||
Why this is set here? - probably to reset current DB to 'no database
|
||||
selected' in case of 'change user' failure.
|
||||
Clear thd->db as it points to something, that will be freed when
|
||||
connection is closed. We don't want to accidently free a wrong pointer
|
||||
if connect failed. Also in case of 'CHANGE USER' failure, current
|
||||
database will be switched to 'no database selected'.
|
||||
*/
|
||||
thd->db= 0;
|
||||
thd->db_length= 0;
|
||||
@ -244,6 +249,7 @@ static int check_user(THD *thd, enum enum_server_command command,
|
||||
scramble_323()). Here we please client to send scrambled_password
|
||||
in old format.
|
||||
*/
|
||||
NET *net= &thd->net;
|
||||
if (opt_secure_auth_local)
|
||||
{
|
||||
net_printf(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
|
||||
@ -258,9 +264,7 @@ static int check_user(THD *thd, enum enum_server_command command,
|
||||
strmake(buff, db, NAME_LEN);
|
||||
db= buff;
|
||||
}
|
||||
NET *net= &thd->net;
|
||||
if (my_net_write(net, thd->scramble_323, SCRAMBLE_LENGTH_323 + 1) ||
|
||||
net_flush(net) ||
|
||||
if (send_old_password_request(thd) ||
|
||||
my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) // We have to read very
|
||||
{ // specific packet size
|
||||
inc_host_errors(&thd->remote.sin_addr);
|
||||
@ -288,7 +292,7 @@ static int check_user(THD *thd, enum enum_server_command command,
|
||||
{
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
bool count_ok= thread_count < max_connections + delayed_insert_threads
|
||||
|| thd->master_access & SUPER_ACL;
|
||||
|| (thd->master_access & SUPER_ACL);
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
if (!count_ok)
|
||||
{ // too many connections
|
||||
@ -305,7 +309,11 @@ static int check_user(THD *thd, enum enum_server_command command,
|
||||
thd->user, thd->host_or_ip,
|
||||
db ? db : (char*) "");
|
||||
|
||||
/* Why is it set here? */
|
||||
/*
|
||||
This is the default access rights for the current database. It's
|
||||
set to 0 here because we don't have an active database yet (and we
|
||||
may not have an active database to set.
|
||||
*/
|
||||
thd->db_access=0;
|
||||
|
||||
/* Don't allow user to connect if he has done too many queries */
|
||||
@ -554,9 +562,10 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
|
||||
Perform handshake, authorize client and update thd ACL variables.
|
||||
SYNOPSIS
|
||||
check_connection()
|
||||
thd INOUT thread handle
|
||||
thd thread handle
|
||||
|
||||
RETURN
|
||||
0 success, OK is sent to user
|
||||
0 success, OK is sent to user, thd is updated.
|
||||
-1 error, which is sent to user
|
||||
> 0 error code (not sent to user)
|
||||
*/
|
||||
@ -644,14 +653,12 @@ check_connection(THD *thd)
|
||||
each handshake.
|
||||
*/
|
||||
create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
|
||||
strmake(thd->scramble_323, thd->scramble, SCRAMBLE_LENGTH_323);
|
||||
|
||||
/*
|
||||
Old clients does not understand long scrambles, but can ignore packet
|
||||
tail: that's why first part of the scramble is placed here, and second
|
||||
part at the end of packet.
|
||||
*/
|
||||
end= strmake(end, thd->scramble_323, SCRAMBLE_LENGTH_323) + 1;
|
||||
end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
|
||||
|
||||
int2store(end, client_flags);
|
||||
/* write server characteristics: up to 16 bytes allowed */
|
||||
@ -754,8 +761,6 @@ check_connection(THD *thd)
|
||||
return(ER_HANDSHAKE_ERROR);
|
||||
}
|
||||
|
||||
/* why has it been put here? */
|
||||
|
||||
if (thd->client_capabilities & CLIENT_INTERACTIVE)
|
||||
thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
|
||||
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
|
||||
@ -778,9 +783,8 @@ check_connection(THD *thd)
|
||||
|
||||
if (thd->user)
|
||||
x_free(thd->user);
|
||||
thd->user= my_strdup(user, MYF(0));
|
||||
if (!thd->user)
|
||||
return(ER_OUT_OF_RESOURCES);
|
||||
if (!(thd->user= my_strdup(user, MYF(0))))
|
||||
return (ER_OUT_OF_RESOURCES);
|
||||
return check_user(thd, COM_CONNECT, passwd, passwd_len, db, true);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user