diff options
-rw-r--r-- | include/mysql.h | 4 | ||||
-rw-r--r-- | include/mysql_com.h | 4 | ||||
-rw-r--r-- | libmysql/libmysql.c | 10 | ||||
-rw-r--r-- | sql-common/client.c | 13 | ||||
-rw-r--r-- | sql/password.c | 93 | ||||
-rw-r--r-- | sql/protocol.cc | 19 | ||||
-rw-r--r-- | sql/protocol.h | 1 | ||||
-rw-r--r-- | sql/sql_acl.cc | 54 | ||||
-rw-r--r-- | sql/sql_class.h | 8 | ||||
-rw-r--r-- | sql/sql_crypt.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 56 |
11 files changed, 148 insertions, 116 deletions
diff --git a/include/mysql.h b/include/mysql.h index bf05f6e8e37..079808d9ba7 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -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 diff --git a/include/mysql_com.h b/include/mysql_com.h index e5782235934..87cedafb93d 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -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); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index ee7fd6a2576..cec9980bae7 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -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; diff --git a/sql-common/client.c b/sql-common/client.c index 9a0b7eb3fe2..aac5be4b690 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -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; diff --git a/sql/password.c b/sql/password.c index 2e9139c12aa..16227aab611 100644 --- a/sql/password.c +++ b/sql/password.c @@ -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); diff --git a/sql/protocol.cc b/sql/protocol.cc index 1b9256c7723..7e009aa6a17 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -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 */ diff --git a/sql/protocol.h b/sql/protocol.h index ffd61b3e848..405d3d4aebe 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -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); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ee544335a99..fafe725201d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -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"); diff --git a/sql/sql_class.h b/sql/sql_class.h index e80b5d9c8d5..1557ede8305 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -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; diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc index 930ecfffef7..b0b8050e311 100644 --- a/sql/sql_crypt.cc +++ b/sql/sql_crypt.cc @@ -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); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7878f2c8a29..9d75029a997 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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); } |