2011-06-09 20 views
20

he sido incapaz de encontrar una solución razonable para lograr lo siguiente:MySQL conceder privilegios a todas las bases de datos, excepto una mesa de

Deseo tener un usuario con todos los privilegios en una base de datos (o una serie de bases de datos con el mismo esquema), excepto para una tabla, a la que solo tendrán privilegios SELECT.

Básicamente quiero que el usuario tenga dominio libre sobre una base de datos pero no pueda actualizar una tabla específica.

Hasta ahora no lo han intentado, sin éxito: (. Nombre_base_de_datos *)

  • concesión de todos los privilegios de esa base de datos y luego conceder específicamente sólo privilegios en esa tabla deseada (la esperanza de que sobrescribir el " todo ", estúpido, lo sé).

  • Otorgando todos los privilegios en esa base de datos (db_name. *) Luego revocando insert, update, y delete. Pero esto produjo un error al decir que no había una regla de concesión para db_name.table_name.

Según lo que he podido reunir, tendré que otorgar individualmente todos los privilegios en cada tabla de la base de datos, excepto en la tabla de solo lectura.

Por favor, que alguien me diga que hay una manera más fácil

Nota: estoy corriendo MySQL 5.1. La última disponible en Ubuntu 10.04.

+0

¿Cuál es su versión de MySQL? – Devart

+0

Lo sentimos debería haber dicho esto, es 5.1 – xzyfer

+0

1. ¿Qué hay de usar dos bases de datos? Quiero decir que podrías almacenar una tabla especial en la segunda base de datos. 2. ... He preguntado sobre la versión, porque en MySQL 5.5 esto podría hacerse con declaraciones preparadas. – Devart

Respuesta

6

AFAIK, sí, debe otorgar de forma individual por mesa. Pero oye, tienes una computadora allí. Las computadoras son grandes en la automatización de tareas repetitivas para usted, así que ¿por qué no hacer un script que hace lo siguiente:

  1. obtener una lista de todas las tablas en la base de datos (SHOW TABLES;)
  2. Para cada elemento de la lista, conceder todos los permisos
  3. permisos Revocar en la mesa especial

O, alternativamente: 2. Para cada elemento de la lista, compruebe si se trata de la mesa especial; si es no, conceda todos los permisos

La razón por la que no estoy dando código es que se puede hacer en cualquier lenguaje de scripting con instalaciones de MySQL, incluso script de shell; usa lo que te resulte más cómodo usar.

+4

Si bien esta solución funciona ahora, si alguna vez agrega tablas a la base de datos, tendrá que agregar permisos para cada usuario para las nuevas tablas No parece haber una manera de simplemente agregar permisos en * pero tener anti-permisos en una tabla específica. –

+0

¿Realmente no hay forma de hacer esto excepto de esta manera? No parece correcto. Me gustaría menos de mysql. Necesito hacer esto también. – Para

25

Sé que esta es una publicación anterior, pero pensé que agregaría @tdammers question para que otros las vean. También puede realizar SELECCIONAR CONCAT en information_schema.tables para crear sus comandos de concesión y no tener que escribir un script separado.

Primera revocar todos los privilegios de que DB:

REVOKE ALL PRIVILEGES ON db.* FROM [email protected]; 

A continuación, crear la formulación de subvención:

SELECT CONCAT("GRANT UPDATE ON db.", table_name, " TO [email protected];") 
FROM information_schema.TABLES 
WHERE table_schema = "YourDB" AND table_name <> "table_to_skip"; 

copiar y pegar los resultados en el cliente de MySQL y ejecutar todas.

+1

para usar excepciones de 'comodín' en lugar de usar 'AND table_name <>' use 'Y table_name NO COMO"% _something _% "' –

+0

Esto es * realmente * útil. :) – Bowi

1

Aquí hay un borrador de lo que uso para otorgar roles en MariaDB. Tal vez establecer un EVENTO sería más genial :-)

DELIMITER $$ 

DROP PROCEDURE IF EXISTS refreshRoles $$ 
CREATE PROCEDURE refreshRoles() 
    COMMENT 'Grant SELECT on new databases/tables, revoke on deleted' 
BEGIN 
    DECLARE done BOOL; 
    DECLARE db VARCHAR(128); 
    DECLARE tb VARCHAR(128); 
    DECLARE rl VARCHAR(128); 
    DECLARE tables CURSOR FOR 
    SELECT table_schema, table_name, '_bob_live_sg' FROM information_schema.tables 
    WHERE table_schema LIKE '%bob\_live\_sg' AND 
     ( false 
     OR table_name LIKE 'bundle%' 
     OR table_name LIKE 'cart%' 
     OR table_name LIKE 'catalog%' 
     OR table_name LIKE 'url%' 
    ); 

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true; 

    CREATE ROLE IF NOT EXISTS '_bob_live_sg'; 
    REVOKE ALL, GRANT OPTION FROM '_bob_live_sg'; 

    OPEN tables; 
    SET done = false; 
    grant_loop: LOOP 
    FETCH tables INTO db, tb, rl; 
    IF done THEN 
     LEAVE grant_loop; 
    END IF; 
    SET @g = CONCAT('GRANT SELECT ON `', db, '`.`', tb, '` TO ', rl); 
    PREPARE g FROM @g; 
    EXECUTE g; 
    DEALLOCATE PREPARE g; 
    END LOOP; 
    CLOSE tables; 
END $$ 

DELIMITER ; 

CALL refreshRoles; 
Cuestiones relacionadas