Commit acfcf762 authored by serg@serg.mylan's avatar serg@serg.mylan

make acl_init() more robust -

  don't be confused if  new privilege - ENUM ('N','Y') - columns are added (mostly because of downgrade)
  don't expect NOT NULL fields to never contain a NULL :) - somebody may've changed table definition, or we may be reading the wrong column
parent 5eadafe5
...@@ -64,7 +64,7 @@ static DYNAMIC_ARRAY acl_wild_hosts; ...@@ -64,7 +64,7 @@ static DYNAMIC_ARRAY acl_wild_hosts;
static hash_filo *acl_cache; static hash_filo *acl_cache;
static uint grant_version=0; static uint grant_version=0;
static uint priv_version=0; /* Version of priv tables. incremented by acl_init */ static uint priv_version=0; /* Version of priv tables. incremented by acl_init */
static ulong get_access(TABLE *form,uint fieldnr); static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0);
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b); static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
static ulong get_sort(uint count,...); static ulong get_sort(uint count,...);
static void init_check_host(void); static void init_check_host(void);
...@@ -299,13 +299,14 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -299,13 +299,14 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
} }
else // password is correct else // password is correct
{ {
user.access= get_access(table,3) & GLOBAL_ACLS; uint next_field;
user.access= get_access(table,3,&next_field) & GLOBAL_ACLS;
user.sort= get_sort(2,user.host.hostname,user.user); user.sort= get_sort(2,user.host.hostname,user.user);
user.hostname_length= (user.host.hostname ? user.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0); (uint) strlen(user.host.hostname) : 0);
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */ if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
{ {
char *ssl_type=get_field(&mem, table->field[24]); char *ssl_type=get_field(&mem, table->field[next_field++]);
if (!ssl_type) if (!ssl_type)
user.ssl_type=SSL_TYPE_NONE; user.ssl_type=SSL_TYPE_NONE;
else if (!strcmp(ssl_type, "ANY")) else if (!strcmp(ssl_type, "ANY"))
...@@ -315,16 +316,16 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -315,16 +316,16 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
else /* !strcmp(ssl_type, "SPECIFIED") */ else /* !strcmp(ssl_type, "SPECIFIED") */
user.ssl_type=SSL_TYPE_SPECIFIED; user.ssl_type=SSL_TYPE_SPECIFIED;
user.ssl_cipher= get_field(&mem, table->field[25]); user.ssl_cipher= get_field(&mem, table->field[next_field++]);
user.x509_issuer= get_field(&mem, table->field[26]); user.x509_issuer= get_field(&mem, table->field[next_field++]);
user.x509_subject= get_field(&mem, table->field[27]); user.x509_subject= get_field(&mem, table->field[next_field++]);
char *ptr = get_field(&mem, table->field[28]); char *ptr = get_field(&mem, table->field[next_field++]);
user.user_resource.questions=atoi(ptr); user.user_resource.questions=ptr ? atoi(ptr) : 0;
ptr = get_field(&mem, table->field[29]); ptr = get_field(&mem, table->field[next_field++]);
user.user_resource.updates=atoi(ptr); user.user_resource.updates=ptr ? atoi(ptr) : 0;
ptr = get_field(&mem, table->field[30]); ptr = get_field(&mem, table->field[next_field++]);
user.user_resource.connections=atoi(ptr); user.user_resource.connections=ptr ? atoi(ptr) : 0;
if (user.user_resource.questions || user.user_resource.updates || if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.connections) user.user_resource.connections)
mqh_used=1; mqh_used=1;
...@@ -489,11 +490,24 @@ void acl_reload(THD *thd) ...@@ -489,11 +490,24 @@ void acl_reload(THD *thd)
/* /*
Get all access bits from table after fieldnr Get all access bits from table after fieldnr
We know that the access privileges ends when there is no more fields
or the field is not an enum with two elements. IMPLEMENTATION
We know that the access privileges ends when there is no more fields
or the field is not an enum with two elements.
SYNOPSIS
get_access()
form an open table to read privileges from.
The record should be already read in table->record[0]
fieldnr number of the first privilege (that is ENUM('N','Y') field
next_field on return - number of the field next to the last ENUM
(unless next_field == 0)
RETURN VALUE
privilege mask
*/ */
static ulong get_access(TABLE *form, uint fieldnr) static ulong get_access(TABLE *form, uint fieldnr, uint *next_field)
{ {
ulong access_bits=0,bit; ulong access_bits=0,bit;
char buff[2]; char buff[2];
...@@ -503,12 +517,14 @@ static ulong get_access(TABLE *form, uint fieldnr) ...@@ -503,12 +517,14 @@ static ulong get_access(TABLE *form, uint fieldnr)
for (pos=form->field+fieldnr, bit=1; for (pos=form->field+fieldnr, bit=1;
*pos && (*pos)->real_type() == FIELD_TYPE_ENUM && *pos && (*pos)->real_type() == FIELD_TYPE_ENUM &&
((Field_enum*) (*pos))->typelib->count == 2 ; ((Field_enum*) (*pos))->typelib->count == 2 ;
pos++ , bit<<=1) pos++, fieldnr++, bit<<=1)
{ {
(*pos)->val_str(&res); (*pos)->val_str(&res);
if (my_toupper(&my_charset_latin1, res[0]) == 'Y') if (my_toupper(&my_charset_latin1, res[0]) == 'Y')
access_bits|= bit; access_bits|= bit;
} }
if (next_field)
*next_field=fieldnr;
return access_bits; return access_bits;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment