Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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 @vrana 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.