Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 171 lines (164 sloc) 7.582 kb
ec09c36 User privileges
jakubvrana authored
1 <?php
79d1902 Substitute table name to $TABLE
jakubvrana authored
2 $USER = $_GET["user"];
5beacc3 All privileges
jakubvrana authored
3 $privileges = array("" => array("All privileges" => ""));
b0d637b Jakub Vrána Avoid fatal errors
authored
4 foreach (get_rows("SHOW PRIVILEGES") as $row) {
f973fda Ability to grant and revoke ALL and GRANT together
jakubvrana authored
5 foreach (explode(",", ($row["Privilege"] == "Grant option" ? "" : $row["Context"])) as $context) {
6 $privileges[$context][$row["Privilege"]] = $row["Comment"];
7d635e1 Edit any user
jakubvrana authored
7 }
8 }
9 $privileges["Server Admin"] += $privileges["File access on server"];
64ba924 Comments
jakubvrana authored
10 $privileges["Databases"]["Create routine"] = $privileges["Procedures"]["Create routine"]; // MySQL bug #30305
11 unset($privileges["Procedures"]["Create routine"]);
7d635e1 Edit any user
jakubvrana authored
12 $privileges["Columns"] = array();
13 foreach (array("Select", "Insert", "Update", "References") as $val) {
14 $privileges["Columns"][$val] = $privileges["Tables"][$val];
15 }
16 unset($privileges["Server Admin"]["Usage"]);
17 foreach ($privileges["Tables"] as $key => $val) {
18 unset($privileges["Databases"][$key]);
19 }
20
d8df520 Initialize variables outside blocks
jakubvrana authored
21 $new_grants = array();
ec09c36 User privileges
jakubvrana authored
22 if ($_POST) {
23 foreach ($_POST["objects"] as $key => $val) {
1ff155a Fix revoking of old privileges
jakubvrana authored
24 $new_grants[$val] = (array) $new_grants[$val] + (array) $_POST["grants"][$key];
ec09c36 User privileges
jakubvrana authored
25 }
26 }
27 $grants = array();
28 $old_pass = "";
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
29 if (isset($_GET["host"]) && ($result = $connection->query("SHOW GRANTS FOR " . q($USER) . "@" . q($_GET["host"])))) { //! use information_schema for MySQL 5 - column names in column privileges are not escaped
ec09c36 User privileges
jakubvrana authored
30 while ($row = $result->fetch_row()) {
5beacc3 All privileges
jakubvrana authored
31 if (preg_match('~GRANT (.*) ON (.*) TO ~', $row[0], $match) && preg_match_all('~ *([^(,]*[^ ,(])( *\\([^)]+\\))?~', $match[1], $matches, PREG_SET_ORDER)) { //! escape the part between ON and TO
32 foreach ($matches as $val) {
1ff155a Fix revoking of old privileges
jakubvrana authored
33 if ($val[1] != "USAGE") {
34 $grants["$match[2]$val[2]"][$val[1]] = true;
35 }
5abd943 Change simple preg_match to ereg
jakubvrana authored
36 if (ereg(' WITH GRANT OPTION', $row[0])) { //! don't check inside strings and identifiers
5beacc3 All privileges
jakubvrana authored
37 $grants["$match[2]$val[2]"]["GRANT OPTION"] = true;
7d635e1 Edit any user
jakubvrana authored
38 }
ec09c36 User privileges
jakubvrana authored
39 }
40 }
41 if (preg_match("~ IDENTIFIED BY PASSWORD '([^']+)~", $row[0], $match)) {
42 $old_pass = $match[1];
43 }
44 }
45 }
46
47 if ($_POST && !$error) {
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
48 $old_user = (isset($_GET["host"]) ? q($USER) . "@" . q($_GET["host"]) : "''");
49 $new_user = q($_POST["user"]) . "@" . q($_POST["host"]); // if $_GET["host"] is not set then $new_user is always different
50 $pass = q($_POST["pass"]);
ec09c36 User privileges
jakubvrana authored
51 if ($_POST["drop"]) {
98507da Function verify_version doesn't use version parameter
jakubvrana authored
52 query_redirect("DROP USER $old_user", ME . "privileges=", lang('User has been dropped.'));
5beacc3 All privileges
jakubvrana authored
53 } else {
2b472a5 Jakub Vrána Drop user only if successfully created
authored
54 $created = false;
e3492e8 Change password only if changed
jakubvrana authored
55 if ($old_user != $new_user) {
2b472a5 Jakub Vrána Drop user only if successfully created
authored
56 $created = queries(($connection->server_info < 5 ? "GRANT USAGE ON *.* TO" : "CREATE USER") . " $new_user IDENTIFIED BY" . ($_POST["hashed"] ? " PASSWORD" : "") . " $pass");
57 $error = !$created;
e3492e8 Change password only if changed
jakubvrana authored
58 } elseif ($_POST["pass"] != $old_pass || !$_POST["hashed"]) {
59 queries("SET PASSWORD FOR $new_user = " . ($_POST["hashed"] ? $pass : "PASSWORD($pass)"));
7d7e10b GRANT USAGE only on MySQL 4
jakubvrana authored
60 }
5beacc3 All privileges
jakubvrana authored
61 if (!$error) {
62 $revoke = array();
63 foreach ($new_grants as $object => $grant) {
64 if (isset($_GET["grant"])) {
65 $grant = array_filter($grant);
66 }
67 $grant = array_keys($grant);
68 if (isset($_GET["grant"])) {
64ba924 Comments
jakubvrana authored
69 // no rights to mysql.user table
5beacc3 All privileges
jakubvrana authored
70 $revoke = array_diff(array_keys(array_filter($new_grants[$object], 'strlen')), $grant);
71 } elseif ($old_user == $new_user) {
72 $old_grant = array_keys((array) $grants[$object]);
73 $revoke = array_diff($old_grant, $grant);
74 $grant = array_diff($grant, $old_grant);
75 unset($grants[$object]);
76 }
77 if (preg_match('~^(.+)\\s*(\\(.*\\))?$~U', $object, $match) && (
fc3b652 Whitespace
jakubvrana authored
78 !grant("REVOKE", $revoke, $match[2], " ON $match[1] FROM $new_user") //! SQL injection
79 || !grant("GRANT", $grant, $match[2], " ON $match[1] TO $new_user")
5beacc3 All privileges
jakubvrana authored
80 )) {
81 $error = true;
82 break;
ec09c36 User privileges
jakubvrana authored
83 }
84 }
85 }
5beacc3 All privileges
jakubvrana authored
86 if (!$error && isset($_GET["host"])) {
87 if ($old_user != $new_user) {
36a3656 Change escape_string to quote
jakubvrana authored
88 queries("DROP USER $old_user");
7d635e1 Edit any user
jakubvrana authored
89 } elseif (!isset($_GET["grant"])) {
ec09c36 User privileges
jakubvrana authored
90 foreach ($grants as $object => $revoke) {
91 if (preg_match('~^(.+)(\\(.*\\))?$~U', $object, $match)) {
1ff155a Fix revoking of old privileges
jakubvrana authored
92 grant("REVOKE", array_keys($revoke), $match[2], " ON $match[1] FROM $new_user");
ec09c36 User privileges
jakubvrana authored
93 }
94 }
95 }
96 }
dbdd40a Introduce queries_redirect function
jakubvrana authored
97 queries_redirect(ME . "privileges=", (isset($_GET["host"]) ? lang('User has been altered.') : lang('User has been created.')), !$error);
2b472a5 Jakub Vrána Drop user only if successfully created
authored
98 if ($created) {
97807b0 Comments
jakubvrana authored
99 // delete new user in case of an error
64d616c Rename get_dbh to connection
jakubvrana authored
100 $connection->query("DROP USER $new_user");
5beacc3 All privileges
jakubvrana authored
101 }
ec09c36 User privileges
jakubvrana authored
102 }
103 }
36d6864 Whitespace
jakubvrana authored
104
79d1902 Substitute table name to $TABLE
jakubvrana authored
105 page_header((isset($_GET["host"]) ? lang('Username') . ": " . h("$USER@$_GET[host]") : lang('Create user')), $error, array("privileges" => array('', lang('Privileges'))));
ec09c36 User privileges
jakubvrana authored
106
107 if ($_POST) {
108 $row = $_POST;
109 $grants = $new_grants;
110 } else {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
111 $row = $_GET + array("host" => $connection->result("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', -1)")); // create user on the same domain by default
ec09c36 User privileges
jakubvrana authored
112 $row["pass"] = $old_pass;
31b7b3a Not hashed password by default
jakubvrana authored
113 if ($old_pass != "") {
114 $row["hashed"] = true;
115 }
841cbbb Jakub Vrána Prefill .* when creating a new user
authored
116 $grants[(DB != "" && !isset($_GET["host"]) ? idf_escape(addcslashes(DB, "%_")) : "") . ".*"] = array();
ec09c36 User privileges
jakubvrana authored
117 }
118
119 ?>
120 <form action="" method="post">
d30face Remove useless table attributes (thanks to Juraj Krivda)
jakubvrana authored
121 <table cellspacing="0">
689699a Shortcut for htmlspecialchars
jakubvrana authored
122 <tr><th><?php echo lang('Server'); ?><td><input name="host" maxlength="60" value="<?php echo h($row["host"]); ?>">
bd88113 Jakub Vrána Same fields order as in login form
authored
123 <tr><th><?php echo lang('Username'); ?><td><input name="user" maxlength="16" value="<?php echo h($row["user"]); ?>">
6b30cfa Separate checkbox
jakubvrana authored
124 <tr><th><?php echo lang('Password'); ?><td><input id="pass" name="pass" value="<?php echo h($row["pass"]); ?>">
3c5c0f0 Use camelCase in JavaScript
jakubvrana authored
125 <?php if (!$row["hashed"]) { ?><script type="text/javascript">typePassword(document.getElementById('pass'));</script><?php } ?>
126 <?php echo checkbox("hashed", 1, $row["hashed"], lang('Hashed'), "typePassword(this.form['pass'], this.checked);"); ?>
ec09c36 User privileges
jakubvrana authored
127 </table>
128
129 <?php
130 //! MAX_* limits, REQUIRE
d30face Remove useless table attributes (thanks to Juraj Krivda)
jakubvrana authored
131 echo "<table cellspacing='0'>\n";
f195903 Jakub Vrána Use rel="noreferrer" for documentation links
authored
132 echo "<thead><tr><th colspan='2'><a href='http://dev.mysql.com/doc/refman/" . substr($connection->server_info, 0, 3) . "/en/grant.html#priv_level' target='_blank' rel='noreferrer'>" . lang('Privileges') . "</a>";
ec09c36 User privileges
jakubvrana authored
133 $i = 0;
b76fd38 Vertical privileges
jakubvrana authored
134 foreach ($grants as $object => $grant) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
135 echo '<th>' . ($object != "*.*" ? "<input name='objects[$i]' value='" . h($object) . "' size='10'>" : "<input type='hidden' name='objects[$i]' value='*.*' size='10'>*.*"); //! separate db, table, columns, PROCEDURE|FUNCTION, routine
b76fd38 Vertical privileges
jakubvrana authored
136 $i++;
137 }
ace55ed HTML instead of XHTML
jakubvrana authored
138 echo "</thead>\n";
ec09c36 User privileges
jakubvrana authored
139 foreach (array(
5beacc3 All privileges
jakubvrana authored
140 "" => "",
ec09c36 User privileges
jakubvrana authored
141 "Server Admin" => lang('Server'),
142 "Databases" => lang('Database'),
143 "Tables" => lang('Table'),
144 "Columns" => lang('Column'),
145 "Procedures" => lang('Routine'),
b76fd38 Vertical privileges
jakubvrana authored
146 ) as $context => $desc) {
147 foreach ((array) $privileges[$context] as $privilege => $comment) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
148 echo "<tr" . odd() . "><td" . ($desc ? ">$desc<td" : " colspan='2'") . ' lang="en" title="' . h($comment) . '">' . h($privilege);
b76fd38 Vertical privileges
jakubvrana authored
149 $i = 0;
ec09c36 User privileges
jakubvrana authored
150 foreach ($grants as $object => $grant) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
151 $name = "'grants[$i][" . h(strtoupper($privilege)) . "]'";
b76fd38 Vertical privileges
jakubvrana authored
152 $value = $grant[strtoupper($privilege)];
841cbbb Jakub Vrána Prefill .* when creating a new user
authored
153 if ($context == "Server Admin" && $object != (isset($grants["*.*"]) ? "*.*" : ".*")) {
ace55ed HTML instead of XHTML
jakubvrana authored
154 echo "<td>&nbsp;";
b76fd38 Vertical privileges
jakubvrana authored
155 } elseif (isset($_GET["grant"])) {
cb6d36c HTML instead of XHTML
jakubvrana authored
156 echo "<td><select name=$name><option><option value='1'" . ($value ? " selected" : "") . ">" . lang('Grant') . "<option value='0'" . ($value == "0" ? " selected" : "") . ">" . lang('Revoke') . "</select>";
b76fd38 Vertical privileges
jakubvrana authored
157 } else {
3c5c0f0 Use camelCase in JavaScript
jakubvrana authored
158 echo "<td align='center'><input type='checkbox' name=$name value='1'" . ($value ? " checked" : "") . ($privilege == "All privileges" ? " id='grants-$i-all'" : ($privilege == "Grant option" ? "" : " onclick=\"if (this.checked) formUncheck('grants-$i-all');\"")) . ">"; //! uncheck all except grant if all is checked
ec09c36 User privileges
jakubvrana authored
159 }
b76fd38 Vertical privileges
jakubvrana authored
160 $i++;
ec09c36 User privileges
jakubvrana authored
161 }
162 }
163 }
b76fd38 Vertical privileges
jakubvrana authored
164 echo "</table>\n";
ec09c36 User privileges
jakubvrana authored
165 ?>
166 <p>
ace55ed HTML instead of XHTML
jakubvrana authored
167 <input type="submit" value="<?php echo lang('Save'); ?>">
a93bc19 Jakub Vrána Create confirm function
authored
168 <?php if (isset($_GET["host"])) { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
740ae10 Jakub Vrána Don't send incomplete forms
authored
169 <input type="hidden" name="token" value="<?php echo $token; ?>">
ec09c36 User privileges
jakubvrana authored
170 </form>
Something went wrong with that request. Please try again.