O Firebird tornou-se, com toda certeza, um dos SGBD’s free mais utilizados na comunidade Delphi. E não foi à toa que isso aconteceu. Ele é um banco de dados leve, robusto, fácil de gerenciar e o melhor de tudo: grátis. Além dos diversos recursos que o Firebird nos proporciona, não podemos nos esquecer de um fator essencial na escolha de um banco: segurança. Basear-se em desempenho, custo e ferramentas não é tudo se o banco não tiver um nível de segurança aceitável. Nessa edição preparei uma série de dicas para a utilização do sistema de usuários e roles do Firebird. Veremos como utilizar o esquema de privilégios, como revogar (“revoke”) ou aplicar direitos (“grant”) a tabelas e campos. Aprenderemos a usar o aplicativo GSEC para criação de usuários e como utilizá-los em nossas aplicações.

Entendendo o GSEC

O Firebird possui uma série de utilitários em sua pasta bin no diretório de instalação, tais como: gbak, gfix e claro o gsec. O gsec é um utilitário para gerenciamento de usuários e senhas do banco de dados. Com ele conseguimos incluir, excluir e modificar usuários e roles. Ele roda por linha de comando localmente ou remotamente e é normalmente utilizado pelo administrador do banco ou DBA. Toda a operação é feita em cima do arquivo security.fdb, onde todos os privilégios são guardados. Esse arquivo está situado no diretório de instalação do SGBD, normalmente em C:\Arquivos de Programas\Firebird\Firebird_Versao. Vamos a uma visão geral do aplicativo.

Nota: A partir da versão 2.0 do Firebird, o arquivo de segurança do banco passou a chamar-se de security2.fdb para diferenciar das versões abaixo de 2.0. Espera-se para a vesão 3.0, denominada Vulcan, que o security não seja mais um arquivo separado e sim parte do banco de dados.

Até a data deste artigo o código do Vulcan é mantido pelo Jim Starkley e está sendo embutido no novo Firebird. Entre as metas para o novo Firebird estão:

  • Portabilidade: O Vulcan foi desenvolvido simultaneamente para quatro plataformas que são: 32 bits usando o compilador Microsoft Visual Studio 7, 32 e 64 bits, Linux para AMD64 usando várias versões do GCC (“Compilador Linux”) e 64 bits para Solaris usando o compilador Sun Forte C++;
  • Performance: Maior performance em vista do Firebird 1.5. A equipe da FirebirdSQL tem como meta aumentar ainda mais a velocidade de acesso e processamento do Firebird;
  • Segurança: Integração do security.fdb ao banco de dados. Isso siginifica que não existirá mais um arquivo separado para guardar senhas do usuário SYSDBA e demais, tornando assim ainda mais seguro o SGBD;

Para melhor entender todo o desenvolvimento dessa nova versão aconselho acessar o link www.ibphoenix.com que contém todas as informações necessárias incluindo um documento em PDF sobre o Overview do Vulcan.

Comandos do GSEC

A inclusão de usuários, bem como a definição de sua senha, é feita utilizando-se os comandos add e –pw, respectivamente. Veja um exemplo a seguir:


GSEC>add ADRIANO –pw 123456

Em seguida, para termos certeza de que o usuário foi adicionado com sucesso, podemos usar o comando display que mostra todos os usuários do banco, como a seguir (Figura 1):


GSEC>display
Todos os usuários criados no banco
Figura 1. Todos os usuários criados no banco

Como podemos notar na Figura 1, temos como usuários além do SYSDBA os nomes ADRIANO, JOSE, GUINTHER e JOANA. Note também que o prompt está diferente apresentando GSEC> ao invés do convencional C:\, isso porque estamos acessando a área de administração do Firebird. Com o Firebird instalado em seu computador, abra uma janela de prompt do DOS e entre na pasta bin do Firebird. No meu caso fica situada em:


C:\Program Files\Firebird\Firebird_2_1\bin

Perceba que já estou usando a versão 2.1.0 RC2, ainda em beta teste. Ao entrar no diretório digite a linha de comando em seguida:


C:\Program Files\Firebird\Firebird_2_1\bin>gsec –user SYSDBA –pw masterkey

Esse comando é usado para logar-se no banco de dados e ter acesso a todos os seus recursos. Perceba que o prompt do DOS muda para GSEC> como mencionado anteriormente e agora já temos condições de executar nossos testes. Crie um novo usuário usando a linha de comando que vimos anteriormente, ou seja:


GSEC>add ADRIANO –pw 123456

Em seguida digite display e tecle enter. Facilmente notamos que o usuário ADRIANO foi incluído com sucesso. Para testarmos se ele tem acesso ao SGBD vamos sair do banco usando o comando quit. Em seguida tente conectar-se usando o comando a seguir:


GSEC>gsec –user ADRIANO –password 123456

Se o prompt de comando virar para GSEC> é porque temos total acesso ao servidor. Retorne ao usuário SYSDBA e vamos fazer um teste de exclusão. Para excluir um usuário basta usar o comando delete conforme segue:


GSEC>delete ADRIANO

Como podemos ver a inclusão e exclusão de usuários é bem simples. Vejamos agora como modificar as configurações de conta de um usuário usando o comando modify. Todos os usuários do banco de dados podem ter fname (“primero nome”), mname (“nome do meio”) ou lname (“último nome”). Vamos aprender agora como modificar esses parâmetros. Para o usuário ADRIANO vamos adicionar o primeiro, segundo e último nome. Volte ao prompt e digite:


GSEC>modify ADRIANO –fname ADRIANO –mname SILVA –lname SANTOS

Em seguida podemos invocar o comando display seguido do nome do usuário, como podemos ver em seguida. O GSEC nos retornará uma tela como a Figura 2. Veja um fato interessante, o último campo mostrado pelo display é uma concatenação dos três parâmetros anteriores, portanto a tabela de usuários do Firebird possui os campos FIRST_NAME, MIDDLE_NAME, LAST_NAME e FULL_NAME:


GSEC>display ADRIANO
Mostrando as informações de ADRIANO
Figura 2. Mostrando as informações de ADRIANO.

A modificação de senha de usuário segue o mesmo esquema anterior. Basta usarmos o comando display juntamente com o parâmetro –pw, veja:


GSEC>display ADRIANO –pw 456

No exemplo anterior estamos modificando a senha do usuário ADRIANO para 456.

Conectando-se ao banco pela aplicação

A grande maioria dos desenvolvedores costuma utilizar o usuário e senha do Firebird (usuário:SYSDBA e senha: masterkey) para conectar sua aplicação ao banco de dados, o que não é aconselhável. O correto seria utilizar os usuários criados diretamente no SGBD e dar privilégios e acesso a cada um deles ou a grupos, os roles. Nessa seção veremos como fazer isso utilizando os componentes DBExpress.

Antes de mais nada criaremos um banco de dados para efetuarmos nossos testes. Para isso utilize seu gerenciador preferido para trabalhar com SGBD’s Firebird e crie um arquivo com o nome Seguranca.fdb e nele adicione uma tabela de CLIENTES conforme o script da Listagem 1. Inclua alguns registros nela para que possamos efetuar os testes.

Listagem 1. Estrutura de criação do banco e tabelas.

SET SQL DIALECT 3;

SET NAMES WIN1252;

 

CREATE DATABASE '\Seguranca.fdb'

USER 'SYSDBA' PASSWORD 'masterkey'

PAGE_SIZE 8192

DEFAULT CHARACTER SET WIN1252;

 

CREATE GENERATOR GEN_CLIENTES_ID;

SET GENERATOR GEN_CLIENTES_ID TO 3;

 

CREATE TABLE CLIENTES (

    ID        INTEGER NOT NULL,

    NOME      VARCHAR(40),

    ENDERECO  VARCHAR(200),

    CIDADE    VARCHAR(40),

    ESTADO    VARCHAR(2),

    CEP       VARCHAR(9)

);

ALTER TABLE CLIENTES ADD CONSTRAINT PK_CLIENTES

  PRIMARY KEY (ID);

SET TERM ^ ;

/* Trigger: CLIENTES_BI */

CREATE TRIGGER CLIENTES_BI FOR CLIENTES

ACTIVE BEFORE INSERT POSITION 0

AS

BEGIN

  IF (NEW.ID IS NULL) THEN

    NEW.ID = GEN_ID(GEN_CLIENTES_ID,1);

END

SET TERM;

Abra o Delphi e crie um nova aplicação salvando-a como Seguranca.dpr. Na tela principal inclua um componente SQLConnection(“sqlConexao”) da paleta dbExpress. Clique duas vezes no componente e configure uma nova conexão de maneira que se conecte a nossa base de dados criada anteriormente. Em seguida inclua um SQLDataSet(“sdsClientes”) conectado ao sqlConexao, um DataSetProvider(“dspClientes”) conectado ao sdsClientes pela propriedade DataSet e por fim um ClientDataSet(“cdsClientes”) ligado ao dspClientes. Na propriedade CommandText do sdsClientes digite uma instrução SQL que traga todos os dados da tabela Clientes, ex.:


SELECT * FROM CLIENTES

Acesse o Fields Editor do cdsClientes e com o botão direito adicione todos os campos da tabela. Para que possamos ver os dados na tela inclua também um DataSource(“dtsClientes”) e um DBGrid(“grdCliente”), ambos ligados aos seus respectivos componentes.

Inclua também dois Edits(“edtUsuario” e “edtSenha”) para usuário/senha e outro para instruções SQL(“edtSQL”). Devemos colocar mais alguns botões para conectar e desconectar, para aplicar instruções SQL e por fim um Button para efetuar ApplyUpdates quando necessário (Figura 3). Se preferir insira um DBNavigator e vincule-o ao dtsClientes.

Tela exemplo para conexão com o banco
Figura 3. Tela exemplo para conexão com o banco.

A primeira coisa que veremos a seguir é “como fazer a conexão de nossa aplicação com o banco de dados usando um usuário específico”. Basicamente o que precisamos fazer é alterar em runtime os parâmetros User_Name e Password do sqlConexao. E já que faremos isso em runtime, aproveitamos para limpar todos os parâmetros e renová-los com nosso padrão. Digite o código da Listagem 2 no evento OnClick do botão Conectar.

Observe que estamos utilizando o conteúdo dos campos edtUsuario e edtSenha para informar ao sqlConexao qual usuário e senha, respectivamente, serão usados para conectar-se ao Seguranca.fdb. A programação em si é muito simples de entender. Estamos apenas confirmando se o sqlConexao está conectado e desconectando-o para que possamos limpar seus parâmetros. Em seguida limpamos e adicionamos novamente seus parâmetros, desta vez informando dinamicamente usuário e senha como já foi explicado anteriormente. Por fim conectamos ao banco e caso ocorra tudo bem abrimos o ClientDataSet exibindo os registros da tabela Clientes.

Listagem 2. Código de conexão com o banco.

procedure TForm1.Button1Click(Sender: TObject);

begin

  if sqlConexao.Connected then

    sqlConexao.Connected := False;

 

  with sqlConexao.Params do

  begin

    Clear;

    Add('DriverName=Interbase');

    Add('Database=\SEGURANCA.FDB');

    Add('RoleName=');

    Add('User_Name=' + Edit1.Text);

    Add('Password=' + Edit2.Text);

    Add('ServerCharSet=');

    Add('SQLDialect=3');

    Add('BlobSize=-1');

    Add('CommitRetain=False');

    Add('WaitOnLocks=True');

    Add('ErrorResourceFile=');

    Add('LocaleCode=0000');

    Add('Interbase TransIsolation=ReadCommited');

    Add('Trim Char=False');

  end;

 

  sqlConexao.Connected := True;

  if sqlConexao.Connected then

    cdsClientes.Active := True;

end;

Todas as configurações estando corretas podemos executar a aplicação e testar. Certamente os registros da tabela Clientes retornarão no DBGrid assim que conectarmos ao banco (Figura 4).

Banco de dados conectado usando usuário diferente do SYSDBA
Figura 4. Banco de dados conectado usando usuário diferente do SYSDBA.

Trabalhando com privilégios

Quando conectamos utilizando o usuário SYSDBA, ou seja, o usuário principal também conhecido como Administrador, estamos dando plenos poderes ao sistema para realizar qualquer tipo de operação no SGBD, incluindo execução de Stored Procedures e Triggers. Uma grande maioria de desenvolvedores utiliza desta forma, ou seja, não se preocupa em mudar ou mesmo criar sua própria senha de administrador. Por esse motivo, acaba utilizando por padrão a senha que o próprio banco fornece. Veja na Listagem 3 como o SQLConnection é configurado por default logo quando criamos uma conexão nova. O que podemos ver na listagem é a propriedade Params do sqlConexao. Perceba que nos parâmetros User_Name e Password estamos usando SYSDBA e masterkey, respectivamente.

Listagem 3. Propriedade Params default

DriverName=Interbase

Database=\Seguranca.fdb

RoleName=RoleName

User_Name=SYSDBA

Password=masterkey

ServerCharSet=

SQLDialect=3

BlobSize=-1

CommitRetain=False

WaitOnLocks=True

ErrorResourceFile=

LocaleCode=0000

Interbase TransIsolation=ReadCommited

Trim Char=False

Observe também o parâmetro RoleName. Ele possui o valor RoleName, ou seja, seu default. Nesse ponto estamos utilizando os privilégios do administrador. Mas podemos facilmente mudar esse cenário e fazer com que o sistema utilize os privilégios de cada usuário criado no banco. Vejamos como isso funciona.

Primeiramente faremos uso dos usuários do SGBD sem a utilização de roles, em seguida veremos o que exatamente são roles e como usá-los. Para este artigo usaremos o IBExpert para realizar as operações de manutenção no banco. Portanto no IBExpert abra uma nova janela de scripts usando o menu SQL Editor ou pressione F12. Usaremos o comando Grant para adicionar privilégios e Revoke para removê-los. Retorne ao prompt do GSEC se necessário e inclua novos usuários. Aqui utilizarei os usuários ADRIANO e GUINTHER. Cada um terá seus próprios privilégios.

O usuário ADRIANO terá acesso somente à execução de Select’s, ou seja, ele não poderá incluir, excluir ou alterar registros em determinada tabela. Já o usuário GUINTHER, terá acesso total.

A sintaxe do comando Grant é:


grant [select | insert | delete | update | references | execute | all]

on [table tabela(s)] to [usuario(s) | role(s) | procedures(s) | public]

[with [ grant | admin ] option]

A explicação para cada item é a seguinte:

  • Select: Permite que usuário execute comandos de seleção de registros;
  • Insert, Delete e Update: Como o próprio parâmetro sugere, significa privilégios para inclusão, exclusão e alteração de registros;
  • References: Permite definir chaves estrangeiras;
  • All: Acesso total, incluindo execução de Stored Procedures e Triggers;

Em seguida informamos no Grant para qual(is) tabela(s) os privilégios são válidos (“on table(s)”) e qual(is) usuário(s), role(s) e/ou procedure(s) serão aplicados. Para entender um pouco melhor, vamos fazer um pequeno teste. Digite o script seguinte, execute e confirme clicando no botão Commit Transaction do IBExpert:


GRANT SELECT ON CLIENTES TO ADRIANO;

O script anterior aplica o privilégio apenas para execução de Select na tabela CLIENTES para o usuário ADRIANO. Execute novamente a aplicação e experimente conectar-se ao banco de dados usando o usuário ADRIANO. Certamente a conexão e a seleção dos dados serão feitas normalmente, porém se tentarmos alterar um registro, gravar e efetuar um ApplyUpdates, veremos que uma exceção será levantada e a operação não será confirmada. Para testarmos, faça uma chamada ao método ApplyUpdates em um dos Buttons da tela e faça novamente o teste, desta vez simulando a alteração de um registro qualquer. Veja a exceção gerada na Figura 5.

Exceção gerada pelo ApplyUpdates
Figura 5. Exceção gerada pelo ApplyUpdates.

A mensagem gerada pelo Delphi, como podemos perceber, foi “no permission for update/write access to TABLE CLIENTES”. Isso porque o usuário ADRIANO não possui permissão para escrita na tabela CLIENTES. O erro só será notado ao executar o botão que possui a chamada ao método ApplyUpdates devido ao fato de estarmos usando a estrutura de acesso bidirecional, ou seja, SQLConnection > SQLDataSet > DataSetProvider > ClientDataSet. Em outras palavras, o Post executado no botão Save do DBNavigator ou mesmo se tivéssemos um botão separado para isso, não geraria tal exceção, já que os dados estão carregados na memória ClientDataSet e somente são enviados ao banco por meio do ApplyUpdates.

Façamos um novo teste agora. Vamos dar permissão total ao usuário GUINTHER e tentar fazer alterações no banco. Para isso, volte ao IBExpert e digite o comando a seguir:


GRANT ALL ON CLIENTES TO GUINTHER;

Execute o script, aplique um commit e logo em seguida abra nossa aplicação teste. Para testarmos novamente, utilize o usuário GUINTHER. Logo perceberá que o erro não ocorre. O parâmetro ALL significa que estamos dando total acesso ao usuário, por isso ele poderá selecionar (“Select”), incluir (“Insert”), excluir (“Delete”), atualizar (“Update”) além de executar Stored Procedures e Triggers.

Revogando privilégios

O Revoke é um comando contrário ao Grant, ou seja, ele revoga os direitos que o usuário tem sobre determinada tabela, view etc. Sua sintaxe é bem simples:


revoke [select | insert | delete | update | references | execute | all]

on [table tabela(s)] from [usuario(s) | role(s) | procedures(s) | public]

A explicação para cada parâmetro é a mesma encontrada no comando Grant, porém com sentido contrário como já explicado. Em outras palavras quando usamos revoke, estamos retirando o direito do usuário sobre tal operação. Ex.:


REVOKE DELETE ON CLIENTES FROM GUINTHER;

Estamos retirando o direito do usuário GUINTHER de fazer exclusões no banco de dados. Rode a aplicação novamente e faça o teste. Você receberá como exceção a mensagem que vimos ao tentarmos alterar um registro com o usuário ADRIANO. Contudo, o erro só nos aparece se executarmos um ApplyUpdates e se estivermos executando de dentro do IDE do Delphi. Esse último caso é mais complicado, pois se estivermos rodando a aplicação por fora do Delphi o erro não será exibido e o registro não excluído. Faremos uma pequena modificação, para que possamos saber quando ocorreu algum erro. No evento OnReconcileError do cdsClientes inclua o código a seguir:


  MessageDlg('Ocorreu um erro ao salvar no banco de dados.' + #13 +

    'Erro original:' + #13#13 +

    E.Message, mtError, [mbOk], 0);

Estamos interceptando o erro e mostrando-o em uma MessageDlg (Figura 6). Sendo assim, nossa mensagem de erro torna-se personalizada.

Mensagem de erro no ReconcileError
Figura 6. Mensagem de erro no ReconcileError.

Trabalhando com Roles

A primeira pergunta é: O que são Roles? Role é um grupo, onde podemos definir privilégios a ele e em seguida atribuí-lo a um ou mais usuários. A principal vantagem em se usar Role, é que você define apenas uma vez a que cada usuário terá ou não acesso. Em um sistema com muitos funcionários acessando o software, a criação de grupos pode ser muito benéfica, pois poupa muito tempo. Sua utilização é muito simples.

Começaremos pela criação de Roles. Para criar uma role no Firebird, basta executar o comando create role juntamente com o nome desse grupo. Ex.:


CREATE ROLE GRUPO_SELECT;

CRATE ROLE GRUPO_ALTERACAO;

Como podemos ver estamos criando dois grupos. O próximo passo é especificar o que cada grupo terá direito a acessar. Assim como os nomes dos grupos sugerem vamos fazer com que a role GRUPO_SELECT não tenha acesso à inclusão, alteração, exclusão e execução de Stored Procedures e Triggers. Para isso digite e execute cada comando a seguir:


GRANT SELECT ON CLIENTES TO GRUPO_SELECT;

GRANT ALL ON CLIENTES TO GRUPO_ALTERACAO;

Veja que usamos o mesmo comando Grant usado anteriormente, só que desta vez atribuímos seus privilégios diretamente a role. Em resumo estamos configurando o grupo GRUPO_SELECT para executar somente Select no banco, diferente do GRUPO_ALTERACAO que tem acesso total ALL.

O último passo é alocar os usuários em seus respectivos grupos:


GRANT GRUPO_SELECT TO ADRIANO;

GRANT GRUPO_ALTERACAO TO GUINTHER;

Agora fica ainda mais fácil de entender. Especificamos que o usuário ADRIANO é do GRUPO_SELECT e só tem acesso à consulta. Diferente do usuário GUINTHER que é do GRUPO_ALTERACAO e possui acesso total às rotinas do SGBD. Experimente executar a aplicação e fazer os devidos testes. Certamente terá uma surpresa, ambos usuários não possuem acesso ao sistema devido a mensagem de erro “no permission for update/write access to TABLE CLIENTES”. Isso acontece porque não informamos ao SQLConnection qual a role estará sendo usada. Vamos rever o código da Listagem 3. Note que no parâmetro RoleName estamos mantendo seu valor padrão, ou seja, RoleName=RoleName. Teremos que mudar esse procedimento já que o sistema interpreta que nenhuma role está sendo usada no momento.

Insira um novo botão na tela e mude seu Caption para “Conectar usando Role” e logo em seguida clique duas vezes nele para visualizarmos a página de código e seu evento OnClick. No evento mencionado digite o código da Listagem 4.

Vamos ao que interessa. O segredo de tudo está no parâmetro RoleName. Nele precisamos informar “qual o role será usado”, do contrário o banco retornará que tal usuário não tem acesso a determinadas operações.

Mas para que isso se concretize precisamos saber qual o Role, ou seja, a qual grupo o usuário faz parte. E como saber essa informação? A resposta é simples: recorrendo às tabelas de sistema.

O Firebird assim como outros bancos de dados possui algumas tabelas adicionais que chamamos de System Tables, ou Tabelas de Sistema. Uma série de informações referentes ao banco de dados em questão são mostradas/armazenadas nessas tabelas. No Firebird elas começam pelo prefixo RDB$. Faremos uso delas para detectar qual a role em que determinado usuário se encontra alocado. A System Table que vamos usar é a RDB$USER_PRIVILEGIES que guarda os privilégios.

A explicação dessa tabela é bem simples: cada vez que usamos o comando grant ou revoke para dar ou retirar privilégios de um usuário ou role, essa tabela é atualizada. Execute a Select a seguir e veja o que ocorre:


SELECT * FROM RDB$PRIVILEGIES

Notará que cada privilégio de cada usuário/role é listado, e assim fica fácil entendermos o que vamos fazer. Faremos uma Select nessa fonte de dados para que possamos descobrir qual o grupo que determinado usuário está alocado, mas para isso precisaremos de um novo ClientDataSet(“cdsAuxiliar”). Insira-o em tela e vincule-o ao dspClientes. A Listagem 4 fará toda a diferença. Estamos conectando ao banco de dados usando o usuário SYSDBA e senha masterkey e listando o campo RDB$RELATION_NAME com o apelido ROLE da tabela RDB$USER_PRIVILEGIES. Por fim pegamos esse resultado e usamos como parâmetro na função AtualizarParametros. Em AtualizarParametros substituímos o parâmetro RoleName por RoleName=ARole, ou seja, a Role recebida no parâmetro da procedure.

O cdsAuxiliar é usado como ClientDataSet de apoio, pra poder receber o resultado da Select na tabela de sistema. Se rodar o sistema, perceberá que temos o mesmo cenário usado nos últimos exemplos, porém desta vez definimos os privilégios para o grupo e não para cada usuário. Para ter certeza de que o sistema está usando os privilégios configurados nas Roles GRUPO_SELECT e GRUPO_ALTERACAO, rode os scripts em seguida e execute novamente o sistema fazendo os mesmos testes. Os scripts revogam todos os direitos de cada usuário:


REVOKE ALL ON CLIENTES TO ADRIANO;

REVOKE ALL ON CLIENTES TO GUINTHER;
Listagem 4. Código do botão Conectar usando Role.

procedure TForm1.ConectarUsandoRole5Click(Sender:

  TObject);

var

  Role : string;

  procedure AtualizarParametros(AUser, ASenha,

    ARole: string);

  begin

    with sqlConexao.Params do

    begin

      Clear;

      Add('DriverName=Interbase');

      Add('Database=\SEGURANCA.FDB');

      Add('RoleName=' + ARole);

      Add('User_Name=' + AUser);

      Add('Password=' + ASenha);

      Add('ServerCharSet=');

      Add('SQLDialect=1');

      Add('BlobSize=-1');

      Add('CommitRetain=False');

      Add('WaitOnLocks=True');

      Add('ErrorResourceFile=');

      Add('LocaleCode=0000');

      Add('Interbase TransIsolation=ReadCommited');

      Add('Trim Char=False');

    end;

  end;

begin

  if sqlConexao.Connected then

    sqlConexao.Connected := False;

  AtualizarParametros('SYSDBA', 'masterkey', '');

  sqlConexao.Connected := True;

 

  sdsClientes.Close;

  sdsClientes.CommandText := '';

  sdsClientes.CommandText := 'SELECT RDB$RELATION_NAME

    AS ROLE FROM RDB$USER_PRIVILEGES WHERE

    RDB$USER = ' + QuotedStr(Edit1.Text);

  cdsAuxiliar.Params.Clear;

  cdsAuxiliar.FetchParams;

  cdsAuxiliar.Open;

 

  Role := cdsAuxiliar.FieldByName('ROLE').AsString;

 

  sqlConexao.Connected := False;

 

  AtualizarParametros(Edit1.Text, Edit2.Text, Role);

  sqlConexao.Connected := True;

 

  if sqlConexao.Connected then

  begin

    sdsClientes.CommandText := '';

    sdsClientes.CommandText :='SELECT * FROM

      CLIENTES';

    cdsClientes.Params.Clear;

    cdsClientes.FetchParams;

    cdsClientes.Open;

  end;

end;

Gerenciando usuários pelo IBExpert

Para finalizar nosso artigo vejamos como fazer todo esse gerenciamento usando o IBExpert. O IBExpert em sua versão free (“Personal Edition”), permite apenas a inclusão, alteração e exclusão de usuários e roles, bem como atribuição destes roles a usuários (Figura 7).

A tela de gerenciamento pode ser acessada pelo menu Tools|User Manager. Na primeira aba, Users, podemos adicionar (“Add”), alterar (“Edit”) e excluir (“Delete”) um usuário. A aba seguinte, Roles, é destinada a inclusão e exclusão. E por fim, Membership, é onde atribuímos um grupo a determinado usuário. Para isso basta marcarmos com um “x” na coluna “G” o grupo que desejamos atribuir.

O grande trunfo do IBExpert está em sua versão full, completa. Com ela podemos atribuir ou revogar direitos a grupos e usuários de forma visual. Veja na Figura 8 que o GRUPO_ALTERACAO possui permissão total (“ícones em verde limão”) em todas as colunas. Note também que podemos dar direitos ou revogá-los para cada campo da tabela. Isso significa que podemos ter um nível de segurança ainda mais avançado, não permitindo que determinado grupo ou usuário possa efetuar atualizações em um ou mais campos da tabela em questão.

A esquerda da janela encontramos um ComboBox com a descrição Privilegies For. Nesse ComboBox podemos escolher as opções: Roles, Users, Views, Triggers e Procedures. São os objetos os quais podem receber privilégios. No botão Salvar podemos escolher como o IBExpert aplicará as mudanças. Se escolher Save to Script Execute, uma caixa de diálogo aparecerá com o script já pronto para execução, como no meu caso:


GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON CLIENTES TO GRUPO_ALTERACAO;
IBExpert, inclusão e exclusão de usuários e roles
Figura 7. IBExpert, inclusão e exclusão de usuários e roles.
Grant e Revoke diretamente no IBExpert
Figura 8. Grant e Revoke diretamente no IBExpert.

Considerações finais

O nível de segurança em um banco de dados deve ser elevado de acordo com o sistema a ser desenvolvido. Há “n” fatores a se levar em consideração quando falamos em segurança da informação. Podemos citar milhares de casos onde a segurança não precisa ser tão elevada e outros tantos milhões que devem ser profundamente estudados. Cada caso deve ser avaliado individualmente no intuito de prover a melhor solução ao cliente.

Um fator importante que deve se levado em consideração é que o arquivo security.fdb que acompanha o banco de dados Firebird, é um arquivo separado. O fato do security.fdb (“arquivo que guarda os usuários e senhas do Firebird”) ser separado do SGBD causa uma pequena falha na segurança no Firebird, já que uma pessoa mal intencionada poderia facilmente roubar o arquivo .fdb de nosso cliente, instalar o Firebird em qualquer máquina e abrir o banco roubado usando a senha SYSDBA/masterkey.

A nova vesão do Firebird, a 3.0, batizada de Vulcan vem sendo aprimorada em uma série de fatores e um deles diz respeito a essa “falha”. O gerenciamento de usuário vem sendo embutido no banco, ou seja, a partir da versão 3.0 o security.fdb será interno. Em outras palavras, o SGBD de seu cliente poderá ter sua própria senha SYSDBA impossibilitando a abertura do mesmo sem conhecimento da senha. Enfim, segurança nunca é demais.

Conclusão

Nesse artigo vimos algumas dicas para melhorar a segurança em nossos aplicativos quando se trata de banco de dados. Uma boa dica é estudar com bastante dedicação e criar seus próprios mecanismos de segurança evitando que seus usuários burlem o sistema ou mesmo cometam erros. Até a próxima em um forte abraço.