Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   GRANT desde Delphi (https://www.clubdelphi.com/foros/showthread.php?t=81691)

mRoman 08-12-2012 06:09:57

GRANT desde Delphi
 
Hola amigos foreros de nuevo con una consulta, la cual SÉ DE ANTEMANO QUE YA SE HA TRATADO ESTE TEMA AMPLIAMENTE, pero por lo mismo que no logro encontrar la respuesta es que posteo mis dudas.

Se trata del porque no se puede asignar un rol a un usuario firebird 1.5 desde Delphi6 con la siguiente instruccion:

GRANT rol TO usuario

Para lo anterior ya consulte algunos hilos de este foro:
http://www.clubdelphi.com/foros/showthread.php?t=36622
http://www.clubdelphi.com/foros/show...ignar+permisos
y algunos otros en Google. Para ejecutar la instruccion GRANT use el componente IBSql (en algun hilo consultado el posteador lo uso).....


Ahora lo mas raro es q tampoco desde IBExpert puedo asignar un rol usando las instrucciones....mediante sus opciones del menu principal no tengo problemas, pero desde el Script Executive no hace nada, no marca error pero tampoco hace nada.

Despues por ahi vi que en la version de Firebird 2.5 incluia este tipo de mantenimientos....es verdad esto? porque me baje la version 2.5 e intente hacer lo mismo, es decir, desde el Script Executive, ejecutar "grant rol to usuario" y never ...nada !....

El Rol ya esta creado, con sus privilegios.

Uso: S.O. Windows 7 Ultimate.

ecfisa 08-12-2012 11:14:25

Hola mRoman.

Te pongo un ejemplo simple para que pruebes:
Código Delphi [-]
// Crea rol, usuario y lo agrega al rol
procedure TForm1.btCrearClick(Sender: TObject);
begin
  // Crear rol
  IBSQL1.Close;
  IBSQL1.SQL.Text:= 'CREATE ROLE ABCXYZ';
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Rol existente');
  end;
  // Crear usuario
  IBSQL1.Close;
  IBSQL1.SQL.Clear;
  IBSQL1.SQL.Add('CREATE USER PEPITO PASSWORD ''1234''');
  IBSQL1.SQL.Add('FIRSTNAME ''JOSE'' MIDDLENAME ''APOLONIO'' LASTNAME ''PEREZ''');
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Usuario existente');
  end;
  // Asignar rol al usuario
  IBSQL1.Close;
  IBSQL1.SQL.Text:= 'GRANT ABCXYZ TO PEPITO';
  IBSQL1.ExecQuery;
  IBTransaction1.CommitRetaining;
end;

// Mostrar los usuarios del rol ABCXYZ
procedure TForm1.btMostrarClick(Sender: TObject);
begin
  with IBQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT RDB$USER AS USUARIO,RDB$RELATION_NAME AS ROL');
    SQL.ADD('FROM RDB$USER_PRIVILEGES');
    SQL.Add('WHERE RDB$RELATION_NAME = ''ABCXYZ''');
    SQL.Add('ORDER BY RDB$USER');
    Open;
  end;
end;

//  Borra rol y usuario
procedure TForm1.btBorrarClick(Sender: TObject);
begin
 IBSQL1.Close;
  IBSQL1.SQL.Text:= 'DROP ROLE ABCXYZ';
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Rol inexistente');
  end;
  
  IBSQL1.Close;
  IBSQL1.SQL.Text:= 'DROP USER PEPITO';
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Usuario inexistente');
  end;
end;

Saludos.

mRoman 08-12-2012 19:45:11

Gracias..
 
Cita:

Empezado por ecfisa (Mensaje 451462)
Hola mRoman.

Te pongo un ejemplo simple para que pruebes:
Código Delphi [-]
// Crea rol, usuario y lo agrega al rol
procedure TForm1.btCrearClick(Sender: TObject);
begin
  // Crear rol
  IBSQL1.Close;
  IBSQL1.SQL.Text:= 'CREATE ROLE ABCXYZ';
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Rol existente');
  end;
  // Crear usuario
  IBSQL1.Close;
  IBSQL1.SQL.Clear;
  IBSQL1.SQL.Add('CREATE USER PEPITO PASSWORD ''1234''');
  IBSQL1.SQL.Add('FIRSTNAME ''JOSE'' MIDDLENAME ''APOLONIO'' LASTNAME ''PEREZ''');
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Usuario existente');
  end;
  // Asignar rol al usuario
  IBSQL1.Close;
  IBSQL1.SQL.Text:= 'GRANT ABCXYZ TO PEPITO';
  IBSQL1.ExecQuery;
  IBTransaction1.CommitRetaining;
end;

// Mostrar los usuarios del rol ABCXYZ
procedure TForm1.btMostrarClick(Sender: TObject);
begin
  with IBQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT RDB$USER AS USUARIO,RDB$RELATION_NAME AS ROL');
    SQL.ADD('FROM RDB$USER_PRIVILEGES');
    SQL.Add('WHERE RDB$RELATION_NAME = ''ABCXYZ''');
    SQL.Add('ORDER BY RDB$USER');
    Open;
  end;
end;

//  Borra rol y usuario
procedure TForm1.btBorrarClick(Sender: TObject);
begin
 IBSQL1.Close;
  IBSQL1.SQL.Text:= 'DROP ROLE ABCXYZ';
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Rol inexistente');
  end;
  
  IBSQL1.Close;
  IBSQL1.SQL.Text:= 'DROP USER PEPITO';
  try
    IBSQL1.ExecQuery;
    IBTransaction1.CommitRetaining;
  except
    raise Exception.Create('Usuario inexistente');
  end;
end;

Saludos.

Ok....gracias ecfisa, fijate que hice algo parecido, pero no me funciono....lo que veo de diferente es el componente IBTransaction1.CommitRetaining.....NO LO PUSE !!!!....será esta la causa?, probaré y les comento.

Con respecto a la version de Firebird...cual estas usando?

ecfisa 08-12-2012 19:50:48

Cita:

Empezado por mRoman (Mensaje 451482)
Ok....gracias ecfisa, fijate que hice algo parecido, pero no me funciono....lo que veo de diferente es el componente IBTransaction1.CommitRetaining.....NO LO PUSE !!!!....será esta la causa?, probaré y les comento.

Con respecto a la version de Firebird...cual estas usando?

Hola mRoman.

Muy probablemente sea la causa. La versión que uso es la 2.5 y el ejemplo lo hice en Delphi 7.

Saludos. :)

mRoman 08-12-2012 22:08:59

GRANT no funciona
 
Cita:

Empezado por ecfisa (Mensaje 451483)
Hola mRoman.

Muy probablemente sea la causa. La versión que uso es la 2.5 y el ejemplo lo hice en Delphi 7.

Saludos. :)

Ok...sabes que ecfisa, solicitanto tu apoyo y el de los demas foreros.....

este es el codigo q estoy tratando de que funcione:
Código Delphi [-]
unit Usuarios;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IBServices, StdCtrls, Buttons, Mask, ExtCtrls, DBCtrls, Grids,
  DBGrids, DB, IBCustomDataSet, IBQuery, sSkinProvider, IBSQL;

type
  TfrmUsuarios = class(TForm)
    ibUsuario: TIBSecurityService;
    btnCrear: TBitBtn;
    edUserName: TEdit;
    edFirstName: TEdit;
    edMiddleName: TEdit;
    edLastName: TEdit;
    mskPassword: TMaskEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    Panel4: TPanel;
    cbxInstitucion: TDBLookupComboBox;
    Label6: TLabel;
    dSoInstitucion: TDataSource;
    qryInstitucion: TIBQuery;
    Label7: TLabel;
    cbxCT: TDBLookupComboBox;
    GroupBox1: TGroupBox;
    DBGrid1: TDBGrid;
    dSoCT: TDataSource;
    qryCT: TIBQuery;
    Label8: TLabel;
    sSkinProvider1: TsSkinProvider;
    qryUsuarios: TIBQuery;
    dSoUsuarios: TDataSource;
    dsUsuario: TIBDataSet;
    cbxRoles: TComboBox;
    btnBorrar: TBitBtn;
    IBSQLRol: TIBSQL;
    procedure btnCrearClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure cbxCTExit(Sender: TObject);
    procedure Panel1Exit(Sender: TObject);
    procedure DBGrid1CellClick(Column: TColumn);
    procedure btnBorrarClick(Sender: TObject);
    procedure Panel1Enter(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmUsuarios: TfrmUsuarios;

implementation
uses DataModulo;
{$R *.dfm}

{function ArchivosCarpeta(Carpeta, Mascara: String; IncluirPath, IncluirOcultos: Boolean): tStringList;
var DirInfo: TSearchRec;
    I, TiposDeArchivo: Integer;
begin
  Result := tStringList.Create;
  TiposDeArchivo := faAnyfile -faSysFile -faDirectory;
  if not IncluirOcultos then
      TiposDeArchivo := TiposDeArchivo -faHidden;
  I := FindFirst(IncludeTrailingPathDelimiter(Carpeta) + Mascara, TiposDeArchivo, DirInfo);
  while I = 0 do
  begin
    if (DirInfo.Name <> '.') and (DirInfo.Name <> '..') then
    begin
      if IncluirPath then
          Result.Add(IncludeTrailingPathDelimiter(Carpeta) + ExtractFileName(DirInfo.Name))
      else
          Result.Add(ExtractFileName(DirInfo.Name));
    end;
    I := FindNext(DirInfo);
  end;
  FindClose(DirInfo);
end;}

procedure TfrmUsuarios.btnCrearClick(Sender: TObject);
begin
    if btnCrear.Caption='Crear' then
    begin
        ibusuario.UserName:=edUserName.Text;
        ibUsuario.FirstName:=edFirstName.Text;
        ibUsuario.MiddleName:=edMiddleName.Text;
        ibUsuario.LastName:=edLastName.Text;
        ibUsuario.Password:=mskPassword.Text;
//        ibUsuario.Attach;
        ibUsuario.AddUser;
        ibUsuario.Detach;

        IBSQLRol.Close;
        IBSQLRol.SQL.Clear;
        IBSQLRol.SQL.Add('GRANT ' +cbxRoles.Text+ ' TO '+edUserName.Text);
        IBSQLRol.Prepare;
        IBSQLRol.ExecQuery;
        DataModule2.trsCasas.Commit;

        dsUsuario.Close;
        dsUsuario.ParamByName('ct_clave').AsInteger:=cbxCT.KeyValue;
        dsUsuario.ParamByName('inter_clave').AsInteger:=cbxInstitucion.KeyValue;
        dsUsuario.ParamByName('nombre_usuario').AsString:=edUserName.Text;
        dsUsuario.Open;
        dsUsuario.Append;
        dsUsuario.FieldByName('USUARIO_CT_CLAVE').AsInteger:=cbxCT.KeyValue;
        dsUsuario.FieldByName('USUARIO_NOMBRE').AsString:=edUserName.Text;
        dsUsuario.FieldByName('USUARIO_INTER_CLAVE').AsInteger:=cbxInstitucion.KeyValue;
        dsUsuario.FieldByName('USUARIO_NOMBRE_PILA').AsString:=edFirstName.Text;
        dsUsuario.FieldByName('USUARIO_APELLIDO_PATERNO').AsString:=edMiddleName.Text;
        dsUsuario.FieldByName('USUARIO_APELLIDO_MATERNO').AsString:=edLastName.Text;
        dsUsuario.Post;
        dsUsuario.ApplyUpdates;
        DataModule2.trsCasas.Commit;
    end Else
    begin
        ibusuario.UserName:=edUserName.Text;
        ibUsuario.FirstName:=edFirstName.Text;
        ibUsuario.MiddleName:=edMiddleName.Text;
        ibUsuario.LastName:=edLastName.Text;
        ibUsuario.Password:=mskPassword.Text;
        ibUsuario.Attach;
        ibUsuario.ModifyUser;
        ibUsuario.Detach;
    end
end;

procedure TfrmUsuarios.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    Action:=caFree;
end;

procedure TfrmUsuarios.FormShow(Sender: TObject);
var
   sr:TSearchRec;
begin
    ibUsuario.Active:=True;
    cbxRoles.Items.Clear;
    if FindFirst('c:\CISistema\Roles\*.ibg',faArchive, sr)=0 then
    begin
        repeat
            cbxRoles.Items.Add(copy(sr.Name,1,length(sr.Name)-4));
        until FindNext(sr)<>0;
        FindClose(sr);
    end;
//    cbxRoles.Items:=ArchivosCarpeta('C:\CISistema\Roles\','*.ibg',False,False);
end;

procedure TfrmUsuarios.cbxCTExit(Sender: TObject);
begin
    qryInstitucion.Close;
    qryInstitucion.ParamByName('CT_CLAVE').AsInteger:=cbxCT.KeyValue;
    qryInstitucion.Open;
    qryInstitucion.FetchAll;

end;

procedure TfrmUsuarios.Panel1Exit(Sender: TObject);
begin
    qryUsuarios.Close;
    qryUsuarios.ParamByName('INTER_CLAVE').AsInteger:=cbxInstitucion.KeyValue;
    qryUsuarios.ParamByName('CT_CLAVE').AsInteger:=cbxCT.KeyValue;
    qryUsuarios.Open;
end;

procedure TfrmUsuarios.DBGrid1CellClick(Column: TColumn);
begin
     btnCrear.Caption:='Modificar';
     btnBorrar.Enabled:=True;
     edUserName.Text:=qryUsuarios.fieldbyname('usuario_nombre').AsString;
end;

procedure TfrmUsuarios.btnBorrarClick(Sender: TObject);
begin
//        ibusuario.UserName:=edUserName.Text;
        ibUsuario.Attach;
        ibUsuario.DeleteUser;
        ibUsuario.Detach;
end;

procedure TfrmUsuarios.Panel1Enter(Sender: TObject);
begin
    edUserName.Text:='';
    edFirstName.Text:='';
    edMiddleName.Text:='';
    edLastName.Text:='';
    mskPassword.Text:='';
    cbxRoles.ItemIndex:=-1;
    DataModule2.trsCasas.Active:=False;
    DataModule2.trsCasas.StartTransaction;
    qryCT.Close;
    qryCT.Open;
    qryCT.FetchAll;
    btnBorrar.Enabled:=False;
end;

end.

Estoy usando los siguientes componentes:
TIBSecurityService.- Para crear los usuarios en el security2.fdb
TIBSQL.-Para asignarle el ROL a los usuarios (previamente creado desde el IBManager con sus privilegios).
TIBQuery.- Para obtener algunos registros de algunas tablas.
TIBDataSet.- Para registrar a los usuarios creados (en mi base de datos...no confundir con security2.fdb).

Ya desinstale el Firebird 1.5 e instale la 2.5, uso Delphi6 con Win 7 ultimate.

Saludos y espero me puedan auxiliar....gracias por su tiempo muchachos.

mRoman 08-12-2012 22:31:00

GRANT no funciona
 
Fijense que el código se ejecuta sin problemas, pero no le asigna el los privilegios al usuario nuevo, reviso mediante estas instrucciones
Código SQL [-]
SELECT RDB$USER AS USUARIO,RDB$RELATION_NAME AS ROL
FROM RDB$USER_PRIVILEGES
where rdb$user='MMAXIMO'
ORDER BY RDB$USER

y en la columna de ROL tiene registrado "CAPTURISTA" ...entonces ya no entiendo.....que puede estar pasando?. Reviso con el IBManager los privilegios asignados al usuario y no tiene asignado nada !!, estan en blanco....usando las opciones del IBManager para asignar el ROL al usuario no tengo problemas...pero si lo hago mediante sentencia SQL (grant CAPTURISTA to MMAXIMO) ...NO HACE NADA !!..NO ASIGNA NADA !!.

Existe alguna diferencia entre "commit" y "commitretainig" para este caso?

Saludos

ecfisa 10-12-2012 07:56:02

Hola mRoman.
Cita:

Existe alguna diferencia entre "commit" y "commitretainig" para este caso?
No, no en este caso. Utilicé CommitRetaining para reducir el código, pero se podría hacer con Commit sin ningún problema.

A ver si podemos echarle mas luz al asunto con algunos ejemplos simples.

Las acciones a tomar son:
  • Crear un rol
  • Darle privilegios
  • Crear un usuario
  • Asignarle el rol


Script ejemplo:
Código SQL [-]
CREATE ROLE ROLCLIENTE;
GRANT SELECT ON HORARIOS TO ROLCLIENTE;  
CREATE USER PEPE PASSWORD '1234' FIRSTNAME 'JOSE' MIDDLENAME 'APOLONIO' LASTNAME 'PEREZ';
GRANT ROLCLIENTE TO PEPE;

Desde Delphi:
Código Delphi [-]
 with IBSQL1 do
  begin
    Close;
    SQL.Text := 'CREATE ROLE ROLCLIENTE';
    ExecQuery;
    IBTransaction1.CommitRetaining;
    Close;
    SQL.Text := 'GRANT SELECT ON HORARIOS TO ROLCLIENTE';
    ExecQuery;
    IBTransaction1.CommitRetaining;
    SQL.Text := 'CREATE USER PEPE PASSWORD ''1234'' FIRSTNAME ''JOSE'''+
                'MIDDLENAME ''APOLONIO'' LASTNAME ''PEREZ''';
    ExecQuery;
    IBTransaction1.CommitRetaining;
    Close;
    SQL.Text := 'GRANT ROLCLIENTE TO PEPE';
    ExecQuery;
    IBTransaction1.CommitRetaining;
  end;

Luego de creado, como siempre antes de abrir el TIBDatabase debes contar con el nombre, la contraseña del usuario... Y ahora también el nombre del rol para pasarlo como parámetro con los anteriores.

Y seguramente me vas a preguntar: ¿ De donde saco la lista de roles del candidato para mostrarlos y que pueda elegir con cuál entra ?

Un ejemplo:
Código Delphi [-]
...
procedure TForm1.GetUsrRoles(const UserName: string; TS: TStrings);
begin
  with IBQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT RDB$RELATION_NAME AS ROLNAME');
    SQL.Add('FROM RDB$USER_PRIVILEGES');
    SQL.Add('WHERE RDB$PRIVILEGE = ''M'' AND RDB$USER = :PNAME');
    ParamByName('PNAME').AsString:= UserName;
    Open;
    while not Eof do
    begin
      TS.Add(FieldByName('ROLNAME').AsString);
      Next
    end;
    Close
  end;
end;

// Ejemplo de llamada
procedure TForm1.EditNombreExit(Sender: TObject);
begin
   GetUsrRoles(EditNombre.Text,ComboBox1.Items);
end;
...
Si el usuario PEPE tiene asignado mas de un rol, los privilegios que adquirirá, se corresponderán con el rol que haya elegido previamente a conectarse:
Código Delphi [-]
begin
  with IBDatabase1 do
  begin
    Close;
    DatabaseName := 'SERVER:C\Carpeta\SubCarpeta\BaseDatos.FDB';
    LoginPrompt:= False;
    Params.Clear;
    Params.Add('user_name=' + EditNombre.Text);
    Params.Add('password=' + EditPassword.Text);
    Params.Add('sql_role_name=' + ComboBox1.Text);
  try
    Open;
  except
    on E: Exception do
    begin
      MessageDlg(E.Message, mtError, [mbOk], 0);
      raise
    end
  end
end;

Saludos.

mRoman 10-12-2012 16:51:33

Ok...te agradezco.

Fijate que dando un poco de antecedente, te diré que la base de datos la creé en Firebird 1.5 y sobre ella hice las pruebas....pero déspues desinstalé la 1.5 y re-instalé la 2.5 y empecé nuevamente ....es decir creé de nuevo la base, los roles y asginé privilegios...y lo que yo estaba haciendo era verificar seleccionando del menú del IBExpert, la opcion GRANT MANAGER y no mostraba los privilegios del usuario....es decir estaban en blanco....y yo estaba suponiendo que no lo estaba haciendo, pero luego me conecté con el usuario y SORPRESA....si TENIA LOS PRIVILEGIOS ASIGNADOS.....NO DE MANERA VISUAL, PERO SI EN LA BASE DE DATOS....raro no?

Te comento que ya me pude concectar con el usuario creado desde mi aplicación y donde también desde la misma, le asigné privilegios de "capturista"....y se conectó ya sin problemas y pude realizar movimientos a la base con este usuario, validando obviamente los privilegios asignados.

Me parece algo extraño que el IBExpert no muestre de manera visiual los privilegios que le asignes desde sentencias SQL.

Te agradezco tu tiempo para ayudarme a resolver mi problema.


La franja horaria es GMT +2. Ahora son las 13:46:46.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi