250 |
kaklik |
1 |
<?php |
|
|
2 |
/* $Id: check_user_privileges.lib.php,v 1.12 2006/01/17 17:02:30 cybot_tm Exp $ */ |
|
|
3 |
// vim: expandtab sw=4 ts=4 sts=4: |
|
|
4 |
|
|
|
5 |
// Get user's global privileges and some db-specific privileges |
|
|
6 |
// ($controllink and $userlink are links to MySQL defined in the "common.lib.php" library) |
|
|
7 |
// Note: if no controluser is defined, $controllink contains $userlink |
|
|
8 |
|
|
|
9 |
/** |
|
|
10 |
* returns true (int > 0) if current user is superuser |
|
|
11 |
* otherwise 0 |
|
|
12 |
* |
|
|
13 |
* @return integer $is_superuser |
|
|
14 |
*/ |
|
|
15 |
function PMA_isSuperuser() { |
|
|
16 |
return PMA_DBI_try_query( 'SELECT COUNT(*) FROM mysql.user', |
|
|
17 |
$GLOBALS['userlink'], PMA_DBI_QUERY_STORE ); |
|
|
18 |
} |
|
|
19 |
|
|
|
20 |
$is_create_db_priv = false; |
|
|
21 |
$is_process_priv = true; |
|
|
22 |
$is_reload_priv = false; |
|
|
23 |
$db_to_create = ''; |
|
|
24 |
$dbs_where_create_table_allowed = array(); |
|
|
25 |
|
|
|
26 |
// We were trying to find if user if superuser with 'USE mysql' |
|
|
27 |
// but users with the global priv CREATE TEMPORARY TABLES or LOCK TABLES |
|
|
28 |
// can do a 'USE mysql' (even if they cannot see the tables) |
|
|
29 |
$is_superuser = PMA_isSuperuser(); |
|
|
30 |
|
|
|
31 |
function PMA_analyseShowGrant($rs_usr, &$is_create_db_priv, &$db_to_create, &$is_reload_priv, &$dbs_where_create_table_allowed) { |
|
|
32 |
|
|
|
33 |
$re0 = '(^|(\\\\\\\\)+|[^\])'; // non-escaped wildcards |
|
|
34 |
$re1 = '(^|[^\])(\\\)+'; // escaped wildcards |
|
|
35 |
while ($row = PMA_DBI_fetch_row($rs_usr)) { |
|
|
36 |
$show_grants_dbname = substr($row[0], strpos($row[0], ' ON ') + 4, (strpos($row[0], '.', strpos($row[0], ' ON ')) - strpos($row[0], ' ON ') - 4)); |
|
|
37 |
$show_grants_dbname = ereg_replace('^`(.*)`', '\\1', $show_grants_dbname); |
|
|
38 |
$show_grants_str = substr($row[0], 6, (strpos($row[0], ' ON ') - 6)); |
|
|
39 |
if ($show_grants_str == 'RELOAD') { |
|
|
40 |
$is_reload_priv = true; |
|
|
41 |
} |
|
|
42 |
if (($show_grants_str == 'ALL') || ($show_grants_str == 'ALL PRIVILEGES') || ($show_grants_str == 'CREATE') || strpos($show_grants_str, 'CREATE')) { |
|
|
43 |
if ($show_grants_dbname == '*') { |
|
|
44 |
// a global CREATE privilege |
|
|
45 |
$is_create_db_priv = true; |
|
|
46 |
$is_reload_priv = true; |
|
|
47 |
$db_to_create = ''; |
|
|
48 |
$dbs_where_create_table_allowed[] = '*'; |
|
|
49 |
break; |
|
|
50 |
} else { |
|
|
51 |
// this array may contain wildcards |
|
|
52 |
$dbs_where_create_table_allowed[] = $show_grants_dbname; |
|
|
53 |
|
|
|
54 |
// before MySQL 4.1.0, we cannot use backquotes around a dbname |
|
|
55 |
// for the USE command, so the USE will fail if the dbname contains |
|
|
56 |
// a "-" and we cannot detect if such a db already exists; |
|
|
57 |
// since 4.1.0, we need to use backquotes if the dbname contains a "-" |
|
|
58 |
// in a USE command |
|
|
59 |
|
|
|
60 |
if (PMA_MYSQL_INT_VERSION > 40100) { |
|
|
61 |
$dbname_to_test = PMA_backquote($show_grants_dbname); |
|
|
62 |
} else { |
|
|
63 |
$dbname_to_test = $show_grants_dbname; |
|
|
64 |
} |
|
|
65 |
|
|
|
66 |
if ( (ereg($re0 . '%|_', $show_grants_dbname) |
|
|
67 |
&& !ereg('\\\\%|\\\\_', $show_grants_dbname)) |
|
|
68 |
// does this db exist? |
|
|
69 |
|| (!PMA_DBI_try_query('USE ' . ereg_replace($re1 .'(%|_)', '\\1\\3', $dbname_to_test), null, PMA_DBI_QUERY_STORE) && substr(PMA_DBI_getError(), 1, 4) != 1044) |
|
|
70 |
) { |
|
|
71 |
$db_to_create = ereg_replace($re0 . '%', '\\1...', ereg_replace($re0 . '_', '\\1?', $show_grants_dbname)); |
|
|
72 |
$db_to_create = ereg_replace($re1 . '(%|_)', '\\1\\3', $db_to_create); |
|
|
73 |
$is_create_db_priv = true; |
|
|
74 |
|
|
|
75 |
// TODO: collect $db_to_create into an array, to display a drop-down |
|
|
76 |
// in the "Create new database" dialog |
|
|
77 |
// |
|
|
78 |
// we don't break, we want all possible databases |
|
|
79 |
//break; |
|
|
80 |
} // end if |
|
|
81 |
} // end elseif |
|
|
82 |
} // end if |
|
|
83 |
} // end while |
|
|
84 |
} // end function |
|
|
85 |
|
|
|
86 |
// Detection for some CREATE privilege. |
|
|
87 |
|
|
|
88 |
// Since MySQL 4.1.2, we can easily detect current user's grants |
|
|
89 |
// using $userlink (no control user needed) |
|
|
90 |
// and we don't have to try any other method for detection |
|
|
91 |
|
|
|
92 |
if (PMA_MYSQL_INT_VERSION >= 40102) { |
|
|
93 |
$rs_usr = PMA_DBI_try_query('SHOW GRANTS', $userlink, PMA_DBI_QUERY_STORE); |
|
|
94 |
if ($rs_usr) { |
|
|
95 |
PMA_analyseShowGrant($rs_usr, $is_create_db_priv, $db_to_create, $is_reload_priv, $dbs_where_create_table_allowed); |
|
|
96 |
PMA_DBI_free_result($rs_usr); |
|
|
97 |
unset($rs_usr); |
|
|
98 |
} |
|
|
99 |
} else { |
|
|
100 |
|
|
|
101 |
// Before MySQL 4.1.2, we first try to find a priv in mysql.user. Hopefuly |
|
|
102 |
// the controluser is correctly defined; but here, $controllink could contain |
|
|
103 |
// $userlink so maybe the SELECT will fail |
|
|
104 |
|
|
|
105 |
if (!$is_create_db_priv) { |
|
|
106 |
$res = PMA_DBI_query('SELECT USER();', null, PMA_DBI_QUERY_STORE); |
|
|
107 |
list($mysql_cur_user_and_host) = PMA_DBI_fetch_row($res); |
|
|
108 |
$mysql_cur_user = substr($mysql_cur_user_and_host, 0, strrpos($mysql_cur_user_and_host, '@')); |
|
|
109 |
|
|
|
110 |
$local_query = 'SELECT Create_priv, Reload_priv FROM mysql.user WHERE ' . PMA_convert_using('User') . ' = ' . PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ' OR ' . PMA_convert_using('User') . ' = ' . PMA_convert_using('', 'quoted') . ';'; |
|
|
111 |
$rs_usr = PMA_DBI_try_query($local_query, $controllink, PMA_DBI_QUERY_STORE); // Debug: or PMA_mysqlDie('', $local_query, false); |
|
|
112 |
if ($rs_usr) { |
|
|
113 |
while ($result_usr = PMA_DBI_fetch_assoc($rs_usr)) { |
|
|
114 |
if (!$is_create_db_priv) { |
|
|
115 |
$is_create_db_priv = ($result_usr['Create_priv'] == 'Y'); |
|
|
116 |
} |
|
|
117 |
if (!$is_reload_priv) { |
|
|
118 |
$is_reload_priv = ($result_usr['Reload_priv'] == 'Y'); |
|
|
119 |
} |
|
|
120 |
} // end while |
|
|
121 |
PMA_DBI_free_result($rs_usr); |
|
|
122 |
unset($rs_usr, $result_usr); |
|
|
123 |
if ($is_create_db_priv) { |
|
|
124 |
$dbs_where_create_table_allowed[] = '*'; |
|
|
125 |
} |
|
|
126 |
} // end if |
|
|
127 |
} // end if |
|
|
128 |
|
|
|
129 |
// If the user has Create priv on a inexistant db, show him in the dialog |
|
|
130 |
// the first inexistant db name that we find, in most cases it's probably |
|
|
131 |
// the one he just dropped :) |
|
|
132 |
if (!$is_create_db_priv) { |
|
|
133 |
$local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE ' . PMA_convert_using('Create_priv') . ' = ' . PMA_convert_using('Y', 'quoted') . ' AND (' . PMA_convert_using('User') . ' = ' .PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ' OR ' . PMA_convert_using('User') . ' = ' . PMA_convert_using('', 'quoted') . ');'; |
|
|
134 |
|
|
|
135 |
$rs_usr = PMA_DBI_try_query($local_query, $controllink, PMA_DBI_QUERY_STORE); |
|
|
136 |
if ($rs_usr) { |
|
|
137 |
$re0 = '(^|(\\\\\\\\)+|[^\])'; // non-escaped wildcards |
|
|
138 |
$re1 = '(^|[^\])(\\\)+'; // escaped wildcards |
|
|
139 |
while ($row = PMA_DBI_fetch_assoc($rs_usr)) { |
|
|
140 |
$dbs_where_create_table_allowed[] = $row['Db']; |
|
|
141 |
if (ereg($re0 . '(%|_)', $row['Db']) |
|
|
142 |
|| (!PMA_DBI_try_query('USE ' . ereg_replace($re1 . '(%|_)', '\\1\\3', $row['Db'])) && substr(PMA_DBI_getError(), 1, 4) != 1044)) { |
|
|
143 |
$db_to_create = ereg_replace($re0 . '%', '\\1...', ereg_replace($re0 . '_', '\\1?', $row['Db'])); |
|
|
144 |
$db_to_create = ereg_replace($re1 . '(%|_)', '\\1\\3', $db_to_create); |
|
|
145 |
$is_create_db_priv = true; |
|
|
146 |
break; |
|
|
147 |
} // end if |
|
|
148 |
} // end while |
|
|
149 |
PMA_DBI_free_result($rs_usr); |
|
|
150 |
unset($rs_usr, $row, $re0, $re1); |
|
|
151 |
} else { |
|
|
152 |
// Finally, let's try to get the user's privileges by using SHOW |
|
|
153 |
// GRANTS... |
|
|
154 |
// Maybe we'll find a little CREATE priv there :) |
|
|
155 |
$rs_usr = PMA_DBI_try_query('SHOW GRANTS FOR ' . $mysql_cur_user_and_host . ';', $controllink, PMA_DBI_QUERY_STORE); |
|
|
156 |
if (!$rs_usr) { |
|
|
157 |
// OK, now we'd have to guess the user's hostname, but we |
|
|
158 |
// only try out the 'username'@'%' case. |
|
|
159 |
$rs_usr = PMA_DBI_try_query('SHOW GRANTS FOR ' . PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ';', $controllink, PMA_DBI_QUERY_STORE); |
|
|
160 |
} |
|
|
161 |
unset($local_query); |
|
|
162 |
if ($rs_usr) { |
|
|
163 |
PMA_analyseShowGrant($rs_usr, $is_create_db_priv, $db_to_create, $is_reload_priv, $dbs_where_create_table_allowed); |
|
|
164 |
PMA_DBI_free_result($rs_usr); |
|
|
165 |
unset($rs_usr); |
|
|
166 |
} // end if |
|
|
167 |
} // end elseif |
|
|
168 |
} // end if |
|
|
169 |
} // end else (MySQL < 4.1.2) |
|
|
170 |
|
|
|
171 |
// If disabled, don't show it |
|
|
172 |
if (!$cfg['SuggestDBName']) { |
|
|
173 |
$db_to_create = ''; |
|
|
174 |
} |
|
|
175 |
?> |