the attached patch should do it!  it was constructed from the redhat
mysql patch, as well as a recent mysql changeset that i backported to
3.23.x (christian discovered the bugfix was buggy and didn't close the
hole).

the patch builds, the resulting deb installs, and i can no longer
reproduce the privilege escalation.


        sean

-- 
diff -Naru mysql.old/debian/changelog mysql-3.23.49/debian/changelog
--- mysql.old/debian/changelog  Tue Mar 29 04:10:50 2005
+++ mysql-3.23.49/debian/changelog      Tue Mar 29 04:15:58 2005
@@ -1,3 +1,12 @@
+mysql (3.23.49-8.10) stable-security; urgency=high
+
+  * NMU prepared for the security team by sean finney
+  * fix for CAN 2004-0957, using patches massaged together from
+    redhat's srpm patch and mysql's changesets.
+  * the patch is included in debian/patches for reference
+
+ -- sean finney <[EMAIL PROTECTED]>  Mon, 28 Mar 2005 23:15:39 -0500
+
 mysql (3.23.49-8.9) stable-security; urgency=high
 
   * Maintainer upload for the Security Team
diff -Naru 
mysql.old/debian/patches/SECURITY__CAN-2004-0957__db_underscore_grant.diff 
mysql-3.23.49/debian/patches/SECURITY__CAN-2004-0957__db_underscore_grant.diff
--- mysql.old/debian/patches/SECURITY__CAN-2004-0957__db_underscore_grant.diff  
Thu Jan  1 00:00:00 1970
+++ 
mysql-3.23.49/debian/patches/SECURITY__CAN-2004-0957__db_underscore_grant.diff  
    Tue Mar 29 04:13:01 2005
@@ -0,0 +1,287 @@
+diff -Naru mysql.old/include/my_sys.h mysql-3.23.49/include/my_sys.h
+--- mysql.old/include/my_sys.h Thu Feb 14 17:30:15 2002
++++ mysql-3.23.49/include/my_sys.h     Tue Mar 29 04:09:24 2005
+@@ -476,7 +476,7 @@
+                        const char *own_pathname_part);
+ extern my_string my_load_path(my_string to, const char *path,
+                             const char *own_path_prefix);
+-extern int wild_compare(const char *str,const char *wildstr);
++extern int wild_compare(const char *str,const char *wildstr,pbool 
str_is_pattern);
+ extern my_string my_strcasestr(const char *src,const char *suffix);
+ extern int my_strcasecmp(const char *s,const char *t);
+ extern int my_strsortcmp(const char *s,const char *t);
+diff -Naru mysql.old/mysys/mf_wcomp.c mysql-3.23.49/mysys/mf_wcomp.c
+--- mysql.old/mysys/mf_wcomp.c Thu Feb 14 17:30:15 2002
++++ mysql-3.23.49/mysys/mf_wcomp.c     Tue Mar 29 04:09:24 2005
+@@ -24,11 +24,12 @@
+ 
+ char wild_many='*';
+ char wild_one='?';
+-char wild_prefix=0;
++char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */
+ 
+-int wild_compare(register const char *str, register const char *wildstr)
++int wild_compare(register const char *str, register const char *wildstr,
++                 pbool str_is_pattern)
+ {
+-  reg3 int flag;
++  char cmp;
+   DBUG_ENTER("wild_compare");
+ 
+   while (*wildstr)
+@@ -36,33 +37,55 @@
+     while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
+     {
+       if (*wildstr == wild_prefix && wildstr[1])
++      {
+       wildstr++;
+-      if (*wildstr++ != *str++) DBUG_RETURN(1);
++        if (str_is_pattern && *str++ != wild_prefix)
++          DBUG_RETURN(1);
++      }
++      if (*wildstr++ != *str++)
++        DBUG_RETURN(1);
+     }
+-    if (! *wildstr ) DBUG_RETURN (*str != 0);
++    if (! *wildstr )
++      DBUG_RETURN(*str != 0);
+     if (*wildstr++ == wild_one)
+     {
+-      if (! *str++) DBUG_RETURN (1);  /* One char; skipp */
++      if (! *str || (str_is_pattern && *str == wild_many))
++        DBUG_RETURN(1);                     /* One char; skip */
++      if (*str++ == wild_prefix && str_is_pattern && *str)
++        str++;
+     }
+     else
+     {                                         /* Found '*' */
+-      if (!*wildstr) DBUG_RETURN(0);          /* '*' as last char: OK */
+-      flag=(*wildstr != wild_many && *wildstr != wild_one);
+-      do
++      while (str_is_pattern && *str == wild_many)
++        str++;
++      for (; *wildstr ==  wild_many || *wildstr == wild_one; wildstr++)
++        if (*wildstr == wild_many)
++        {
++          while (str_is_pattern && *str == wild_many)
++            str++;
++        }
++        else
++        {
++          if (str_is_pattern && *str == wild_prefix && str[1])
++            str+=2;
++          else if (! *str++)
++            DBUG_RETURN (1);
++        }
++      if (!*wildstr)
++        DBUG_RETURN(0);               /* '*' as last char: OK */
++      if ((cmp= *wildstr) == wild_prefix && wildstr[1] && !str_is_pattern)
++        cmp=wildstr[1];
++      for (;;str++)
+       {
+-      if (flag)
+-      {
+-        char cmp;
+-        if ((cmp= *wildstr) == wild_prefix && wildstr[1])
+-          cmp=wildstr[1];
+-        while (*str && *str != cmp)
+-          str++;
+-        if (!*str) DBUG_RETURN (1);
+-      }
+-      if (wild_compare(str,wildstr) == 0) DBUG_RETURN (0);
+-      } while (*str++ && wildstr[0] != wild_many);
+-      DBUG_RETURN(1);
++        while (*str && *str != cmp)
++          str++;
++        if (!*str)
++          DBUG_RETURN (1);
++      if (wild_compare(str,wildstr,str_is_pattern) == 0)
++          DBUG_RETURN (0);
++      }
++      /* We will never come here */
+     }
+   }
+-  DBUG_RETURN (*str != '\0');
++  DBUG_RETURN (*str != 0);
+ } /* wild_compare */
+diff -Naru mysql.old/mysys/mf_wfile.c mysql-3.23.49/mysys/mf_wfile.c
+--- mysql.old/mysys/mf_wfile.c Thu Feb 14 17:30:21 2002
++++ mysql-3.23.49/mysys/mf_wfile.c     Tue Mar 29 04:09:24 2005
+@@ -107,7 +107,7 @@
+ 
+   not_pos=wf_pack->not_pos;
+   for (i=0 ; i < not_pos; i++)
+-    if (wild_compare(name,wf_pack->wild[i]) == 0)
++    if (wild_compare(name,wf_pack->wild[i],0) == 0)
+       goto found;
+   if (i)
+     DBUG_RETURN(1);                   /* No-match */
+@@ -116,7 +116,7 @@
+ /* Test that it isn't in not-list */
+ 
+   for (i=not_pos ; i < wf_pack->wilds; i++)
+-    if (wild_compare(name,wf_pack->wild[i]) == 0)
++    if (wild_compare(name,wf_pack->wild[i],0) == 0)
+       DBUG_RETURN(1);
+   DBUG_RETURN(0);
+ } /* wf_test */
+diff -Naru mysql.old/sql/sql_acl.cc mysql-3.23.49/sql/sql_acl.cc
+--- mysql.old/sql/sql_acl.cc   Tue Mar 29 04:10:50 2005
++++ mysql-3.23.49/sql/sql_acl.cc       Tue Mar 29 04:09:24 2005
+@@ -563,10 +563,13 @@
+ 
+ /*****************************************************************************
+ ** Get privilege for a host, user and db combination
++
++  as db_is_pattern changes the semantics of comparison,
++  acl_cache is not used if db_is_pattern is set.
+ *****************************************************************************/
+ 
+ uint acl_get(const char *host, const char *ip, const char *bin_ip,
+-           const char *user, const char *db)
++           const char *user, const char *db, my_bool db_is_pattern)
+ {
+   uint host_access,db_access,i,key_length;
+   db_access=0; host_access= ~0;
+@@ -577,7 +580,7 @@
+   memcpy_fixed(&key,bin_ip,sizeof(struct in_addr));
+   end=strmov(strmov(key+sizeof(struct in_addr),user)+1,db);
+   key_length=(uint) (end-key);
+-  if ((entry=(acl_entry*) acl_cache->search(key,key_length)))
++  if (!db_is_pattern && (entry=(acl_entry*) 
acl_cache->search(key,key_length)))
+   {
+     db_access=entry->access;
+     VOID(pthread_mutex_unlock(&acl_cache->lock));
+@@ -594,7 +597,7 @@
+     {
+       if (compare_hostname(&acl_db->host,host,ip))
+       {
+-      if (!acl_db->db || !wild_compare(db,acl_db->db))
++      if (!acl_db->db || !wild_compare(db,acl_db->db,db_is_pattern))
+       {
+         db_access=acl_db->access;
+         if (acl_db->host.hostname)
+@@ -616,7 +619,7 @@
+     ACL_HOST *acl_host=dynamic_element(&acl_hosts,i,ACL_HOST*);
+     if (compare_hostname(&acl_host->host,host,ip))
+     {
+-      if (!acl_host->db || !wild_compare(db,acl_host->db))
++      if (!acl_host->db || !wild_compare(db,acl_host->db,0))
+       {
+       host_access=acl_host->access;           // Fully specified. Take it
+       break;
+@@ -625,7 +628,8 @@
+   }
+ exit:
+   /* Save entry in cache for quick retrieval */
+-  if ((entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
++  if (!db_is_pattern &&
++      (entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
+   {
+     entry->access=(db_access & host_access);
+     entry->length=key_length;
+@@ -897,7 +901,7 @@
+   }
+   return (!host->hostname ||
+         (hostname && !wild_case_compare(hostname,host->hostname)) ||
+-        (ip && !wild_compare(ip,host->hostname)));
++        (ip && !wild_compare(ip,host->hostname,0)));
+ }
+ 
+ 
+@@ -957,7 +961,7 @@
+     tl.db=       (char*) "mysql";
+     tl.real_name= (char*) "user";
+     db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
+-                    thd->priv_user, tl.db);
++                    thd->priv_user, tl.db, 0);
+     if (!(db_access & INSERT_ACL))
+     {
+       if (check_grant(thd,INSERT_ACL,&tl,0,1))
+diff -Naru mysql.old/sql/sql_acl.h mysql-3.23.49/sql/sql_acl.h
+--- mysql.old/sql/sql_acl.h    Thu Feb 14 17:30:23 2002
++++ mysql-3.23.49/sql/sql_acl.h        Tue Mar 29 04:09:24 2005
+@@ -58,7 +58,7 @@
+ void acl_reload(void);
+ void acl_free(bool end=0);
+ uint acl_get(const char *host, const char *ip, const char *bin_ip,
+-           const char *user, const char *db);
++           const char *user, const char *db, my_bool db_is_pattern);
+ uint acl_getroot(const char *host, const char *ip, const char *user,
+                const char *password,const char *scramble,char **priv_user,
+                bool old_ver);
+diff -Naru mysql.old/sql/sql_base.cc mysql-3.23.49/sql/sql_base.cc
+--- mysql.old/sql/sql_base.cc  Thu Feb 14 17:30:14 2002
++++ mysql-3.23.49/sql/sql_base.cc      Tue Mar 29 04:09:24 2005
+@@ -126,7 +126,7 @@
+     TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
+     if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
+       continue;
+-    if (wild && wild[0] && wild_compare(entry->real_name,wild))
++    if (wild && wild[0] && wild_compare(entry->real_name,wild,0))
+       continue;
+     if (db && !(col_access & TABLE_ACLS))
+     {
+diff -Naru mysql.old/sql/sql_db.cc mysql-3.23.49/sql/sql_db.cc
+--- mysql.old/sql/sql_db.cc    Thu Feb 14 17:30:16 2002
++++ mysql-3.23.49/sql/sql_db.cc        Tue Mar 29 04:09:24 2005
+@@ -329,7 +329,7 @@
+     db_access=DB_ACLS;
+   else
+     db_access= (acl_get(thd->host,thd->ip,(char*) &thd->remote.sin_addr,
+-                      thd->priv_user,dbname) |
++                      thd->priv_user,dbname,0) |
+               thd->master_access);
+   if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
+   {
+diff -Naru mysql.old/sql/sql_parse.cc mysql-3.23.49/sql/sql_parse.cc
+--- mysql.old/sql/sql_parse.cc Tue Mar 29 04:10:50 2005
++++ mysql-3.23.49/sql/sql_parse.cc     Tue Mar 29 04:09:24 2005
+@@ -2138,7 +2138,7 @@
+   
+   if (db && (!thd->db || strcmp(db,thd->db)))
+     db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
+-                    thd->priv_user, db); /* purecov: inspected */
++                    thd->priv_user, db, test(want_access & GRANT_ACL));
+   else
+     db_access=thd->db_access;
+   want_access &= ~EXTRA_ACL;                  // Remove SHOW attribute
+diff -Naru mysql.old/sql/sql_show.cc mysql-3.23.49/sql/sql_show.cc
+--- mysql.old/sql/sql_show.cc  Thu Feb 14 17:30:26 2002
++++ mysql-3.23.49/sql/sql_show.cc      Tue Mar 29 04:09:24 2005
+@@ -77,7 +77,7 @@
+   {
+     if (!opt_safe_show_db || thd->master_access ||
+       acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
+-              thd->priv_user, file_name) ||
++              thd->priv_user, file_name, 0) ||
+       (grant_option && !check_grant_db(thd, file_name)))
+       {
+       thd->packet.length(0);
+@@ -202,7 +202,7 @@
+ #endif
+       {
+         if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat.st_mode) ||
+-            (wild && wild_compare(file->name,wild)))
++            (wild && wild_compare(file->name,wild,0)))
+           continue;
+       }
+     }
+@@ -220,7 +220,7 @@
+         if (wild_case_compare(file->name,wild))
+           continue;
+       }
+-      else if (wild_compare(file->name,wild))
++      else if (wild_compare(file->name,wild, 0))
+         continue;
+       }
+     }
+@@ -1113,7 +1113,7 @@
+   pthread_mutex_lock(&LOCK_status);
+   for (i=0; variables[i].name; i++)
+   {
+-    if (!(wild && wild[0] && wild_compare(variables[i].name,wild)))
++    if (!(wild && wild[0] && wild_compare(variables[i].name, wild, 0)))
+     {
+       packet2.length(0);
+       net_store_data(&packet2,variables[i].name);
diff -Naru mysql.old/include/my_sys.h mysql-3.23.49/include/my_sys.h
--- mysql.old/include/my_sys.h  Thu Feb 14 17:30:15 2002
+++ mysql-3.23.49/include/my_sys.h      Tue Mar 29 04:09:24 2005
@@ -476,7 +476,7 @@
                         const char *own_pathname_part);
 extern my_string my_load_path(my_string to, const char *path,
                              const char *own_path_prefix);
-extern int wild_compare(const char *str,const char *wildstr);
+extern int wild_compare(const char *str,const char *wildstr,pbool 
str_is_pattern);
 extern my_string my_strcasestr(const char *src,const char *suffix);
 extern int my_strcasecmp(const char *s,const char *t);
 extern int my_strsortcmp(const char *s,const char *t);
diff -Naru mysql.old/mysys/mf_wcomp.c mysql-3.23.49/mysys/mf_wcomp.c
--- mysql.old/mysys/mf_wcomp.c  Thu Feb 14 17:30:15 2002
+++ mysql-3.23.49/mysys/mf_wcomp.c      Tue Mar 29 04:09:24 2005
@@ -24,11 +24,12 @@
 
 char wild_many='*';
 char wild_one='?';
-char wild_prefix=0;
+char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */
 
-int wild_compare(register const char *str, register const char *wildstr)
+int wild_compare(register const char *str, register const char *wildstr,
+                 pbool str_is_pattern)
 {
-  reg3 int flag;
+  char cmp;
   DBUG_ENTER("wild_compare");
 
   while (*wildstr)
@@ -36,33 +37,55 @@
     while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
     {
       if (*wildstr == wild_prefix && wildstr[1])
+      {
        wildstr++;
-      if (*wildstr++ != *str++) DBUG_RETURN(1);
+        if (str_is_pattern && *str++ != wild_prefix)
+          DBUG_RETURN(1);
+      }
+      if (*wildstr++ != *str++)
+        DBUG_RETURN(1);
     }
-    if (! *wildstr ) DBUG_RETURN (*str != 0);
+    if (! *wildstr )
+      DBUG_RETURN(*str != 0);
     if (*wildstr++ == wild_one)
     {
-      if (! *str++) DBUG_RETURN (1);   /* One char; skipp */
+      if (! *str || (str_is_pattern && *str == wild_many))
+        DBUG_RETURN(1);                     /* One char; skip */
+      if (*str++ == wild_prefix && str_is_pattern && *str)
+        str++;
     }
     else
     {                                          /* Found '*' */
-      if (!*wildstr) DBUG_RETURN(0);           /* '*' as last char: OK */
-      flag=(*wildstr != wild_many && *wildstr != wild_one);
-      do
+      while (str_is_pattern && *str == wild_many)
+        str++;
+      for (; *wildstr ==  wild_many || *wildstr == wild_one; wildstr++)
+        if (*wildstr == wild_many)
+        {
+          while (str_is_pattern && *str == wild_many)
+            str++;
+        }
+        else
+        {
+          if (str_is_pattern && *str == wild_prefix && str[1])
+            str+=2;
+          else if (! *str++)
+            DBUG_RETURN (1);
+        }
+      if (!*wildstr)
+        DBUG_RETURN(0);                /* '*' as last char: OK */
+      if ((cmp= *wildstr) == wild_prefix && wildstr[1] && !str_is_pattern)
+        cmp=wildstr[1];
+      for (;;str++)
       {
-       if (flag)
-       {
-         char cmp;
-         if ((cmp= *wildstr) == wild_prefix && wildstr[1])
-           cmp=wildstr[1];
-         while (*str && *str != cmp)
-           str++;
-         if (!*str) DBUG_RETURN (1);
-       }
-       if (wild_compare(str,wildstr) == 0) DBUG_RETURN (0);
-      } while (*str++ && wildstr[0] != wild_many);
-      DBUG_RETURN(1);
+        while (*str && *str != cmp)
+          str++;
+        if (!*str)
+          DBUG_RETURN (1);
+       if (wild_compare(str,wildstr,str_is_pattern) == 0)
+          DBUG_RETURN (0);
+      }
+      /* We will never come here */
     }
   }
-  DBUG_RETURN (*str != '\0');
+  DBUG_RETURN (*str != 0);
 } /* wild_compare */
diff -Naru mysql.old/mysys/mf_wfile.c mysql-3.23.49/mysys/mf_wfile.c
--- mysql.old/mysys/mf_wfile.c  Thu Feb 14 17:30:21 2002
+++ mysql-3.23.49/mysys/mf_wfile.c      Tue Mar 29 04:09:24 2005
@@ -107,7 +107,7 @@
 
   not_pos=wf_pack->not_pos;
   for (i=0 ; i < not_pos; i++)
-    if (wild_compare(name,wf_pack->wild[i]) == 0)
+    if (wild_compare(name,wf_pack->wild[i],0) == 0)
       goto found;
   if (i)
     DBUG_RETURN(1);                    /* No-match */
@@ -116,7 +116,7 @@
 /* Test that it isn't in not-list */
 
   for (i=not_pos ; i < wf_pack->wilds; i++)
-    if (wild_compare(name,wf_pack->wild[i]) == 0)
+    if (wild_compare(name,wf_pack->wild[i],0) == 0)
       DBUG_RETURN(1);
   DBUG_RETURN(0);
 } /* wf_test */
diff -Naru mysql.old/sql/sql_acl.cc mysql-3.23.49/sql/sql_acl.cc
--- mysql.old/sql/sql_acl.cc    Tue Mar 29 04:10:50 2005
+++ mysql-3.23.49/sql/sql_acl.cc        Tue Mar 29 04:09:24 2005
@@ -563,10 +563,13 @@
 
 /*****************************************************************************
 ** Get privilege for a host, user and db combination
+
+  as db_is_pattern changes the semantics of comparison,
+  acl_cache is not used if db_is_pattern is set.
 *****************************************************************************/
 
 uint acl_get(const char *host, const char *ip, const char *bin_ip,
-            const char *user, const char *db)
+            const char *user, const char *db, my_bool db_is_pattern)
 {
   uint host_access,db_access,i,key_length;
   db_access=0; host_access= ~0;
@@ -577,7 +580,7 @@
   memcpy_fixed(&key,bin_ip,sizeof(struct in_addr));
   end=strmov(strmov(key+sizeof(struct in_addr),user)+1,db);
   key_length=(uint) (end-key);
-  if ((entry=(acl_entry*) acl_cache->search(key,key_length)))
+  if (!db_is_pattern && (entry=(acl_entry*) acl_cache->search(key,key_length)))
   {
     db_access=entry->access;
     VOID(pthread_mutex_unlock(&acl_cache->lock));
@@ -594,7 +597,7 @@
     {
       if (compare_hostname(&acl_db->host,host,ip))
       {
-       if (!acl_db->db || !wild_compare(db,acl_db->db))
+       if (!acl_db->db || !wild_compare(db,acl_db->db,db_is_pattern))
        {
          db_access=acl_db->access;
          if (acl_db->host.hostname)
@@ -616,7 +619,7 @@
     ACL_HOST *acl_host=dynamic_element(&acl_hosts,i,ACL_HOST*);
     if (compare_hostname(&acl_host->host,host,ip))
     {
-      if (!acl_host->db || !wild_compare(db,acl_host->db))
+      if (!acl_host->db || !wild_compare(db,acl_host->db,0))
       {
        host_access=acl_host->access;           // Fully specified. Take it
        break;
@@ -625,7 +628,8 @@
   }
 exit:
   /* Save entry in cache for quick retrieval */
-  if ((entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
+  if (!db_is_pattern &&
+      (entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
   {
     entry->access=(db_access & host_access);
     entry->length=key_length;
@@ -897,7 +901,7 @@
   }
   return (!host->hostname ||
          (hostname && !wild_case_compare(hostname,host->hostname)) ||
-         (ip && !wild_compare(ip,host->hostname)));
+         (ip && !wild_compare(ip,host->hostname,0)));
 }
 
 
@@ -957,7 +961,7 @@
     tl.db=        (char*) "mysql";
     tl.real_name= (char*) "user";
     db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
-                     thd->priv_user, tl.db);
+                     thd->priv_user, tl.db, 0);
     if (!(db_access & INSERT_ACL))
     {
       if (check_grant(thd,INSERT_ACL,&tl,0,1))
diff -Naru mysql.old/sql/sql_acl.h mysql-3.23.49/sql/sql_acl.h
--- mysql.old/sql/sql_acl.h     Thu Feb 14 17:30:23 2002
+++ mysql-3.23.49/sql/sql_acl.h Tue Mar 29 04:09:24 2005
@@ -58,7 +58,7 @@
 void acl_reload(void);
 void acl_free(bool end=0);
 uint acl_get(const char *host, const char *ip, const char *bin_ip,
-            const char *user, const char *db);
+            const char *user, const char *db, my_bool db_is_pattern);
 uint acl_getroot(const char *host, const char *ip, const char *user,
                 const char *password,const char *scramble,char **priv_user,
                 bool old_ver);
diff -Naru mysql.old/sql/sql_base.cc mysql-3.23.49/sql/sql_base.cc
--- mysql.old/sql/sql_base.cc   Thu Feb 14 17:30:14 2002
+++ mysql-3.23.49/sql/sql_base.cc       Tue Mar 29 04:09:24 2005
@@ -126,7 +126,7 @@
     TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
     if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
       continue;
-    if (wild && wild[0] && wild_compare(entry->real_name,wild))
+    if (wild && wild[0] && wild_compare(entry->real_name,wild,0))
       continue;
     if (db && !(col_access & TABLE_ACLS))
     {
diff -Naru mysql.old/sql/sql_db.cc mysql-3.23.49/sql/sql_db.cc
--- mysql.old/sql/sql_db.cc     Thu Feb 14 17:30:16 2002
+++ mysql-3.23.49/sql/sql_db.cc Tue Mar 29 04:09:24 2005
@@ -329,7 +329,7 @@
     db_access=DB_ACLS;
   else
     db_access= (acl_get(thd->host,thd->ip,(char*) &thd->remote.sin_addr,
-                       thd->priv_user,dbname) |
+                       thd->priv_user,dbname,0) |
                thd->master_access);
   if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
   {
diff -Naru mysql.old/sql/sql_parse.cc mysql-3.23.49/sql/sql_parse.cc
--- mysql.old/sql/sql_parse.cc  Tue Mar 29 04:10:50 2005
+++ mysql-3.23.49/sql/sql_parse.cc      Tue Mar 29 04:09:24 2005
@@ -2138,7 +2138,7 @@
   
   if (db && (!thd->db || strcmp(db,thd->db)))
     db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
-                     thd->priv_user, db); /* purecov: inspected */
+                     thd->priv_user, db, test(want_access & GRANT_ACL));
   else
     db_access=thd->db_access;
   want_access &= ~EXTRA_ACL;                   // Remove SHOW attribute
diff -Naru mysql.old/sql/sql_show.cc mysql-3.23.49/sql/sql_show.cc
--- mysql.old/sql/sql_show.cc   Thu Feb 14 17:30:26 2002
+++ mysql-3.23.49/sql/sql_show.cc       Tue Mar 29 04:09:24 2005
@@ -77,7 +77,7 @@
   {
     if (!opt_safe_show_db || thd->master_access ||
        acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
-               thd->priv_user, file_name) ||
+               thd->priv_user, file_name, 0) ||
        (grant_option && !check_grant_db(thd, file_name)))
       {
       thd->packet.length(0);
@@ -202,7 +202,7 @@
 #endif
       {
         if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat.st_mode) ||
-            (wild && wild_compare(file->name,wild)))
+            (wild && wild_compare(file->name,wild,0)))
           continue;
       }
     }
@@ -220,7 +220,7 @@
          if (wild_case_compare(file->name,wild))
            continue;
        }
-       else if (wild_compare(file->name,wild))
+       else if (wild_compare(file->name,wild, 0))
          continue;
       }
     }
@@ -1113,7 +1113,7 @@
   pthread_mutex_lock(&LOCK_status);
   for (i=0; variables[i].name; i++)
   {
-    if (!(wild && wild[0] && wild_compare(variables[i].name,wild)))
+    if (!(wild && wild[0] && wild_compare(variables[i].name, wild, 0)))
     {
       packet2.length(0);
       net_store_data(&packet2,variables[i].name);

Attachment: signature.asc
Description: Digital signature

Reply via email to