]> git.joonet.de Git - adminer.git/commitdiff
User privileges
authorjakubvrana <jakubvrana@7c3ca157-0c34-0410-bff1-cbf682f78f5c>
Thu, 9 Aug 2007 15:03:39 +0000 (15:03 +0000)
committerjakubvrana <jakubvrana@7c3ca157-0c34-0410-bff1-cbf682f78f5c>
Thu, 9 Aug 2007 15:03:39 +0000 (15:03 +0000)
git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@320 7c3ca157-0c34-0410-bff1-cbf682f78f5c

connect.inc.php
index.php
privileges.inc.php
user.inc.php [new file with mode: 0644]

index 6612652435ad45bdcc3facf1de07f7ff3bf75d12..47e24cec5646acbfd5d0ee4f9e91c74ef4f69171 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-if (!(strlen($_GET["db"]) ? $mysql->select_db($_GET["db"]) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]))) {
+if (!(strlen($_GET["db"]) ? $mysql->select_db($_GET["db"]) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]))) {
        if (strlen($_GET["db"])) {
                unset($_SESSION["databases"][$_GET["server"]]);
        }
index 9dd63f122c9d485186c4b2747986a7fadd2d89bb..0b4b3a19083d8122c3a97fb78633cc659ab4edbf 100644 (file)
--- a/index.php
+++ b/index.php
@@ -48,6 +48,8 @@ if (isset($_GET["dump"])) {
                include "./view.inc.php";
        } elseif (isset($_GET["schema"])) {
                include "./schema.inc.php";
+       } elseif (isset($_GET["privileges"])) {
+               include "./privileges.inc.php";
        } else { // uses CSRF token
                include "./editing.inc.php";
                if ($_POST) {
@@ -83,8 +85,8 @@ if (isset($_GET["dump"])) {
                        include "./procedure.inc.php";
                } elseif (isset($_GET["trigger"])) {
                        include "./trigger.inc.php";
-               } elseif (isset($_GET["privileges"])) {
-                       include "./privileges.inc.php";
+               } elseif (isset($_GET["user"])) {
+                       include "./user.inc.php";
                } elseif (isset($_GET["processlist"])) {
                        include "./processlist.inc.php";
                } else {
@@ -100,8 +102,8 @@ if (isset($_GET["dump"])) {
                                        echo "<table border='0' cellspacing='0' cellpadding='2'>\n";
                                        while ($row = $result->fetch_assoc()) {
                                                echo "<tr>";
-                                               echo "<th>" . htmlspecialchars($row["ROUTINE_TYPE"]) . "</th>";
-                                               echo '<td><a href="' . htmlspecialchars($SELF) . ($row["ROUTINE_TYPE"] == "FUNCTION" ? 'callf' : 'call') . '=' . urlencode($row["ROUTINE_NAME"]) . '">' . htmlspecialchars($row["ROUTINE_NAME"]) . '</a></td>';
+                                               echo "<td>" . htmlspecialchars($row["ROUTINE_TYPE"]) . "</td>";
+                                               echo '<th><a href="' . htmlspecialchars($SELF) . ($row["ROUTINE_TYPE"] == "FUNCTION" ? 'callf' : 'call') . '=' . urlencode($row["ROUTINE_NAME"]) . '">' . htmlspecialchars($row["ROUTINE_NAME"]) . '</a></th>';
                                                echo '<td><a href="' . htmlspecialchars($SELF) . ($row["ROUTINE_TYPE"] == "FUNCTION" ? 'function' : 'procedure') . '=' . urlencode($row["ROUTINE_NAME"]) . '">' . lang('Alter') . "</a></td>\n";
                                                echo "</tr>\n";
                                        }
index 22918a6a0909e8f2b09ce2835722eaec8bf341d2..c231b5c244e859f8116428ec582a74eadc65917d 100644 (file)
@@ -1,90 +1,14 @@
 <?php
-if (isset($_GET["name"])) {
-       page_header((strlen($_GET["privileges"]) ? lang('Username') . ": " . htmlspecialchars("$_GET[name]@$_GET[privileges]") : lang('Create user')), array("privileges" => lang('Privileges')));
-       $privileges = array();
-       $result = $mysql->query("SHOW PRIVILEGES");
-       while ($row = $result->fetch_assoc()) {
-               foreach (explode(",", $row["Context"]) as $context) {
-                       $privileges[$context][$row["Privilege"]] = $row["Comment"]; //! translation
-               }
-       }
-       $result->free();
-       $privileges["Server Admin"] += $privileges["File access on server"];
-       $privileges["Databases"]["Create routine"] = $privileges["Procedures"]["Create routine"];
-       $privileges["Columns"] = array();
-       foreach (array("Select", "Insert", "Update", "References") as $val) {
-               $privileges["Columns"][$val] = $privileges["Tables"][$val];
-       }
-       unset($privileges["Server Admin"]["Usage"]);
-       unset($privileges["Procedures"]["Create routine"]);
-       unset($privileges["Functions"]["Create routine"]);
-       $grants = array();
-       if (strlen($_GET["privileges"]) && ($result = $mysql->query("SHOW GRANTS FOR '" . $mysql->escape_string($_GET["name"]) . "'@'" . $mysql->escape_string($_GET["privileges"]) . "'"))) { //! Use information_schema for MySQL 5 - column names in column privileges are not escaped
-               while ($row = $result->fetch_row()) {
-                       if (preg_match('~GRANT (.*) ON (.*) TO ~', $row[0], $match)) { //! escape part between ON and TO
-                               preg_match_all('~ *([^(,]*[^ ,(])( *\\([^)]+\\))?~', $match[1], $matches, PREG_SET_ORDER);
-                               foreach ($matches as $val) {
-                                       $grants["$match[2]$val[2]"][$val[1]] = true;
-                               }
-                       }
-                       if (preg_match('~ WITH GRANT OPTION~', $row[0])) { //! don't check inside strings and identifiers
-                               $grants[$match[2]]["GRANT OPTION"] = true;
-                       }
-               }
-               $result->free();
-       }
-       $grants[""] = true;
-       
-       foreach (array(
-               "Server Admin" => lang('Server'),
-               "Databases" => lang('Database'),
-               "Tables" => lang('Table'),
-               "Columns" => lang('Column'),
-               "Procedures" => lang('Procedure'),
-               "Functions" => lang('Function'),
-       ) as $key => $val) {
-               if ($privileges[$key]) {
-                       echo "<table border='0' cellspacing='0' cellpadding='2'>\n";
-                       echo "<thead><tr>";
-                       if ($key != "Server Admin") {
-                               echo "<th>$val</th>";
-                       }
-                       foreach ($privileges[$key] as $privilege => $comment) {
-                               echo '<td title="' . htmlspecialchars($comment) . '">' . htmlspecialchars($privilege) . '</td>';
-                       }
-                       echo "</tr></thead>\n";
-                       foreach ($grants as $object => $grant) {
-                               if ($key == "Server Admin" ? $object == (isset($grants["*.*"]) ? "*.*" : "")
-                               : !$object || (substr($object, -1) == ")" || $key == "Columns" ? substr($object, -1) == ")" xor $key != "Columns"
-                               : (preg_match('~PROCEDURE ~', $object) ? $key == "Procedures"
-                               : (preg_match('~FUNCTION ~', $object) ? $key == "Functions"
-                               : (substr($object, -1) == "*" || $key == "Tables"
-                               ))))) {
-                                       echo "<tr align='center'>";
-                                       if ($key != "Server Admin") {
-                                               echo '<th><input name="" value="' . htmlspecialchars($object) . "\" size='10' /></th>";
-                                       }
-                                       foreach ($privileges[$key] as $privilege => $comment) {
-                                               echo "<td><input type='checkbox' name='grant' value='1'" . ($grant[strtoupper($privilege)] || ($privilege != "Grant option" && $grant["ALL PRIVILEGES"]) ? " checked='checked'" : "") . " /></td>";
-                                       }
-                                       echo "</tr>\n";
-                               }
-                       }
-                       echo "</table>\n";
-               }
-       }
-       //! DROP USER, name, server, password
-} else {
-       page_header(lang('Privileges'));
-       echo '<p><a href="' . htmlspecialchars($SELF) . 'privileges=&amp;name=">' . lang('Create user') . "</a></p>\n";
-       //! use mysql database if possible (GRANTEE not properly escaped) or CURRENT_USER in MySQL 4 in case of insufficient privileges
-       $result = $mysql->query("SELECT DISTINCT GRANTEE FROM information_schema.USER_PRIVILEGES");
-       echo "<table border='1' cellspacing='0' cellpadding='2'>\n";
-       echo "<thead><tr><th>&nbsp;</th><th>" . lang('Username') . "</th><th>" . lang('Server') . "</th></tr></thead>\n";
-       while ($row = $result->fetch_row()) {
-               preg_match("~'((?:[^']+|'')*)'@'((?:[^']+|'')+)'~", $row[0], $match);
-               echo '<tr><td><a href="' . htmlspecialchars($SELF) . 'privileges=' . urlencode($match[2]) . '&amp;name=' . urlencode($match[1]) . '">' . lang('edit') . '</a></td><td>' . htmlspecialchars(str_replace("''", "'", $match[1])) . "</td><td>" . htmlspecialchars(str_replace("''", "'", $match[2])) . "</td></tr>\n";
-       }
-       echo "</table>\n";
-       $result->free();
+page_header(lang('Privileges'));
+echo '<p><a href="' . htmlspecialchars($SELF) . 'user=">' . lang('Create user') . "</a></p>\n";
+$result = $mysql->query("SELECT User, Host FROM mysql.user ORDER BY Host, User");
+if (!$result) {
+       $result = $mysql->query("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1) AS User, SUBSTRING_INDEX(CURRENT_USER, '@', -1) AS Host");
 }
+echo "<table border='1' cellspacing='0' cellpadding='2'>\n";
+echo "<thead><tr><th>&nbsp;</th><th>" . lang('Username') . "</th><th>" . lang('Server') . "</th></tr></thead>\n";
+while ($row = $result->fetch_assoc()) {
+       echo '<tr><td><a href="' . htmlspecialchars($SELF) . 'user=' . urlencode($row["User"]) . '&amp;host=' . urlencode($row["Host"]) . '">' . lang('edit') . '</a></td><td>' . htmlspecialchars($row["User"]) . "</td><td>" . htmlspecialchars($row["Host"]) . "</td></tr>\n";
+}
+echo "</table>\n";
+$result->free();
diff --git a/user.inc.php b/user.inc.php
new file mode 100644 (file)
index 0000000..9f94203
--- /dev/null
@@ -0,0 +1,168 @@
+<?php
+if ($_POST) {
+       $new_grants = array();
+       foreach ($_POST["objects"] as $key => $val) {
+               $new_grants[$val] = ((array) $new_grants[$val]) + ((array) $_POST["grants"][$key]);
+       }
+}
+$grants = array();
+$old_pass = "";
+if (isset($_GET["host"]) && ($result = $mysql->query("SHOW GRANTS FOR '" . $mysql->escape_string($_GET["user"]) . "'@'" . $mysql->escape_string($_GET["host"]) . "'"))) { //! Use information_schema for MySQL 5 - column names in column privileges are not escaped
+       while ($row = $result->fetch_row()) {
+               if (preg_match('~GRANT (.*) ON (.*) TO ~', $row[0], $match)) { //! escape the part between ON and TO
+                       preg_match_all('~ *([^(,]*[^ ,(])( *\\([^)]+\\))?~', $match[1], $matches, PREG_SET_ORDER);
+                       foreach ($matches as $val) {
+                               $grants["$match[2]$val[2]"][$val[1]] = true;
+                       }
+               }
+               if (preg_match('~ WITH GRANT OPTION~', $row[0])) { //! don't check inside strings and identifiers
+                       $grants[$match[2]]["GRANT OPTION"] = true;
+               }
+               if (preg_match("~ IDENTIFIED BY PASSWORD '([^']+)~", $row[0], $match)) {
+                       $old_pass = $match[1];
+               }
+       }
+       $result->free();
+}
+
+if ($_POST && !$error) {
+       $old_user = $mysql->escape_string($_GET["user"]) . "'@'" . $mysql->escape_string($_GET["host"]);
+       $new_user = $mysql->escape_string($_POST["user"]) . "'@'" . (strlen($_POST["host"]) ? $mysql->escape_string($_POST["host"]) : "%");
+       $identified = " IDENTIFIED BY" . ($_POST["hashed"] ? " PASSWORD" : "") . " '" . $mysql->escape_string($_POST["pass"]) . "'";
+       if ($_POST["drop"]) {
+               if ($mysql->query("DROP USER '$old_user'")) {
+                       redirect($SELF . "privileges=", lang('User has been dropped.'));
+               }
+       } elseif ($old_user == $new_user || $mysql->server_info < 5 || $mysql->query("CREATE USER '$new_user'$identified")) {
+               if ($old_user == $new_user || $mysql->server_info < 5) {
+                       $mysql->query("GRANT USAGE ON *.* TO '$new_user'$identified");
+               }
+               $revoke = array();
+               foreach ($new_grants as $object => $grant) {
+                       $grant = array_keys($grant);
+                       if ($old_user == $new_user) {
+                               $old_grant = array_keys((array) $grants[$object]);
+                               $revoke = array_diff($old_grant, $grant);
+                               $grant = array_diff($grant, $old_grant);
+                               unset($grants[$object]);
+                       }
+                       if (preg_match('~^(.+)(\\(.*\\))?$~U', $object, $match) && (
+                       ($grant && !$mysql->query("GRANT " . implode("$match[2], ", $grant) . "$match[2] ON $match[1] TO '$new_user'")) //! SQL injection
+                       || ($revoke && !$mysql->query("REVOKE " . implode("$match[2], ", $revoke) . "$match[2] ON $match[1] FROM '$new_user'"))
+                       )) {
+                               $error = $mysql->error;
+                               if ($old_user != $new_user) {
+                                       $mysql->query("DROP USER '$new_user'");
+                               }
+                               break;
+                       }
+               }
+               if (!$error) {
+                       if ($old_user != $new_user) {
+                               $mysql->query("DROP USER '$old_user'");
+                       } else {
+                               foreach ($grants as $object => $revoke) {
+                                       if (preg_match('~^(.+)(\\(.*\\))?$~U', $object, $match)) {
+                                               $mysql->query("REVOKE " . implode("$match[2], ", $revoke) . "$match[2] ON $match[1] FROM '$new_user'");
+                                       }
+                               }
+                       }
+                       redirect($SELF . "privileges=", (isset($_GET["host"]) ? lang('User has been altered.') : lang('User has been created.')));
+               }
+       }
+       if (!$error) {
+               $error = $mysql->error;
+       }
+}
+
+page_header((isset($_GET["host"]) ? lang('Username') . ": " . htmlspecialchars("$_GET[user]@$_GET[host]") : lang('Create user')), array("privileges" => lang('Privileges')));
+$privileges = array();
+$result = $mysql->query("SHOW PRIVILEGES");
+while ($row = $result->fetch_assoc()) {
+       foreach (explode(",", $row["Context"]) as $context) {
+               $privileges[$context][$row["Privilege"]] = $row["Comment"]; //! translation
+       }
+}
+$result->free();
+$privileges["Server Admin"] += $privileges["File access on server"];
+$privileges["Databases"]["Create routine"] = $privileges["Procedures"]["Create routine"];
+$privileges["Columns"] = array();
+foreach (array("Select", "Insert", "Update", "References") as $val) {
+       $privileges["Columns"][$val] = $privileges["Tables"][$val];
+}
+unset($privileges["Server Admin"]["Usage"]);
+unset($privileges["Procedures"]["Create routine"]);
+foreach ($privileges["Tables"] as $key => $val) {
+       unset($privileges["Databases"][$key]);
+}
+//! JS checkbox for all
+
+if ($_POST) {
+       $row = $_POST;
+       $grants = $new_grants;
+       echo "<p class='error'>" . lang('Unable to operate user') . ": " . htmlspecialchars($error) . "</p>\n";
+} else {
+       $row = $_GET;
+       $row["pass"] = $old_pass;
+       if (strlen($old_pass)) {
+               $row["hashed"] = true;
+       }
+       $grants[""] = true;
+}
+
+?>
+<form action="" method="post">
+<table border="0" cellspacing="0" cellpadding="2">
+<tr><th><?php echo lang('Username'); ?></th><td><input name="user" maxlength="16" value="<?php echo htmlspecialchars($row["user"]); ?>" /></td></tr>
+<tr><th><?php echo lang('Server'); ?></th><td><input name="host" maxlength="60" value="<?php echo htmlspecialchars($row["host"]); ?>" /></td></tr>
+<tr><th><?php echo lang('Password'); ?></th><td><input name="pass" value="<?php echo htmlspecialchars($row["pass"]); ?>" /> <label for="hashed"><input type="checkbox" name="hashed" id="hashed" value="1"<?php if ($row["hashed"]) { ?> checked="checked"<?php } ?> /><?php echo lang('Hashed'); ?></label></td></tr>
+</table>
+
+<h3><?php echo lang('Privileges'); ?></h3>
+<?php
+//! MAX_* limits, REQUIRE
+$i = 0;
+foreach (array(
+       "Server Admin" => lang('Server'),
+       "Databases" => lang('Database'),
+       "Tables" => lang('Table'),
+       "Columns" => lang('Column'),
+       "Procedures" => lang('Routine'),
+) as $key => $val) {
+       if ($privileges[$key]) {
+               echo "<table border='0' cellspacing='0' cellpadding='2'>\n";
+               echo "<thead><tr>";
+               if ($key != "Server Admin") {
+                       echo "<th>$val</th>";
+               }
+               foreach ($privileges[$key] as $privilege => $comment) {
+                       echo '<td title="' . htmlspecialchars($comment) . '">' . htmlspecialchars($privilege) . '</td>';
+               }
+               echo "</tr></thead>\n";
+               foreach ($grants as $object => $grant) {
+                       if ($key == "Server Admin" ? $object == (isset($grants["*.*"]) ? "*.*" : "")
+                       : !$object || (substr($object, -1) == ")" || $key == "Columns" ? substr($object, -1) == ")" xor $key != "Columns"
+                       : (preg_match('~(PROCEDURE|FUNCTION) ~', $object) ? $key == "Procedures"
+                       : (substr($object, -1) == "*" || $key == "Tables"
+                       )))) {
+                               echo "<tr align='center'>";
+                               if ($key != "Server Admin") {
+                                       echo '<th><input name="objects[' . $i . ']" value="' . htmlspecialchars($object) . "\" size='10' /></th>"; //! separate db, table, columns, PROCEDURE|FUNCTION, routine
+                               }
+                               foreach ($privileges[$key] as $privilege => $comment) {
+                                       echo '<td><input type="checkbox" name="grants[' . $i . '][' . htmlspecialchars(strtoupper($privilege)) . ']" value="1"' . ($grant[strtoupper($privilege)] || ($privilege != "Grant option" && $grant["ALL PRIVILEGES"]) ? " checked='checked'" : "") . " /></td>";
+                               }
+                               echo "</tr>\n";
+                               $i++;
+                       }
+               }
+               echo "</table>\n";
+       }
+}
+?>
+<p>
+<input type="hidden" name="token" value="<?php echo $token; ?>" />
+<input type="submit" value="<?php echo lang('Save'); ?>" />
+<?php if (isset($_GET["host"])) { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>" /><?php } ?>
+</p>
+</form>