summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorkostja@oak.local <>2003-07-04 20:52:04 +0400
committerkostja@oak.local <>2003-07-04 20:52:04 +0400
commit1d20b23247e19aa6aa5e309fc47d5c5c3bbfe433 (patch)
tree8b19a2b1b84bfe2fb3f99f403acec7fb0a600501 /sql
parent7df0475847103581798ddacf75dbf634e8f98d0a (diff)
downloadmariadb-git-1d20b23247e19aa6aa5e309fc47d5c5c3bbfe433.tar.gz
Bug fixes for authentication
OLD_PASSWORD made a keyword to allow set password=old_password('abc') constructions.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_create.cc12
-rw-r--r--sql/item_create.h2
-rw-r--r--sql/item_strfunc.cc16
-rw-r--r--sql/item_strfunc.h3
-rw-r--r--sql/lex.h2
-rw-r--r--sql/password.c12
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_parse.cc250
-rw-r--r--sql/sql_yacc.yy37
9 files changed, 170 insertions, 173 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 90f42cee959..fbb26e83dfd 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -52,13 +52,6 @@ Item *create_func_ord(Item* a)
return new Item_func_ord(a);
}
-Item *create_func_old_password(Item* a)
-{
- return new Item_func_old_password(a);
-}
-
-
-
Item *create_func_asin(Item* a)
{
return new Item_func_asin(a);
@@ -332,11 +325,6 @@ Item *create_func_quarter(Item* a)
return new Item_func_quarter(a);
}
-Item *create_func_password(Item* a)
-{
- return new Item_func_password(a);
-}
-
Item *create_func_radians(Item *a)
{
return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
diff --git a/sql/item_create.h b/sql/item_create.h
index 4151f59a87f..2872451c034 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -69,14 +69,12 @@ Item *create_func_monthname(Item* a);
Item *create_func_nullif(Item* a, Item *b);
Item *create_func_oct(Item *);
Item *create_func_ord(Item* a);
-Item *create_func_old_password(Item* a);
Item *create_func_period_add(Item* a, Item *b);
Item *create_func_period_diff(Item* a, Item *b);
Item *create_func_pi(void);
Item *create_func_pow(Item* a, Item *b);
Item *create_func_current_user(void);
Item *create_func_quarter(Item* a);
-Item *create_func_password(Item* a);
Item *create_func_radians(Item *a);
Item *create_func_release_lock(Item* a);
Item *create_func_repeat(Item* a, Item *b);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f8488565b75..def465363fe 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1360,6 +1360,14 @@ String *Item_func_password::val_str(String *str)
return str;
}
+char *Item_func_password::alloc(THD *thd, const char *password)
+{
+ char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
+ if (buff)
+ make_scrambled_password(buff, password);
+ return buff;
+}
+
/* Item_func_old_password */
String *Item_func_old_password::val_str(String *str)
@@ -1374,6 +1382,14 @@ String *Item_func_old_password::val_str(String *str)
return str;
}
+char *Item_func_old_password::alloc(THD *thd, const char *password)
+{
+ char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
+ if (buff)
+ make_scrambled_password_323(buff, password);
+ return buff;
+}
+
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 11f5a66b3d1..3e0239cf76a 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -270,6 +270,7 @@ public:
String *val_str(String *str);
void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; }
const char *func_name() const { return "password"; }
+ static char *alloc(THD *thd, const char *password);
};
@@ -288,7 +289,7 @@ public:
String *val_str(String *str);
void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; }
const char *func_name() const { return "old_password"; }
- unsigned int size_of() { return sizeof(*this);}
+ static char *alloc(THD *thd, const char *password);
};
diff --git a/sql/lex.h b/sql/lex.h
index bb6e7a81ab4..f105fd4d9c8 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -284,6 +284,7 @@ static SYMBOL symbols[] = {
{ "NULL", SYM(NULL_SYM),0,0},
{ "NUMERIC", SYM(NUMERIC_SYM),0,0},
{ "OFFSET", SYM(OFFSET_SYM),0,0},
+ { "OLD_PASSWORD", SYM(OLD_PASSWORD),0,0},
{ "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0},
@@ -577,7 +578,6 @@ static SYMBOL sql_functions[] = {
{ "NUMPOINTS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numpoints)},
{ "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
{ "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)},
- { "OLD_PASSWORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_old_password)},
{ "ORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)},
{ "OVERLAPS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_overlaps)},
{ "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)},
diff --git a/sql/password.c b/sql/password.c
index be6514d89c6..bfdb453af01 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -446,22 +446,20 @@ make_scrambled_password(char *to, const char *password)
Produce an obscure octet sequence from password and random
string, recieved from the server. This sequence corresponds to the
password, but password can not be easily restored from it. The sequence
- is then sent to the server for validation. Trailing zero is stored in
- the buf.
+ is then sent to the server for validation. Trailing zero is not stored
+ in the buf as it is not needed.
This function is used by client to create authenticated reply to the
server's greeting.
SYNOPSIS
scramble()
buf OUT store scrambled string here. The buf must be at least
- SHA1_HASH_SIZE+1 bytes long.
+ SHA1_HASH_SIZE bytes long.
message IN random message, must be exactly SCRAMBLE_LENGTH long and
NULL-terminated.
password IN users' password
- RETURN VALUE
- end of scrambled string
*/
-char *
+void
scramble(char *to, const char *message, const char *password)
{
SHA1_CONTEXT sha1_context;
@@ -483,8 +481,6 @@ scramble(char *to, const char *message, const char *password)
/* 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);
- to[SHA1_HASH_SIZE]= '\0';
- return to + SHA1_HASH_SIZE;
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index bbc6b74c3a9..f88799c2843 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -51,7 +51,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length,
return (byte*) entry->key;
}
-#define ACL_KEY_LENGTH (sizeof(long)+NAME_LEN+17)
+#define ACL_KEY_LENGTH (sizeof(long)+NAME_LEN+USERNAME_LENGTH+1)
static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
static MEM_ROOT mem, memex;
@@ -208,7 +208,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
DBUG_PRINT("info",("user table fields: %d, password length: %d",
table->fields, table->field[2]->field_length));
- if (table->field[2]->field_length < 41 && !use_old_passwords)
+ if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH &&
+ !use_old_passwords)
{
sql_print_error("mysql.user table is not updated to new password format; "
"Disabling new password usage until "
@@ -516,6 +517,7 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
RETURN VALUE
0 success: thread data and 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.
*/
@@ -564,6 +566,9 @@ acl_getroot(THD *thd, USER_RESOURCES *mqh,
else if (passwd_len == SCRAMBLE_LENGTH &&
user_i->salt_len == SCRAMBLE_LENGTH_323)
res= -1;
+ else if (passwd_len == SCRAMBLE_LENGTH_323 &&
+ user_i->salt_len == SCRAMBLE_LENGTH)
+ res= 2;
/* linear search complete: */
break;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 384ec2bd4dd..a6d3121158c 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -195,11 +195,8 @@ end:
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;
- 1 access denied or internal error; error is sent to client
- Note, that this return semantics differs from check_connection,
- which returns -1 if message was already sent.
- -1 acl entry for this user contains old scramble, but passwd contains
- new one, error is not sent to client
+ -1 access denied or handshake error; error is sent to client;
+ >0 error, not sent to client
*/
static int check_user(THD *thd, enum enum_server_command command,
@@ -208,87 +205,129 @@ static int check_user(THD *thd, enum enum_server_command command,
{
DBUG_ENTER("check_user");
+ if (passwd_len != 0 &&
+ passwd_len != SCRAMBLE_LENGTH &&
+ passwd_len != SCRAMBLE_LENGTH_323)
+ 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.
*/
thd->db= 0;
thd->db_length= 0;
-
+
+ char buff[NAME_LEN + 1]; /* to conditionally save db */
+
USER_RESOURCES ur;
int res= acl_getroot(thd, &ur, passwd, passwd_len,
protocol_version == 9 ||
!(thd->client_capabilities & CLIENT_LONG_PASSWORD));
- if (res == 0 && !(thd->master_access & NO_ACCESS)) // authentification is OK
+ if (res == -1)
{
- DBUG_PRINT("info",
- ("Capabilities: %d packet_length: %ld Host: '%s' "
- "Login user: '%s' Priv_user: '%s' Using password: %s "
- "Access: %u db: '%s'",
- thd->client_capabilities, thd->max_client_packet_length,
- thd->host_or_ip, thd->user, thd->priv_user,
- passwd_len ? "yes": "no",
- thd->master_access, thd->db ? thd->db : "*none*"));
-
- if (check_count)
+ /*
+ This happens when client (new) sends password scrambled with
+ scramble(), but database holds old value (scrambled with
+ scramble_323()). Here we please client to send scrambled_password
+ in old format.
+ */
+ /* save db because network buffer is to hold new packet */
+ if (db)
{
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- bool count_ok= thread_count < max_connections + delayed_insert_threads ||
- thd->master_access & SUPER_ACL;
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
- if (!count_ok)
- { // too many connections
- send_error(thd, ER_CON_COUNT_ERROR);
- DBUG_RETURN(1);
- }
+ 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) ||
+ my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) // We have to read very
+ { // specific packet size
+ inc_host_errors(&thd->remote.sin_addr);
+ DBUG_RETURN(ER_HANDSHAKE_ERROR);
}
+ /* Final attempt to check the user based on reply */
+ /* So as passwd is short, errcode is always >= 0 */
+ res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323,
+ false);
+ }
+ /* here res is always >= 0 */
+ if (res == 0)
+ {
+ if (!(thd->master_access & NO_ACCESS)) // authentification is OK
+ {
+ DBUG_PRINT("info",
+ ("Capabilities: %d packet_length: %ld Host: '%s' "
+ "Login user: '%s' Priv_user: '%s' Using password: %s "
+ "Access: %u db: '%s'",
+ thd->client_capabilities, thd->max_client_packet_length,
+ thd->host_or_ip, thd->user, thd->priv_user,
+ passwd_len ? "yes": "no",
+ thd->master_access, thd->db ? thd->db : "*none*"));
+
+ if (check_count)
+ {
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ bool count_ok= thread_count < max_connections + delayed_insert_threads
+ || thd->master_access & SUPER_ACL;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (!count_ok)
+ { // too many connections
+ send_error(thd, ER_CON_COUNT_ERROR);
+ DBUG_RETURN(-1);
+ }
+ }
- /* Why logging is performed before all checks've passed? */
- mysql_log.write(thd,command,
- (thd->priv_user == thd->user ?
- (char*) "%s@%s on %s" :
- (char*) "%s@%s as anonymous on %s"),
- thd->user, thd->host_or_ip,
- db ? db : (char*) "");
+ /* Why logging is performed before all checks've passed? */
+ mysql_log.write(thd,command,
+ (thd->priv_user == thd->user ?
+ (char*) "%s@%s on %s" :
+ (char*) "%s@%s as anonymous on %s"),
+ thd->user, thd->host_or_ip,
+ db ? db : (char*) "");
- /* Why is it set here? */
- thd->db_access=0;
+ /* Why is it set here? */
+ thd->db_access=0;
- /* Don't allow user to connect if he has done too many queries */
- if ((ur.questions || ur.updates || ur.connections) &&
- get_or_create_user_conn(thd,thd->user,thd->host_or_ip,&ur))
- DBUG_RETURN(1);
- if (thd->user_connect && thd->user_connect->user_resources.connections &&
- check_for_max_user_connections(thd, thd->user_connect))
- DBUG_RETURN(1);
+ /* Don't allow user to connect if he has done too many queries */
+ if ((ur.questions || ur.updates || ur.connections) &&
+ get_or_create_user_conn(thd,thd->user,thd->host_or_ip,&ur))
+ DBUG_RETURN(1);
+ if (thd->user_connect && thd->user_connect->user_resources.connections &&
+ check_for_max_user_connections(thd, thd->user_connect))
+ DBUG_RETURN(1);
- /* Change database if necessary: OK or FAIL is sent in mysql_change_db */
- if (db && db[0])
- {
- if (mysql_change_db(thd, db))
+ /* Change database if necessary: OK or FAIL is sent in mysql_change_db */
+ if (db && db[0])
{
- if (thd->user_connect)
- decrease_user_connections(thd->user_connect);
- DBUG_RETURN(1);
+ if (mysql_change_db(thd, db))
+ {
+ if (thd->user_connect)
+ decrease_user_connections(thd->user_connect);
+ DBUG_RETURN(-1);
+ }
}
+ else
+ send_ok(thd);
+ thd->password= test(passwd_len); // remember for error messages
+ /* Ready to handle queries */
+ DBUG_RETURN(0);
}
- else
- send_ok(thd);
- thd->password= test(passwd_len); // remember for error messages
- /* Ready to handle queries */
}
- else if (res != -1) // authentication failure
+ else if (res == 2) // client gave short hash, server has long hash
{
- net_printf(thd, ER_ACCESS_DENIED_ERROR,
- thd->user,
- thd->host_or_ip,
- passwd_len ? ER(ER_YES) : ER(ER_NO));
- mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
- thd->user,
- thd->host_or_ip,
- passwd_len ? ER(ER_YES) : ER(ER_NO));
+ net_printf(thd, ER_NOT_SUPPORTED_AUTH_MODE);
+ mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ DBUG_RETURN(-1);
}
- DBUG_RETURN(res);
+ net_printf(thd, ER_ACCESS_DENIED_ERROR,
+ thd->user,
+ thd->host_or_ip,
+ passwd_len ? ER(ER_YES) : ER(ER_NO));
+ mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
+ thd->user,
+ thd->host_or_ip,
+ passwd_len ? ER(ER_YES) : ER(ER_NO));
+ DBUG_RETURN(-1);
}
/*
@@ -492,60 +531,6 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
/*
- Perform check for scrambled password, re-request scrambled password
- from client if necessary. See also help for check_user.
- SYNOPSIS
- authenticate()
- RETURN VALUE
- 0 success, OK sent to client
- -1 error, sent to client
- > 0 error, not sent to client
-*/
-
-static
-int
-authenticate(THD *thd, enum enum_server_command command,
- const char *passwd, uint passwd_len, const char *db,
- bool check_count)
-{
- if (passwd_len != 0 &&
- passwd_len != SCRAMBLE_LENGTH &&
- passwd_len != SCRAMBLE_LENGTH_323)
- return 1;
- int res= check_user(thd, COM_CONNECT, passwd, passwd_len, db, check_count);
- if (res < 0)
- {
- /*
- This happens when client (new) sends password scrambled with
- scramble(), but database holds old value (scrambled with
- scramble_323()). Here we please client to send scrambled_password
- in old format.
- */
- char buff[NAME_LEN + 1];
- /* save db because network buffer is to hold new packet */
- if (db)
- {
- 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) ||
- my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) // We have to read very
- { // specific packet size
- inc_host_errors(&thd->remote.sin_addr);
- return ER_HANDSHAKE_ERROR;
- }
- /* Final attempt to check the user based on reply */
- /* So as passwd is short, errcode is always sent to user and res >= 0 */
- res= check_user(thd, COM_CONNECT, (char *) net->read_pos,
- SCRAMBLE_LENGTH_323, db, check_count);
- }
- return res > 0 ? -1 : 0;
-}
-
-
-/*
Perform handshake, authorize client and update thd ACL variables.
SYNOPSIS
check_connection()
@@ -643,7 +628,7 @@ check_connection(THD *thd)
/*
Old clients does not understand long scrambles, but can ignore packet
- tail: that's why first part of scramble is placed here, and second
+ 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;
@@ -760,17 +745,23 @@ check_connection(THD *thd)
char *user= end;
char *passwd= strend(user)+1;
- uint passwd_len= strlen(passwd);
-
- char *db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
- passwd+passwd_len+1 : 0;
+ char *db= passwd;
+ /*
+ Old clients send null-terminated string as password; new clients send
+ the size (1 byte) + string (not null-terminated). Hence in case of empty
+ password both send '\0'.
+ */
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd);
+ db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
+ db + passwd_len + 1 : 0;
if (thd->user)
x_free(thd->user);
thd->user= my_strdup(user, MYF(0));
if (!thd->user)
return(ER_OUT_OF_RESOURCES);
- return authenticate(thd, COM_CONNECT, passwd, passwd_len, db, true);
+ return check_user(thd, COM_CONNECT, passwd, passwd_len, db, true);
}
@@ -1137,8 +1128,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(com_other, &LOCK_status);
char *user= (char*) packet;
char *passwd= strend(user)+1;
- uint passwd_len= strlen(passwd);
- char *db= passwd + passwd_len + 1;
+ /*
+ Old clients send null-terminated string ('\0' for empty string) for
+ password. New clients send the size (1 byte) + string (not null
+ terminated, so also '\0' for empty string).
+ */
+ char *db= passwd;
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd);
+ db+= passwd_len + 1;
/* Small check for incomming packet */
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
@@ -1163,7 +1161,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
}
- int res= authenticate(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
+ int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
if (res)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c8c9eb97a6a..ddf4b71e891 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -493,6 +493,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MULTIPOINT
%token MULTIPOLYGON
%token NOW_SYM
+%token OLD_PASSWORD
%token PASSWORD
%token POINTFROMTEXT
%token POINT_SYM
@@ -2516,9 +2517,11 @@ simple_expr:
{ $$= new Item_func_now($3); Lex->safe_to_cache_query=0;}
| PASSWORD '(' expr ')'
{
- $$= use_old_passwords ? (Item *) new Item_func_old_password($3) :
- (Item *) new Item_func_password($3);
- }
+ $$= use_old_passwords ? (Item *) new Item_func_old_password($3) :
+ (Item *) new Item_func_password($3);
+ }
+ | OLD_PASSWORD '(' expr ')'
+ { $$= new Item_func_old_password($3); }
| POINT_SYM '(' expr ',' expr ')'
{ $$= new Item_func_point($3,$5); }
| POINTFROMTEXT '(' expr ')'
@@ -4412,6 +4415,7 @@ keyword:
| NO_SYM {}
| NONE_SYM {}
| OFFSET_SYM {}
+ | OLD_PASSWORD {}
| OPEN_SYM {}
| PACK_KEYS_SYM {}
| PARTIAL {}
@@ -4603,24 +4607,15 @@ text_or_password:
TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')'
{
- if (!$3.length)
- $$=$3.str;
- else if (use_old_passwords)
- {
- char *buff= (char *)
- YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
- if (buff)
- make_scrambled_password_323(buff, $3.str);
- $$=buff;
- }
- else
- {
- char *buff= (char *)
- YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
- if (buff)
- make_scrambled_password(buff, $3.str);
- $$=buff;
- }
+ $$= $3.length ? use_old_passwords ?
+ Item_func_old_password::alloc(YYTHD, $3.str) :
+ Item_func_password::alloc(YYTHD, $3.str) :
+ $3.str;
+ }
+ | OLD_PASSWORD '(' TEXT_STRING ')'
+ {
+ $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str) :
+ $3.str;
}
;