summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorserg@serg.mylan <>2004-07-19 16:01:53 +0200
committerserg@serg.mylan <>2004-07-19 16:01:53 +0200
commitacfcf762281260f1000c0feb959690c8828edb73 (patch)
tree1a04f04660802f1326a84b98226f5d93312cff90
parent5eadafe56960a5df27007ae382c1c5445cc1ed9a (diff)
downloadmariadb-git-acfcf762281260f1000c0feb959690c8828edb73.tar.gz
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
-rw-r--r--sql/sql_acl.cc48
1 files changed, 32 insertions, 16 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index fa8065a5fc3..fddd5b70a2f 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -64,7 +64,7 @@ static DYNAMIC_ARRAY acl_wild_hosts;
static hash_filo *acl_cache;
static uint grant_version=0;
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 ulong get_sort(uint count,...);
static void init_check_host(void);
@@ -299,13 +299,14 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
}
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.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0);
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)
user.ssl_type=SSL_TYPE_NONE;
else if (!strcmp(ssl_type, "ANY"))
@@ -315,16 +316,16 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
else /* !strcmp(ssl_type, "SPECIFIED") */
user.ssl_type=SSL_TYPE_SPECIFIED;
- user.ssl_cipher= get_field(&mem, table->field[25]);
- user.x509_issuer= get_field(&mem, table->field[26]);
- user.x509_subject= get_field(&mem, table->field[27]);
+ user.ssl_cipher= get_field(&mem, table->field[next_field++]);
+ user.x509_issuer= get_field(&mem, table->field[next_field++]);
+ user.x509_subject= get_field(&mem, table->field[next_field++]);
- char *ptr = get_field(&mem, table->field[28]);
- user.user_resource.questions=atoi(ptr);
- ptr = get_field(&mem, table->field[29]);
- user.user_resource.updates=atoi(ptr);
- ptr = get_field(&mem, table->field[30]);
- user.user_resource.connections=atoi(ptr);
+ char *ptr = get_field(&mem, table->field[next_field++]);
+ user.user_resource.questions=ptr ? atoi(ptr) : 0;
+ ptr = get_field(&mem, table->field[next_field++]);
+ user.user_resource.updates=ptr ? atoi(ptr) : 0;
+ ptr = get_field(&mem, table->field[next_field++]);
+ user.user_resource.connections=ptr ? atoi(ptr) : 0;
if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.connections)
mqh_used=1;
@@ -489,11 +490,24 @@ void acl_reload(THD *thd)
/*
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;
char buff[2];
@@ -503,12 +517,14 @@ static ulong get_access(TABLE *form, uint fieldnr)
for (pos=form->field+fieldnr, bit=1;
*pos && (*pos)->real_type() == FIELD_TYPE_ENUM &&
((Field_enum*) (*pos))->typelib->count == 2 ;
- pos++ , bit<<=1)
+ pos++, fieldnr++, bit<<=1)
{
(*pos)->val_str(&res);
if (my_toupper(&my_charset_latin1, res[0]) == 'Y')
access_bits|= bit;
}
+ if (next_field)
+ *next_field=fieldnr;
return access_bits;
}