|
Home → WINDEV 25 → PostgreSQL: Solução atende aos requisitos de bloquear os comandos solicitados, registrar tentativas bloqueadas e funcionar de forma portátil em Windows, macOS e Linux. |
PostgreSQL: Solução atende aos requisitos de bloquear os comandos solicitados, registrar tentativas bloqueadas e funcionar de forma portátil em Windows, macOS e Linux. |
Started by Boller, May, 05 2025 1:51 PM - No answer |
| |
| | | |
|
| |
Registered member 3,963 messages |
|
Posted on May, 05 2025 - 1:51 PM |
Solução do bloqueio de comandos no PostgreSQL para não executar os comandos: RENAME, ALTER TABLE, ALTER COLUMN GRANT, DROP, TRUNCATE DELETE,
E com registro em log e suporte para Windows, macOS e Linux.
Solução para Bloqueio de Comandos no PostgreSQL Vamos implementar uma funcionalidade no PostgreSQL que bloqueia os comandos especificados (DROP, TRUNCATE, DELETE, RENAME, ALTER TABLE, ALTER COLUMN, GRANT) com base em um arquivo de configuração .ini e registra todas as tentativas bloqueadas em um log. A solução será portátil para Windows, macOS e Linux. Visão Geral 1 Arquivo de Configuração: Um arquivo restrict_commands.ini define quais comandos são permitidos ou bloqueados por banco de dados. 2 Verificação de Permissões: Antes de executar cada comando, o código verifica se ele é permitido no banco de dados atual. 3 Registro em Log: Tentativas bloqueadas são registradas em um arquivo de log específico para cada banco de dados. 4 Portabilidade: O código usa funções do PostgreSQL que funcionam em todos os sistemas operacionais suportados.
Código-Fonte Atualizado 1. `restrict_commands.c` Este arquivo contém a lógica principal para verificar permissões e registrar tentativas bloqueadas.
#include "postgres.h" #include "utils/guc.h" #include "storage/fd.h" #include #include #include #include
static char INI_PATH[1024]; static char LOG_PATH_BASE[1024];
// Inicializa caminhos dinamicamente na inicialização do módulo void _PG_init(void) { char share_path[MAXPGPATH]; get_share_path(my_exec_path, share_path); snprintf(INI_PATH, sizeof(INI_PATH), "%s/restrict_commands.ini", share_path); snprintf(LOG_PATH_BASE, sizeof(LOG_PATH_BASE), "%s/", DataDir); }
bool check_command_permission(const char *dbname, const char *operation) { FILE *fp = AllocateFile(INI_PATH, "r"); if (!fp) { ereport(WARNING, (errmsg("Cannot open INI file: %s", INI_PATH))); return true; // Permite por padrão se não conseguir ler }
char line[256]; char section[128]; bool in_section = false; snprintf(section, sizeof(section), "[%s]", dbname);
while (fgets(line, sizeof(line), fp)) { if (strncmp(line, section, strlen(section)) == 0) { in_section = true; continue; } if (in_section && line[0] == '[') break;
if (in_section && strstr(line, operation)) { if (strstr(line, "false")) { FreeFile(fp); log_blocked_command(dbname, operation); return false; } } }
FreeFile(fp); return true; // Permite por padrão se não especificado }
void log_blocked_command(const char *dbname, const char *operation) { char logpath[512]; snprintf(logpath, sizeof(logpath), "%s%s_blocked.log", LOG_PATH_BASE, dbname);
// Verifica permissões de escrita if (access(LOG_PATH_BASE, W_OK) != 0) { ereport(WARNING, (errmsg("Cannot write to log directory: %s", LOG_PATH_BASE))); return; }
FILE *logf = AllocateFile(logpath, "a"); if (!logf) { ereport(WARNING, (errmsg("Cannot open log file: %s", logpath))); return; }
time_t now = time(NULL); char *timestamp = ctime(&now); timestamp[strlen(timestamp)-1] = '\0';
char *user = GetUserNameOrNull(); if (!user) user = "unknown";
fprintf(logf, "[%s] USER: %s tried: %s (BLOCKED)\n", timestamp, user, operation); FreeFile(logf); }
2. `restrict_commands.h` Cabeçalho para as funções definidas em restrict_commands.c. #ifndef RESTRICT_COMMANDS_H #define RESTRICT_COMMANDS_H
bool check_command_permission(const char *dbname, const char *operation); void log_blocked_command(const char *dbname, const char *operation);
#endif /* RESTRICT_COMMANDS_H */
Modificações nos Arquivos do PostgreSQL Para bloquear os comandos especificados, modificamos os arquivos onde eles são processados, adicionando verificações de permissão.
3.1. `DROP` • Arquivo: src/backend/commands/dbcommands.c • Função: DropDatabase() • Modificação: Adicione no início da função: #include "utils/restrict_commands.h" if (!check_command_permission(dbname, "drop")) { ereport(ERROR, (errmsg("DROP DATABASE is blocked for this database by policy"))); } • Nota: Para DROP TABLE e similares, use RemoveRelations em tablecmds.c: #include "utils/restrict_commands.h" if (!check_command_permission(get_database_name(MyDatabaseId), "drop")) { ereport(ERROR, (errmsg("DROP is blocked for this database by policy"))); }
3.2. `TRUNCATE` • Arquivo: src/backend/commands/tablecmds.c • Função: ExecuteTruncateGuts() • Modificação: Adicione no início da função: #include "utils/restrict_commands.h" if (!check_command_permission(get_database_name(MyDatabaseId), "truncate")) { ereport(ERROR, (errmsg("TRUNCATE is blocked for this database by policy"))); }
3.3. `DELETE` • Arquivo: src/backend/commands/delete.c • Função: ExecDelete() • Modificação: Adicione no início da função: #include "utils/restrict_commands.h" if (!check_command_permission(get_database_name(MyDatabaseId), "delete")) { ereport(ERROR, (errmsg("DELETE is blocked for this database by policy"))); }
3.4. `RENAME` • Arquivo: src/backend/commands/tablecmds.c • Função: RenameRelation() • Modificação: Adicione no início da função: #include "utils/restrict_commands.h" if (!check_command_permission(get_database_name(MyDatabaseId), "rename")) { ereport(ERROR, (errmsg("RENAME is blocked for this database by policy"))); }
3.5. `ALTER TABLE` e `ALTER COLUMN` • Arquivo: src/backend/commands/tablecmds.c • Função: AlterTable() • Modificação: Adicione no início da função uma verificação geral para ALTER TABLE. Para ALTER COLUMN, verifique o tipo de comando: #include "utils/restrict_commands.h" if (!check_command_permission(get_database_name(MyDatabaseId), "alter_table")) { ereport(ERROR, (errmsg("ALTER TABLE is blocked for this database by policy"))); } // Verificação específica para ALTER COLUMN if (cmd->subtype == AT_AlterColumnType && !check_command_permission(get_database_name(MyDatabaseId), "alter_column")) { ereport(ERROR, (errmsg("ALTER COLUMN is blocked for this database by policy"))); }
3.6. `GRANT` • Arquivo: src/backend/commands/grant.c • Função: ExecGrantStmt() • Modificação: Adicione no início da função: #include "utils/restrict_commands.h" if (!check_command_permission(get_database_name(MyDatabaseId), "grant")) { ereport(ERROR, (errmsg("GRANT is blocked for this database by policy"))); }
3.7. Atualização do Makefile • Arquivo: src/backend/utils/misc/Makefile • Modificação: Adicione restrict_commands.o à lista de objetos: OBJS = ... restrict_commands.o ...
Exemplo de `restrict_commands.ini`
Coloque este arquivo no diretório share do PostgreSQL (ex.: /usr/local/pgsql/share/ no Linux/macOS ou
C:\Program Files\PostgreSQL\15\share no Windows). [db_financeiro] drop=false truncate=false delete=false rename=false alter_table=false alter_column=false grant=false
[db_erp] drop=false truncate=true delete=true rename=true alter_table=true alter_column=true grant=true
[db_analytics] drop=true truncate=false delete=false rename=false alter_table=false alter_column=false grant=false
Portabilidade para Windows, macOS e Linux • O código usa funções do PostgreSQL como AllocateFile, FreeFile, get_share_path e DataDir, que são portáteis entre Windows, macOS e Linux. • O arquivo .ini é lido de um caminho relativo ao diretório share, e os logs são gravados no diretório de dados (DataDir), garantindo compatibilidade com a estrutura de arquivos de cada sistema operacional. • Nenhuma modificação específica por SO é necessária.
Como Aplicar as Mudanças 1 Adicione os arquivos restrict_commands.c e restrict_commands.h em src/backend/utils/misc/. 2 Aplique as modificações nos arquivos listados acima. 3 Compile o PostgreSQL com ./configure, make e make install. 4 Coloque o arquivo restrict_commands.ini no diretório share. 5 Reinicie o servidor PostgreSQL. Os logs de tentativas bloqueadas serão gravados em /_blocked.log.
Arquivos Modificados #############
Aqui está a lista final dos arquivos que devem ser modificados no código-fonte do PostgreSQL: 1 src/backend/utils/misc/restrict_commands.c: Código principal para verificação e logging. 2 src/include/utils/restrict_commands.h: Cabeçalho. 3 src/backend/commands/dbcommands.c: Para DROP DATABASE. 4 src/backend/commands/tablecmds.c: Para TRUNCATE, RENAME, ALTER TABLE, ALTER COLUMN,
DROP TABLE. 5 src/backend/commands/delete.c: Para DELETE. 6 src/backend/commands/grant.c: Para GRANT. 7 src/backend/utils/misc/Makefile: Adicionar restrict_commands.o.
Essa solução atende aos requisitos de bloquear os comandos solicitados, registrar tentativas bloqueadas e funcionar de forma portátil em Windows, macOS e Linux.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
|