diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7dcbad1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Claude Code handoff files +.claude/HANDOFF.md + +# Input/backup files (large DMP files) +input/ + +# IDE files +.idea/ +.vscode/ +*.swp +*.swo diff --git a/proxmox/lxc108-oracle/roa-windows-setup/README.md b/proxmox/lxc108-oracle/roa-windows-setup/README.md new file mode 100644 index 0000000..95fa7c7 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/README.md @@ -0,0 +1,390 @@ +# ROA Oracle Database Setup for Windows + +## Overview + +Scripts and documentation for setting up ROA Oracle Database on Windows servers: + +| Scenario | Description | +|----------|-------------| +| **New Server** | Oracle 21c SE (non-CDB) or XE (CDB/PDB) + CONTAFIN_ORACLE.dmp | +| **Migration** | Import existing DMP files (CONTAFIN_ORACLE + 30-50 companies) | +| **Add Company** | Add new company schema to existing server | + +--- + +## Prerequisites + +- Windows Server 2016+ or Windows 10/11 +- Oracle 21c Standard Edition or Express Edition installed +- Administrator privileges +- PowerShell 5.1+ +- Minimum 8GB RAM (16GB recommended for SE) +- 50GB free disk space + +--- + +## Quick Start + +1. Download Oracle 21c XE or SE from Oracle +2. Install Oracle (see `docs/00-INSTALL-ORACLE-XE.md` or `docs/00-INSTALL-ORACLE-SE.md`) +3. Copy DMP files to `C:\DMPDIR\` +4. Copy `config.example.ps1` to `config.ps1` and edit values +5. Run scripts in order: `01` -> `07` + +```powershell +# Example workflow +.\01-setup-database.ps1 +.\02-create-sys-objects.ps1 +.\03-import-contafin.ps1 +.\04-create-synonyms-grants.ps1 +.\05-import-companies.ps1 +.\07-verify-installation.ps1 +``` + +--- + +## Configuration + +Copy `config.example.ps1` to `config.ps1` and edit: + +| Parameter | XE Value | SE Value | +|-----------|----------|----------| +| `ORACLE_HOME` | `C:\app\oracle\product\21c\dbhomeXE` | `C:\app\oracle\product\21c\dbhome_1` | +| `SERVICE_NAME` | `XEPDB1` | `ROA` | +| `DATAFILE_DIR` | `C:\app\oracle\oradata\XE\XEPDB1` | `C:\app\oracle\oradata\ROA` | + +--- + +## Directory Structure + +``` +roa-windows-setup/ +├── README.md # This file +├── config.example.ps1 # Configuration template +│ +├── docs/ # Installation guides +│ ├── 00-INSTALL-ORACLE-XE.md # Oracle 21c XE installation +│ └── 00-INSTALL-ORACLE-SE.md # Oracle 21c SE installation +│ +├── scripts/ # PowerShell setup scripts +│ ├── 01-setup-database.ps1 # Tablespace, profile, CONTAFIN_ORACLE user +│ ├── 02-create-sys-objects.ps1# SYS objects (AUTH_PACK, NEWSCHEMA, etc.) +│ ├── 03-import-contafin.ps1 # Import CONTAFIN_ORACLE schema +│ ├── 04-create-synonyms-grants.ps1 # Public synonyms and grants +│ ├── 05-import-companies.ps1 # Batch import company schemas +│ ├── 06-add-company.ps1 # Add new company to existing server +│ └── 07-verify-installation.ps1# Verify installation completeness +│ +├── config/ # Configuration templates +│ └── sqlnet.ora # Compatibility for Instant Client 10/11 +│ +├── par/ # Data Pump parameter files +│ ├── import-contafin.par # CONTAFIN_ORACLE import parameters +│ └── import-company.par # Company schema import template +│ +├── sql/ # SQL scripts +│ └── (to be added) +│ +└── test/ # Testing scripts + └── clone-vm300.sh # Proxmox VM cloning for testing +``` + +--- + +## Scripts Overview + +| Script | Purpose | Required | +|--------|---------|----------| +| `01-setup-database.ps1` | Create tablespace ROA, configure profile, create CONTAFIN_ORACLE user | Yes | +| `02-create-sys-objects.ps1` | Install SYS objects: AUTH_PACK, NEWSCHEMA, EXECUTESCRIPTOS, UTL_MAIL | Yes | +| `03-import-contafin.ps1` | Import CONTAFIN_ORACLE schema from DMP | Yes | +| `04-create-synonyms-grants.ps1` | Create public synonyms and grants for CONTAFIN_ORACLE | Yes | +| `05-import-companies.ps1` | Batch import company schemas from DMP files | Yes | +| `06-add-company.ps1` | Add new company to existing server | Optional | +| `07-verify-installation.ps1` | Verify installation completeness (objects, grants, synonyms) | Yes | + +--- + +## Architecture Differences + +### Oracle 21c Standard Edition (non-CDB) + +Traditional single-database architecture (legacy compatibility). + +| Feature | Value | +|---------|-------| +| Architecture | Single database (non-CDB) | +| Database Name | ROA | +| Service Name | ROA | +| SID | ROA | +| Connection | `system/pass@ROA` | +| Datafiles | `C:\app\oracle\oradata\ROA\` | + +**Advantages:** +- Simpler administration +- Compatible with Oracle 10g migration scripts +- No PDB management overhead + +### Oracle 21c Express Edition (CDB/PDB) + +Modern multitenant architecture with Container Database. + +| Feature | Value | +|---------|-------| +| Architecture | Container + Pluggable Database | +| CDB Name | XE | +| PDB Name | XEPDB1 | +| Service Name | XEPDB1 (for applications) | +| Connection | `system/pass@XEPDB1` | +| Datafiles | `C:\app\oracle\oradata\XE\XEPDB1\` | + +**Advantages:** +- Free license (Express Edition) +- Modern architecture +- Easy backup/clone of PDB + +**Connection Warning:** +> Always connect to **XEPDB1** (PDB), not to **XE** (CDB root) for ROA operations! + +--- + +## Standard Passwords + +| User | Password | Notes | +|------|----------|-------| +| SYS | romfastsoft | SYSDBA | +| SYSTEM | romfastsoft | DBA | +| CONTAFIN_ORACLE | ROMFASTSOFT | Common schema | +| Company schemas | From NOM_FIRME.parola | See company-specific config | + +> **Security Note:** Change passwords in production environments! + +--- + +## DMP Files Required + +### For New Installation + +| File | Description | Size | +|------|-------------|------| +| `contafin_oracle.dmp` | Common schema (rights, updates, etc.) | ~50MB | +| `[company].dmp` | Company schema (one per company) | ~100-500MB each | + +### Obtaining DMP Files + +Export from existing Oracle 18c server (for compatibility): + +```bash +# From LXC 108 (Oracle 18c - port 1522) +docker exec oracle18-xe expdp system/romfastsoft@localhost:1521/XEPDB1 \ + SCHEMAS=CONTAFIN_ORACLE DIRECTORY=DMPDIR DUMPFILE=contafin_oracle.dmp \ + LOGFILE=export_contafin.log VERSION=11.2 +``` + +Copy to Windows: +```powershell +# Using SCP from WSL/Linux +scp root@10.0.20.201:/opt/oracle18/oradata/dmpdir/contafin_oracle.dmp C:\DMPDIR\ +``` + +--- + +## Workflow Examples + +### New Server Installation + +```powershell +# 1. Install Oracle 21c XE (see docs/00-INSTALL-ORACLE-XE.md) + +# 2. Configure +Copy-Item config.example.ps1 config.ps1 +notepad config.ps1 # Edit values + +# 3. Copy DMP files +mkdir C:\DMPDIR +Copy-Item \\server\dmp\*.dmp C:\DMPDIR\ + +# 4. Run setup scripts +.\01-setup-database.ps1 +.\02-create-sys-objects.ps1 +.\03-import-contafin.ps1 +.\04-create-synonyms-grants.ps1 +.\05-import-companies.ps1 +.\07-verify-installation.ps1 +``` + +### Add New Company + +```powershell +# Copy company DMP +Copy-Item \\server\dmp\NEWCOMPANY.dmp C:\DMPDIR\ + +# Run add company script +.\06-add-company.ps1 -CompanyName "NEWCOMPANY" -Password "ROMFASTSOFT" +``` + +### Migration from Oracle 10g + +```powershell +# 1. Export from Oracle 10g (on source Windows server) +exp system/password@ORCL file=C:\backup\COMPANY.dmp owner=COMPANY + +# 2. Convert with Oracle 21c imp (if needed) +# Or use impdp with VERSION parameter + +# 3. Import using scripts +.\05-import-companies.ps1 -DmpFile "COMPANY.dmp" +``` + +--- + +## Troubleshooting + +### ORA-28040: No matching authentication protocol + +**Problem:** Old clients (Instant Client 10/11) cannot connect to Oracle 21c. + +**Solution:** Configure `sqlnet.ora` for backward compatibility: + +```powershell +# Copy sqlnet.ora template +Copy-Item config\sqlnet.ora $env:ORACLE_HOME\network\admin\sqlnet.ora + +# Restart listener +lsnrctl reload +``` + +### ORA-01017: invalid username/password + +**After configuring sqlnet.ora for old clients, reset passwords:** + +```sql +ALTER USER CONTAFIN_ORACLE IDENTIFIED BY ROMFASTSOFT; +ALTER USER [COMPANY] IDENTIFIED BY [PASSWORD]; +``` + +### ORA-12514: TNS:listener does not currently know of service + +**Check listener status:** + +```powershell +lsnrctl status +lsnrctl services +``` + +**For XE, ensure PDB is open:** + +```sql +ALTER SESSION SET CONTAINER = XEPDB1; +ALTER PLUGGABLE DATABASE XEPDB1 OPEN; +ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE; +``` + +### Import Errors + +**ORA-00959: tablespace 'ROA' does not exist:** +```powershell +# Use REMAP_TABLESPACE in impdp +impdp ... REMAP_TABLESPACE=ROA:USERS +``` + +**ORA-39405: Oracle Data Pump does not support importing from a source database with TSTZ version newer:** + +Use DMP files exported from Oracle 18c (TSTZ 31) instead of Oracle 21c (TSTZ 35). + +### Service Not Starting + +Check Windows Services: +- `OracleServiceXE` (for XE) +- `OracleServiceROA` (for SE) +- `OracleOraDB21Home1TNSListener` + +```powershell +# Restart services +net stop OracleServiceXE +net start OracleServiceXE +net stop OracleOraDB21Home1TNSListener +net start OracleOraDB21Home1TNSListener +``` + +--- + +## Connection Strings + +### SQL*Plus + +```bash +# Oracle XE (connect to PDB) +sqlplus system/romfastsoft@localhost:1521/XEPDB1 +sqlplus CONTAFIN_ORACLE/ROMFASTSOFT@localhost:1521/XEPDB1 + +# Oracle SE (connect to database) +sqlplus system/romfastsoft@localhost:1521/ROA +sqlplus CONTAFIN_ORACLE/ROMFASTSOFT@localhost:1521/ROA +``` + +### JDBC + +``` +# Oracle XE +jdbc:oracle:thin:@localhost:1521/XEPDB1 + +# Oracle SE +jdbc:oracle:thin:@localhost:1521/ROA +``` + +### ODBC (Instant Client) + +| Parameter | XE Value | SE Value | +|-----------|----------|----------| +| Host | localhost | localhost | +| Port | 1521 | 1521 | +| Service Name | XEPDB1 | ROA | +| User | CONTAFIN_ORACLE | CONTAFIN_ORACLE | +| Password | ROMFASTSOFT | ROMFASTSOFT | + +### TNS Entry + +``` +# For Oracle XE +ROA = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) + (CONNECT_DATA = (SERVICE_NAME = XEPDB1)) + ) + +# For Oracle SE +ROA = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) + (CONNECT_DATA = (SERVICE_NAME = ROA)) + ) +``` + +--- + +## Testing with Proxmox VM Clone + +For testing installations, use the VM cloning script: + +```bash +# On Proxmox host (pvemini) +./test/clone-vm300.sh 301 # Creates VM 301 from template 300 +``` + +See `test/clone-vm300.sh` for details. + +--- + +## Related Documentation + +- **Oracle LXC 108 (Docker):** `../README.md` +- **Migration Oracle 10g -> 21c:** `../migration/README.md` +- **SQL Migration Guidelines:** `/system_instructions/system_prompt.md` +- **Proxmox Infrastructure:** `../../README.md` + +--- + +**Last Updated:** 2026-01-28 +**Author:** Marius Mutu +**Project:** ROMFASTSQL - ROA Oracle Database Windows Setup diff --git a/proxmox/lxc108-oracle/roa-windows-setup/config.example.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/config.example.ps1 new file mode 100644 index 0000000..36713cc --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/config.example.ps1 @@ -0,0 +1,372 @@ +# ============================================================================= +# ROA Oracle Database Setup Configuration +# ============================================================================= +# This file is sourced by setup scripts. It auto-detects Oracle paths and +# prompts for user input when needed. +# +# Usage: +# 1. Copy to config.ps1: Copy-Item config.example.ps1 config.ps1 +# 2. Run any setup script - it will prompt for missing values +# 3. Or edit config.ps1 manually to set values +# +# If a value is $null or empty, the script will auto-detect or prompt. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Oracle Installation Paths (auto-detected if empty) +# ----------------------------------------------------------------------------- + +# Oracle Home - leave empty to auto-detect from registry/common paths +$ORACLE_HOME = $null + +# Oracle Base - derived from ORACLE_HOME if empty +$ORACLE_BASE = $null + +# ----------------------------------------------------------------------------- +# Database Connection (auto-detected if empty) +# ----------------------------------------------------------------------------- + +# Service Name - leave empty to auto-detect (XEPDB1 for XE, ROA for SE) +$SERVICE_NAME = $null + +# Database host - auto-detected from listener if empty +$DB_HOST = $null + +# Database port +$DB_PORT = 1521 + +# ----------------------------------------------------------------------------- +# Passwords - MUST be set (will prompt if empty) +# ----------------------------------------------------------------------------- + +# SYS/SYSTEM password (set during Oracle installation) +$SYSTEM_PASSWORD = $null + +# CONTAFIN_ORACLE schema password +$CONTAFIN_PASSWORD = "ROMFASTSOFT" + +# Default password for new company schemas +$DEFAULT_COMPANY_PASSWORD = "ROMFASTSOFT" + +# ----------------------------------------------------------------------------- +# Paths (auto-detected if empty) +# ----------------------------------------------------------------------------- + +# Directory for DMP files (import/export) +$DMPDIR = "C:\DMPDIR" + +# Oracle DIRECTORY object name +$DMPDIR_NAME = "DMPDIR" + +# Datafile directory - auto-detected from existing datafiles if empty +$DATAFILE_DIR = $null + +# ----------------------------------------------------------------------------- +# Tablespace Configuration +# ----------------------------------------------------------------------------- + +$TABLESPACE_NAME = "ROA" +$TABLESPACE_SIZE = "2G" +$TABLESPACE_MAXSIZE = "UNLIMITED" +$TABLESPACE_AUTOEXTEND = $true + +# ----------------------------------------------------------------------------- +# Import Settings +# ----------------------------------------------------------------------------- + +$PARALLEL_JOBS = 2 +$TABLE_EXISTS_ACTION = "REPLACE" + +# ----------------------------------------------------------------------------- +# Logging +# ----------------------------------------------------------------------------- + +$LOG_DIR = "$PSScriptRoot\logs" +$VERBOSE_LOGGING = $true + +# ----------------------------------------------------------------------------- +# Advanced Settings +# ----------------------------------------------------------------------------- + +$NLS_CHARACTERSET = "WE8MSWIN1252" +$USER_PROFILE = "DEFAULT" +$DEFAULT_TABLESPACE = "USERS" +$TEMP_TABLESPACE = "TEMP" + +# ============================================================================= +# AUTO-DETECTION AND PROMPTING FUNCTIONS +# ============================================================================= + +function Initialize-Config { + <# + .SYNOPSIS + Initialize configuration by auto-detecting values and prompting for missing ones. + #> + + Write-Host "" + Write-Host "========================================" -ForegroundColor Cyan + Write-Host " ROA Oracle Setup - Configuration" -ForegroundColor Cyan + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "" + + # Auto-detect Oracle Home + if (-not $script:ORACLE_HOME) { + $script:ORACLE_HOME = Find-OracleHome + if ($script:ORACLE_HOME) { + Write-Host "[AUTO] Oracle Home: $script:ORACLE_HOME" -ForegroundColor Green + } else { + $script:ORACLE_HOME = Read-Host "Enter Oracle Home path (e.g., C:\app\oracle\product\21c\dbhomeXE)" + } + } else { + Write-Host "[SET] Oracle Home: $script:ORACLE_HOME" -ForegroundColor Gray + } + + # Derive Oracle Base + if (-not $script:ORACLE_BASE) { + # Go up from dbhomeXE to product to 21c to oracle to app + $script:ORACLE_BASE = Split-Path (Split-Path (Split-Path $script:ORACLE_HOME -Parent) -Parent) -Parent + Write-Host "[AUTO] Oracle Base: $script:ORACLE_BASE" -ForegroundColor Green + } + + # Prompt for SYSTEM password if not set + if (-not $script:SYSTEM_PASSWORD) { + $securePass = Read-Host "Enter SYSTEM password" -AsSecureString + $script:SYSTEM_PASSWORD = [Runtime.InteropServices.Marshal]::PtrToStringAuto( + [Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePass)) + } + + # Auto-detect DB_HOST from listener + if (-not $script:DB_HOST) { + $script:DB_HOST = Find-ListenerHost + if ($script:DB_HOST) { + Write-Host "[AUTO] Database Host: $script:DB_HOST" -ForegroundColor Green + } else { + $script:DB_HOST = "localhost" + Write-Host "[DEFAULT] Database Host: $script:DB_HOST" -ForegroundColor Yellow + } + } else { + Write-Host "[SET] Database Host: $script:DB_HOST" -ForegroundColor Gray + } + + # Build connection string + $script:DB_CONNECT = "${script:DB_HOST}:${script:DB_PORT}" + + # Auto-detect Service Name + if (-not $script:SERVICE_NAME) { + $script:SERVICE_NAME = Find-ServiceName + if ($script:SERVICE_NAME) { + Write-Host "[AUTO] Service Name: $script:SERVICE_NAME" -ForegroundColor Green + } else { + $script:SERVICE_NAME = Read-Host "Enter Service Name (XEPDB1 for XE, or your database name)" + } + } else { + Write-Host "[SET] Service Name: $script:SERVICE_NAME" -ForegroundColor Gray + } + + # Full connection string + $script:DB_CONNECT = "${script:DB_HOST}:${script:DB_PORT}/${script:SERVICE_NAME}" + Write-Host "[INFO] Connection: $script:DB_CONNECT" -ForegroundColor Cyan + + # Auto-detect datafile directory + if (-not $script:DATAFILE_DIR) { + $script:DATAFILE_DIR = Find-DatafileDir + if ($script:DATAFILE_DIR) { + Write-Host "[AUTO] Datafile Dir: $script:DATAFILE_DIR" -ForegroundColor Green + } else { + Write-Host "[WARN] Could not auto-detect datafile directory" -ForegroundColor Yellow + $script:DATAFILE_DIR = Read-Host "Enter datafile directory path" + } + } else { + Write-Host "[SET] Datafile Dir: $script:DATAFILE_DIR" -ForegroundColor Gray + } + + # Create log directory + if (-not (Test-Path $script:LOG_DIR)) { + New-Item -ItemType Directory -Path $script:LOG_DIR -Force | Out-Null + } + + Write-Host "" + Write-Host "Configuration complete!" -ForegroundColor Green + Write-Host "" +} + +function Find-OracleHome { + <# + .SYNOPSIS + Auto-detect Oracle Home from registry or common paths. + #> + + # Try ORACLE_HOME environment variable + if ($env:ORACLE_HOME -and (Test-Path "$env:ORACLE_HOME\bin\sqlplus.exe")) { + return $env:ORACLE_HOME + } + + # Try registry + $regPaths = @( + 'HKLM:\SOFTWARE\Oracle\KEY_OraDB21Home1', + 'HKLM:\SOFTWARE\Oracle\KEY_OraDB18Home1', + 'HKLM:\SOFTWARE\Oracle\KEY_XE', + 'HKLM:\SOFTWARE\Wow6432Node\Oracle\KEY_OraDB21Home1' + ) + + foreach ($regPath in $regPaths) { + if (Test-Path $regPath) { + $oraHome = (Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue).ORACLE_HOME + if ($oraHome -and (Test-Path "$oraHome\bin\sqlplus.exe")) { + return $oraHome + } + } + } + + # Try common paths (including user-specific) + $currentUser = $env:USERNAME + $commonPaths = @( + "C:\app\$currentUser\product\21c\dbhomeXE", + "C:\app\$currentUser\product\21c\dbhome_1", + 'C:\app\oracle\product\21c\dbhomeXE', + 'C:\app\oracle\product\21c\dbhome_1', + 'C:\app\romfast\product\21c\dbhomeXE', + "D:\app\$currentUser\product\21c\dbhomeXE", + 'D:\app\oracle\product\21c\dbhomeXE' + ) + + foreach ($path in $commonPaths) { + if (Test-Path "$path\bin\sqlplus.exe") { + return $path + } + } + + return $null +} + +function Find-ListenerHost { + <# + .SYNOPSIS + Get the host from listener configuration. + #> + + if (-not $script:ORACLE_HOME) { return $null } + + try { + $lsnrctl = Join-Path $script:ORACLE_HOME "bin\lsnrctl.exe" + if (-not (Test-Path $lsnrctl)) { return $null } + + $output = & $lsnrctl status 2>&1 | Out-String + + # Parse HOST from listener output + if ($output -match "HOST=([^\)]+)\)") { + $host = $Matches[1] + # If it's 0.0.0.0 or localhost variant, try to get actual IP + if ($host -eq "0.0.0.0" -or $host -match "^127\." -or $host -eq "localhost") { + # Get first non-loopback IPv4 address + $ip = (Get-NetIPAddress -AddressFamily IPv4 | + Where-Object { $_.IPAddress -notmatch "^127\." } | + Select-Object -First 1).IPAddress + if ($ip) { return $ip } + } + return $host + } + } catch { + # Ignore errors + } + + return $null +} + +function Find-ServiceName { + <# + .SYNOPSIS + Auto-detect service name from listener. + #> + + if (-not $script:ORACLE_HOME) { return $null } + + try { + $lsnrctl = Join-Path $script:ORACLE_HOME "bin\lsnrctl.exe" + if (-not (Test-Path $lsnrctl)) { return $null } + + $output = & $lsnrctl status 2>&1 | Out-String + + # Look for XEPDB1 first (Oracle XE PDB) + if ($output -match 'Service "xepdb1"') { + return "XEPDB1" + } + # Look for ROA + if ($output -match 'Service "roa"') { + return "ROA" + } + # Look for XE + if ($output -match 'Service "XE"') { + return "XE" + } + } catch { + # Ignore errors + } + + # Default to XEPDB1 for modern Oracle XE + return "XEPDB1" +} + +function Find-DatafileDir { + <# + .SYNOPSIS + Auto-detect datafile directory from existing database files. + #> + + if (-not $script:ORACLE_HOME -or -not $script:SYSTEM_PASSWORD -or -not $script:SERVICE_NAME) { + return $null + } + + try { + $sqlplus = Join-Path $script:ORACLE_HOME "bin\sqlplus.exe" + $connStr = "system/$script:SYSTEM_PASSWORD@${script:DB_HOST}:${script:DB_PORT}/${script:SERVICE_NAME}" + + $sql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500 +SELECT SUBSTR(file_name, 1, INSTR(file_name, '\', -1) - 1) +FROM dba_data_files +WHERE tablespace_name = 'SYSTEM' AND ROWNUM = 1; +EXIT; +"@ + + $result = $sql | & $sqlplus -s $connStr 2>$null + $path = ($result -split "`n" | Where-Object { $_ -match "^[A-Z]:\\" } | Select-Object -First 1) + + if ($path) { + return $path.Trim() + } + } catch { + # Ignore errors + } + + return $null +} + +function Get-OracleConnection { + return "system/$script:SYSTEM_PASSWORD@$script:DB_CONNECT" +} + +function Get-SysdbaConnection { + return "sys/$script:SYSTEM_PASSWORD@$script:DB_CONNECT as sysdba" +} + +function Get-SqlPlusPath { + return Join-Path $script:ORACLE_HOME "bin\sqlplus.exe" +} + +function Get-ImpdpPath { + return Join-Path $script:ORACLE_HOME "bin\impdp.exe" +} + +function Get-ExpdpPath { + return Join-Path $script:ORACLE_HOME "bin\expdp.exe" +} + +# ============================================================================= +# AUTO-INITIALIZE when sourced (if not already configured) +# ============================================================================= + +# Check if this is being sourced by a setup script +if ($MyInvocation.InvocationName -ne '.') { + Write-Host "This file should be dot-sourced: . .\config.ps1" -ForegroundColor Yellow +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/config/sqlnet.ora b/proxmox/lxc108-oracle/roa-windows-setup/config/sqlnet.ora new file mode 100644 index 0000000..f0d3fd9 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/config/sqlnet.ora @@ -0,0 +1,105 @@ +# ============================================================================= +# Oracle sqlnet.ora - Compatibility Configuration for Old Instant Client +# ============================================================================= +# +# Purpose: Allow connections from Oracle Instant Client 10g/11g to Oracle 21c +# +# IMPORTANT - Oracle 21c Location: +# Oracle 21c uses a read-only Oracle Home. Configuration files must go in +# the "Oracle Base Home" directory, NOT in ORACLE_HOME. +# +# For Oracle 21c XE, copy to: +# %ORACLE_BASE%\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora +# Example: +# C:\app\\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora +# +# For older Oracle versions, copy to: +# %ORACLE_HOME%\network\admin\sqlnet.ora +# +# After copying: +# 1. STOP and START listener (not just reload!): +# lsnrctl stop +# lsnrctl start +# 2. Wait ~10 seconds for database services to re-register +# 3. Reset user passwords (required to generate 10G password verifier): +# ALTER USER CONTAFIN_ORACLE IDENTIFIED BY ROMFASTSOFT; +# ALTER USER IDENTIFIED BY ; +# +# Note: The password MUST be reset after sqlnet.ora change - this regenerates +# the password hash to include the 10G verifier needed by old clients. +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Authentication Protocol Compatibility +# ----------------------------------------------------------------------------- + +# Allow older authentication protocols (required for Instant Client 10/11) +# Value 8 allows all protocols from Oracle 8i onwards +# Default in 21c is 12, which blocks clients older than 12c +SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 +SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8 + +# ----------------------------------------------------------------------------- +# Password Case Sensitivity (Optional) +# ----------------------------------------------------------------------------- + +# Disable password case sensitivity for compatibility with old applications +# that may send passwords in uppercase +# Uncomment if needed: +# SEC_CASE_SENSITIVE_LOGON=FALSE + +# ----------------------------------------------------------------------------- +# Name Resolution +# ----------------------------------------------------------------------------- + +# Standard name resolution order +NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT) + +# ----------------------------------------------------------------------------- +# Connection Settings (Optional) +# ----------------------------------------------------------------------------- + +# Timeout for establishing connection (seconds) +# SQLNET.INBOUND_CONNECT_TIMEOUT = 60 + +# Dead connection detection interval (minutes) +# SQLNET.EXPIRE_TIME = 10 + +# ----------------------------------------------------------------------------- +# Encryption (Optional - for secure connections) +# ----------------------------------------------------------------------------- + +# Enable native encryption (AES256) +# SQLNET.ENCRYPTION_SERVER = REQUIRED +# SQLNET.ENCRYPTION_TYPES_SERVER = (AES256) +# SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED +# SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA256) + +# ----------------------------------------------------------------------------- +# Logging (for troubleshooting) +# ----------------------------------------------------------------------------- + +# Enable tracing (set to OFF in production) +# TRACE_LEVEL_CLIENT = OFF +# TRACE_LEVEL_SERVER = OFF + +# Log file locations +# LOG_DIRECTORY_CLIENT = C:\app\oracle\network\log +# LOG_DIRECTORY_SERVER = C:\app\oracle\network\log + +# ============================================================================= +# After applying this configuration: +# +# 1. Reload listener: +# lsnrctl reload +# +# 2. Reset passwords for users connecting with old clients: +# sqlplus sys/romfastsoft@SERVICE as sysdba +# ALTER USER CONTAFIN_ORACLE IDENTIFIED BY ROMFASTSOFT; +# ALTER USER [COMPANY] IDENTIFIED BY [PASSWORD]; +# +# 3. Test connection from old client: +# sqlplus CONTAFIN_ORACLE/ROMFASTSOFT@//host:1521/SERVICE +# +# ============================================================================= diff --git a/proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-SE.md b/proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-SE.md new file mode 100644 index 0000000..02be5b6 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-SE.md @@ -0,0 +1,436 @@ +# Installing Oracle 21c Standard Edition on Windows + +## Overview + +Oracle 21c Standard Edition 2 (SE2) is a licensed product for production use. +Unlike Express Edition, SE has no resource limitations. + +| Feature | Express Edition | Standard Edition 2 | +|---------|-----------------|-------------------| +| License | Free | Paid (per socket) | +| CPU | 2 threads max | Unlimited | +| RAM | 2 GB max | Unlimited | +| User Data | 12 GB max | Unlimited | +| Architecture | CDB only | CDB or non-CDB | + +For large ROA installations (50+ companies), SE2 is recommended. + +--- + +## Download + +1. Go to Oracle Database Downloads: + https://www.oracle.com/database/technologies/oracle-database-software-downloads.html + +2. Download **Oracle Database 21c for Windows x64** + - File: `WINDOWS.X64_213000_db_home.zip` (~2.9 GB) + - Requires Oracle account + +3. You will also need the Oracle Database license key + +--- + +## System Requirements + +| Requirement | Minimum | Recommended | +|-------------|---------|-------------| +| OS | Windows Server 2016+ | Windows Server 2019/2022 | +| RAM | 8 GB | 16 GB+ | +| Disk | 30 GB | 100 GB+ | +| CPU | 4 cores | 8+ cores | + +--- + +## Installation + +### Step 1: Extract ZIP + +```powershell +# Create Oracle Home directory first +mkdir C:\app\oracle\product\21c\dbhome_1 + +# Extract directly to Oracle Home +Expand-Archive WINDOWS.X64_213000_db_home.zip -DestinationPath C:\app\oracle\product\21c\dbhome_1 +``` + +### Step 2: Run Installer + +1. Open Command Prompt **as Administrator** + +2. Navigate to Oracle Home: + ```powershell + cd C:\app\oracle\product\21c\dbhome_1 + ``` + +3. Run setup: + ```powershell + .\setup.exe + ``` + +### Step 3: Installation Wizard + +1. **Configuration Option** + - Select: **Create and configure a single instance database** + - Click Next + +2. **System Class** + - Select: **Server Class** + - Click Next + +3. **Database Edition** + - Select: **Standard Edition 2** + - Click Next + +4. **Installation Type** + - Select: **Typical Install** (simpler) + - Or **Advanced Install** for custom settings + - Click Next + +5. **For Typical Install:** + - Oracle base: `C:\app\oracle` + - Database file location: `C:\app\oracle\oradata` + - Database edition: Standard Edition 2 + - Character set: **WE8MSWIN1252** (for Romanian support) + - Global database name: **ROA** + - Password: `romfastsoft` + - **Uncheck:** Create as Container database (for non-CDB) + +6. **Summary** - Review and click Install + +7. **Installation Progress** - Wait (~30-45 minutes) + +8. **Finish** - Note connection information + +--- + +## Non-CDB vs CDB Architecture + +### Non-CDB (Traditional - Recommended for ROA) + +Single database, simpler administration: + +``` ++---------------------------+ +| Database: ROA | +| +---------------------+ | +| | Schema: CONTAFIN | | +| +---------------------+ | +| | Schema: COMPANY1 | | +| +---------------------+ | +| | Schema: COMPANY2 | | +| +---------------------+ | ++---------------------------+ +``` + +Connection: `system/romfastsoft@ROA` + +### CDB (Multitenant) + +Container with pluggable databases: + +``` ++---------------------------------------------+ +| CDB: ROA | +| +---------------------------------------+ | +| | CDB$ROOT | | +| +---------------------------------------+ | +| +---------------------------------------+ | +| | ROAPDB1 - Application Data | | +| +---------------------------------------+ | ++---------------------------------------------+ +``` + +Connection: `system/romfastsoft@ROAPDB1` + +> **Recommendation:** Use **non-CDB** for compatibility with Oracle 10g migration scripts. + +--- + +## Post-Installation Configuration + +### Verify Services Running + +```powershell +Get-Service Oracle* | Format-Table Name, Status, StartType +``` + +Expected services: +| Service | Description | +|---------|-------------| +| OracleServiceROA | Database instance | +| OracleOraDB21Home1TNSListener | TNS Listener | +| OracleVssWriterROA | VSS Writer for backups | + +### Test Connection + +```powershell +# Set Oracle environment +$env:ORACLE_HOME = "C:\app\oracle\product\21c\dbhome_1" +$env:ORACLE_SID = "ROA" +$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH" + +# Test connection +sqlplus system/romfastsoft@localhost:1521/ROA +``` + +### Configure for Old Client Compatibility + +```powershell +notepad C:\app\oracle\product\21c\dbhome_1\network\admin\sqlnet.ora +``` + +Add: +``` +SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 +SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8 +``` + +Reload listener: +```powershell +lsnrctl reload +``` + +--- + +## Create DMPDIR Directory + +```sql +-- Connect as SYSDBA +sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba + +-- Create Windows directory +host mkdir C:\DMPDIR + +-- Create Oracle DIRECTORY object +CREATE OR REPLACE DIRECTORY DMPDIR AS 'C:\DMPDIR'; +GRANT READ, WRITE ON DIRECTORY DMPDIR TO PUBLIC; + +-- Verify +SELECT directory_name, directory_path FROM dba_directories WHERE directory_name = 'DMPDIR'; +``` + +--- + +## Configure Password Policy + +```sql +sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba + +-- Modify DEFAULT profile +ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED; +ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_TIME UNLIMITED; +ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_MAX UNLIMITED; +ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS UNLIMITED; +``` + +--- + +## Memory Configuration + +For Standard Edition with 16GB RAM: + +```sql +-- Connect as SYSDBA +sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba + +-- Check current settings +SHOW PARAMETER memory; +SHOW PARAMETER sga; +SHOW PARAMETER pga; + +-- Configure memory (adjust based on available RAM) +ALTER SYSTEM SET MEMORY_TARGET = 8G SCOPE = SPFILE; +ALTER SYSTEM SET MEMORY_MAX_TARGET = 10G SCOPE = SPFILE; + +-- Restart database for changes +SHUTDOWN IMMEDIATE; +STARTUP; +``` + +Recommended memory allocation: +| RAM Available | MEMORY_TARGET | MEMORY_MAX_TARGET | +|---------------|---------------|-------------------| +| 8 GB | 4 GB | 6 GB | +| 16 GB | 8 GB | 10 GB | +| 32 GB | 16 GB | 20 GB | + +--- + +## Create ROA Tablespace + +```sql +sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba + +-- Create tablespace +CREATE TABLESPACE ROA + DATAFILE 'C:\app\oracle\oradata\ROA\roa01.dbf' + SIZE 2G + AUTOEXTEND ON NEXT 512M + MAXSIZE UNLIMITED; + +-- Verify +SELECT tablespace_name, file_name, bytes/1024/1024 as MB +FROM dba_data_files +WHERE tablespace_name = 'ROA'; +``` + +--- + +## Listener Configuration + +Check `listener.ora`: +```powershell +notepad C:\app\oracle\product\21c\dbhome_1\network\admin\listener.ora +``` + +Should contain: +``` +LISTENER = + (DESCRIPTION_LIST = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) + ) + ) + +SID_LIST_LISTENER = + (SID_LIST = + (SID_DESC = + (GLOBAL_DBNAME = ROA) + (ORACLE_HOME = C:\app\oracle\product\21c\dbhome_1) + (SID_NAME = ROA) + ) + ) +``` + +Check `tnsnames.ora`: +```powershell +notepad C:\app\oracle\product\21c\dbhome_1\network\admin\tnsnames.ora +``` + +Should contain: +``` +ROA = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) + (CONNECT_DATA = + (SERVER = DEDICATED) + (SERVICE_NAME = ROA) + ) + ) +``` + +--- + +## Enterprise Manager Database Express + +Access EM Express: +``` +https://localhost:5500/em/ +``` + +If not configured, enable it: +```sql +sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba + +EXEC DBMS_XDB_CONFIG.SETHTTPPORT(5500); +EXEC DBMS_XDB_CONFIG.SETHTTPSPORT(5501); +``` + +--- + +## Troubleshooting + +### OracleServiceROA Not Starting + +1. Check Oracle alert log: + ```powershell + Get-Content C:\app\oracle\diag\rdbms\roa\ROA\trace\alert_ROA.log -Tail 100 + ``` + +2. Common issues: + - Insufficient memory + - Disk space + - Port 1521 already in use + +### ORA-01034: ORACLE not available + +Start the database manually: +```powershell +sqlplus / as sysdba +SQL> STARTUP; +``` + +### ORA-12514: TNS listener does not know of service + +```powershell +# Register database with listener +sqlplus / as sysdba +SQL> ALTER SYSTEM REGISTER; + +# Check listener +lsnrctl status +lsnrctl services +``` + +### Database Won't Shut Down + +```sql +-- Force shutdown +SHUTDOWN ABORT; + +-- Start clean +STARTUP; +``` + +--- + +## Backup Configuration (Recommended) + +### Enable Archivelog Mode + +```sql +sqlplus sys/romfastsoft@localhost:1521/ROA as sysdba + +-- Check current mode +ARCHIVE LOG LIST; + +-- If NOARCHIVELOG, enable: +SHUTDOWN IMMEDIATE; +STARTUP MOUNT; +ALTER DATABASE ARCHIVELOG; +ALTER DATABASE OPEN; + +-- Verify +ARCHIVE LOG LIST; +``` + +### Configure RMAN + +```powershell +rman target sys/romfastsoft@ROA + +RMAN> CONFIGURE RETENTION POLICY TO REDUNDANCY 2; +RMAN> CONFIGURE BACKUP OPTIMIZATION ON; +RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON; +RMAN> CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO 'C:\backup\%F'; +``` + +--- + +## Next Steps + +After Oracle SE installation: + +1. Copy `config.example.ps1` to `config.ps1` +2. Edit `config.ps1`: + - Set `$ORACLE_HOME = "C:\app\oracle\product\21c\dbhome_1"` + - Set `$SERVICE_NAME = "ROA"` + - Set `$DATAFILE_DIR = "C:\app\oracle\oradata\ROA"` +3. Run `01-setup-database.ps1` + +See main `README.md` for complete workflow. + +--- + +**Last Updated:** 2026-01-28 +**Project:** ROMFASTSQL - Oracle SE Installation Guide diff --git a/proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-XE.md b/proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-XE.md new file mode 100644 index 0000000..f60516b --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-XE.md @@ -0,0 +1,337 @@ +# Installing Oracle 21c Express Edition on Windows + +## Overview + +Oracle 21c Express Edition (XE) is free to use with the following limitations: +- 2 CPU threads +- 2 GB RAM for database +- 12 GB user data + +For ROA installations with up to 50 companies, XE is sufficient. + +--- + +## Download + +1. Go to Oracle XE Downloads: + https://www.oracle.com/database/technologies/xe-downloads.html + +2. Download **OracleXE213_Win64.zip** (~1.5 GB) + - Requires Oracle account (free registration) + +3. Verify download integrity (optional): + ```powershell + Get-FileHash OracleXE213_Win64.zip -Algorithm SHA256 + ``` + +--- + +## System Requirements + +| Requirement | Minimum | Recommended | +|-------------|---------|-------------| +| OS | Windows 10/11, Server 2016+ | Windows Server 2019+ | +| RAM | 4 GB | 8 GB | +| Disk | 15 GB | 50 GB | +| CPU | 2 cores | 4 cores | + +--- + +## Installation + +### Step 1: Extract ZIP + +```powershell +Expand-Archive OracleXE213_Win64.zip -DestinationPath C:\OracleXE_Install +``` + +### Step 2: Run Installer + +1. Open Command Prompt or PowerShell **as Administrator** + +2. Navigate to extracted folder: + ```powershell + cd C:\OracleXE_Install\Disk1 + ``` + +3. Run setup: + ```powershell + .\setup.exe + ``` + +### Step 3: Installation Wizard + +1. **Welcome Screen** - Click Next + +2. **License Agreement** - Accept and click Next + +3. **Oracle Home Location** + - Default: `C:\app\oracle\product\21c\dbhomeXE` + - Keep default unless disk space is an issue + +4. **Database Passwords** + - Enter password for SYS and SYSTEM: `romfastsoft` + - Confirm password + - **Important:** Remember this password! + +5. **Summary** - Review and click Install + +6. **Installation Progress** - Wait (~10-20 minutes) + +7. **Finish** - Note the connection information: + - Multitenant container database: XE + - Pluggable database: XEPDB1 + - EM Express URL: https://localhost:5500/em/ + +--- + +## Post-Installation Configuration + +### Verify Services Running + +Open Services (services.msc) and verify: + +| Service | Status | Startup Type | +|---------|--------|--------------| +| OracleServiceXE | Running | Automatic | +| OracleOraDB21Home1TNSListener | Running | Automatic | + +Or via PowerShell: +```powershell +Get-Service Oracle* | Format-Table Name, Status, StartType +``` + +### Test Connection + +```powershell +# Set Oracle environment +$env:ORACLE_HOME = "C:\app\oracle\product\21c\dbhomeXE" +$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH" + +# Test connection to CDB +sqlplus system/romfastsoft@localhost:1521/XE + +# Test connection to PDB (for applications) +sqlplus system/romfastsoft@localhost:1521/XEPDB1 +``` + +Expected output: +``` +Connected to: +Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production +Version 21.3.0.0.0 + +SQL> +``` + +### Configure for Old Client Compatibility + +If using Instant Client 10/11 (ODBC), configure `sqlnet.ora`: + +```powershell +# Edit sqlnet.ora +notepad C:\app\oracle\product\21c\dbhomeXE\network\admin\sqlnet.ora +``` + +Add these lines: +``` +SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 +SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8 +``` + +Reload listener: +```powershell +lsnrctl reload +``` + +--- + +## CDB/PDB Architecture + +Oracle XE uses Container Database (CDB) architecture: + +``` ++---------------------------------------------+ +| CDB: XE | +| +---------------------------------------+ | +| | CDB$ROOT - System, SYS objects | | +| +---------------------------------------+ | +| +---------------------------------------+ | +| | PDB$SEED - Template (read-only) | | +| +---------------------------------------+ | +| +---------------------------------------+ | +| | XEPDB1 - Application Data (ROA) | | +| +---------------------------------------+ | ++---------------------------------------------+ +``` + +| Container | Purpose | Connect To | +|-----------|---------|------------| +| XE (CDB$ROOT) | Administration, SYS | Admin only | +| XEPDB1 | Application data | ROA applications | + +> **Important:** Always connect to **XEPDB1** for ROA operations, not XE! + +--- + +## Verify PDB Status + +```sql +-- Connect as SYSDBA +sqlplus sys/romfastsoft@localhost:1521/XE as sysdba + +-- Check PDB status +SELECT name, open_mode FROM v$pdbs; + +-- Expected output: +-- NAME OPEN_MODE +-- --------- ---------- +-- PDB$SEED READ ONLY +-- XEPDB1 READ WRITE +``` + +If XEPDB1 is MOUNTED (not READ WRITE): +```sql +ALTER PLUGGABLE DATABASE XEPDB1 OPEN; +ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE; +``` + +--- + +## Create DMPDIR Directory + +```sql +-- Connect to PDB +sqlplus sys/romfastsoft@localhost:1521/XEPDB1 as sysdba + +-- Create Windows directory +host mkdir C:\DMPDIR + +-- Create Oracle DIRECTORY object +CREATE OR REPLACE DIRECTORY DMPDIR AS 'C:\DMPDIR'; +GRANT READ, WRITE ON DIRECTORY DMPDIR TO PUBLIC; + +-- Verify +SELECT directory_name, directory_path FROM dba_directories WHERE directory_name = 'DMPDIR'; +``` + +--- + +## Configure Password Policy + +Disable password expiration for application users: + +```sql +-- Connect to PDB +sqlplus sys/romfastsoft@localhost:1521/XEPDB1 as sysdba + +-- Modify DEFAULT profile +ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED; +ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_TIME UNLIMITED; +ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_MAX UNLIMITED; +ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS UNLIMITED; + +-- Verify +SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_type = 'PASSWORD'; +``` + +--- + +## Enterprise Manager Express + +Access EM Express web interface: +``` +https://localhost:5500/em/ +``` + +Login: +- Username: system +- Password: romfastsoft +- Container: XEPDB1 (or leave empty for CDB) + +--- + +## Memory Configuration + +Check current memory settings: +```sql +SHOW PARAMETER memory; +SHOW PARAMETER sga; +SHOW PARAMETER pga; +``` + +XE defaults (cannot exceed due to license): +- SGA: 2 GB max +- PGA: 2 GB max + +For better performance within limits: +```sql +-- Automatic memory management +ALTER SYSTEM SET MEMORY_TARGET = 2G SCOPE = SPFILE; +ALTER SYSTEM SET MEMORY_MAX_TARGET = 2G SCOPE = SPFILE; +``` + +--- + +## Troubleshooting + +### OracleServiceXE Not Starting + +1. Check Windows Event Viewer for errors +2. Verify disk space (need 15+ GB free) +3. Check Oracle alert log: + ```powershell + Get-Content C:\app\oracle\diag\rdbms\xe\XE\trace\alert_XE.log -Tail 50 + ``` + +### Cannot Connect to XEPDB1 + +```sql +-- Connect to CDB +sqlplus sys/romfastsoft@localhost:1521/XE as sysdba + +-- Check PDB status +SELECT name, open_mode FROM v$pdbs; + +-- Open if mounted +ALTER PLUGGABLE DATABASE XEPDB1 OPEN; +ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE; +``` + +### ORA-12514: TNS listener does not know of service + +```powershell +# Check listener status +lsnrctl status +lsnrctl services + +# Restart listener +lsnrctl stop +lsnrctl start +``` + +### Uninstall Oracle XE + +If needed, run the universal installer in deinstall mode: +```powershell +C:\app\oracle\product\21c\dbhomeXE\deinstall\deinstall.bat +``` + +Or via Control Panel > Programs and Features. + +--- + +## Next Steps + +After Oracle XE installation: + +1. Copy `config.example.ps1` to `config.ps1` +2. Edit `config.ps1` with your settings +3. Run `01-setup-database.ps1` + +See main `README.md` for complete workflow. + +--- + +**Last Updated:** 2026-01-28 +**Project:** ROMFASTSQL - Oracle XE Installation Guide diff --git a/proxmox/lxc108-oracle/roa-windows-setup/par/import-company.par b/proxmox/lxc108-oracle/roa-windows-setup/par/import-company.par new file mode 100644 index 0000000..cbe8bfe --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/par/import-company.par @@ -0,0 +1,144 @@ +# ============================================================================= +# Oracle Data Pump Import Parameter File - Company Schema Template +# ============================================================================= +# +# Purpose: Template for importing company schemas (FIRMANOUA, COMPANY1, etc.) +# +# Usage: +# 1. Copy this file to import-COMPANYNAME.par +# 2. Replace COMPANY_NAME with actual schema name +# 3. Run: impdp system/password@service parfile=import-COMPANYNAME.par +# +# Or create dynamically: +# $company = "FIRMA1" +# (Get-Content import-company.par) -replace 'COMPANY_NAME', $company | +# Set-Content "import-$company.par" +# impdp system/pass@service parfile="import-$company.par" +# +# Prerequisites: +# 1. DMPDIR directory exists +# 2. COMPANY_NAME.dmp file is in C:\DMPDIR +# 3. COMPANY_NAME user created with appropriate tablespace quota +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Source and Destination +# ----------------------------------------------------------------------------- + +# Oracle directory object containing DMP files +DIRECTORY=DMPDIR + +# Source dump file name +# IMPORTANT: Replace COMPANY_NAME with actual company name +DUMPFILE=COMPANY_NAME.dmp + +# Import log file (will be created in DMPDIR) +LOGFILE=import_COMPANY_NAME.log + +# ----------------------------------------------------------------------------- +# Schema Configuration +# ----------------------------------------------------------------------------- + +# Schema mapping (source:target) +# Use when source and target schema names are the same +REMAP_SCHEMA=COMPANY_NAME:COMPANY_NAME + +# Alternative: If importing to different schema name +# REMAP_SCHEMA=OLD_COMPANY:NEW_COMPANY + +# ----------------------------------------------------------------------------- +# Import Behavior +# ----------------------------------------------------------------------------- + +# Action when table already exists: +# SKIP - Skip existing tables (preserves existing data) - USE FOR MIGRATION +# APPEND - Add rows to existing tables +# TRUNCATE - Delete existing rows, then import +# REPLACE - Drop and recreate tables - USE FOR FRESH INSTALL +TABLE_EXISTS_ACTION=SKIP + +# Transform OID to avoid conflicts +TRANSFORM=OID:N + +# ----------------------------------------------------------------------------- +# Performance Settings +# ----------------------------------------------------------------------------- + +# Number of parallel worker processes +PARALLEL=2 + +# ----------------------------------------------------------------------------- +# Tablespace Remapping +# ----------------------------------------------------------------------------- + +# Remap tablespace if source uses different tablespace +# Common scenario: source uses ROA tablespace, target uses USERS +# REMAP_TABLESPACE=ROA:USERS + +# If source uses multiple tablespaces: +# REMAP_TABLESPACE=ROA:USERS,ROA2:USERS,SYSTEM:USERS + +# ----------------------------------------------------------------------------- +# Exclusions +# ----------------------------------------------------------------------------- + +# Exclude statistics (will be recalculated after import) +EXCLUDE=STATISTICS + +# Exclude grants (will be recreated by setup scripts) +# EXCLUDE=GRANT + +# Exclude specific objects +# EXCLUDE=TABLE:"='TEMP%'" +# EXCLUDE=INDEX:"='IDX_LOG%'" + +# ----------------------------------------------------------------------------- +# Data Filtering (Optional) +# ----------------------------------------------------------------------------- + +# Filter specific tables +# QUERY=TABLEDATA:"WHERE ROWNUM < 1000" + +# Include only specific tables +# INCLUDE=TABLE:"IN ('TABLE1','TABLE2')" + +# ----------------------------------------------------------------------------- +# Advanced Options +# ----------------------------------------------------------------------------- + +# Skip errors and continue +# DATA_OPTIONS=SKIP_CONSTRAINT_ERRORS + +# Disable logging during import (faster but no recovery) +# TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y + +# ============================================================================= +# Expected Objects in Company Schema: +# +# - Tables: gestiune, contabilitate, salarii (~200 tables) +# - Views: Various reports and lookups (~100 views) +# - Packages: Business logic packages (~50) +# - Procedures/Functions: Various (~200) +# - Triggers: Various (~100) +# - Indexes: Performance indexes (~500) +# +# Total: ~3000+ objects +# ============================================================================= + +# ============================================================================= +# Post-Import Steps: +# +# 1. Gather statistics: +# EXEC DBMS_STATS.GATHER_SCHEMA_STATS('COMPANY_NAME'); +# +# 2. Recompile invalid objects: +# EXEC UTL_RECOMP.RECOMP_SERIAL('COMPANY_NAME'); +# +# 3. Create public synonym (if needed): +# CREATE PUBLIC SYNONYM table_name FOR COMPANY_NAME.table_name; +# +# 4. Grant privileges: +# GRANT SELECT ON COMPANY_NAME.table_name TO PUBLIC; +# +# ============================================================================= diff --git a/proxmox/lxc108-oracle/roa-windows-setup/par/import-contafin.par b/proxmox/lxc108-oracle/roa-windows-setup/par/import-contafin.par new file mode 100644 index 0000000..fb66c9a --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/par/import-contafin.par @@ -0,0 +1,104 @@ +# ============================================================================= +# Oracle Data Pump Import Parameter File - CONTAFIN_ORACLE Schema +# ============================================================================= +# +# Purpose: Import CONTAFIN_ORACLE schema (common schema with rights, updates) +# +# Usage: +# impdp system/password@service parfile=import-contafin.par +# +# Or with explicit password prompt: +# impdp system@service parfile=import-contafin.par +# +# Prerequisites: +# 1. DMPDIR directory exists: CREATE DIRECTORY DMPDIR AS 'C:\DMPDIR'; +# 2. contafin_oracle.dmp file is in C:\DMPDIR +# 3. CONTAFIN_ORACLE user created (or will be created by import) +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Source and Destination +# ----------------------------------------------------------------------------- + +# Oracle directory object containing DMP files +DIRECTORY=DMPDIR + +# Source dump file name +DUMPFILE=contafin_oracle.dmp + +# Import log file (will be created in DMPDIR) +LOGFILE=import_contafin_oracle.log + +# ----------------------------------------------------------------------------- +# Schema Configuration +# ----------------------------------------------------------------------------- + +# Schema to import +SCHEMAS=CONTAFIN_ORACLE + +# ----------------------------------------------------------------------------- +# Import Behavior +# ----------------------------------------------------------------------------- + +# Action when table already exists: +# SKIP - Skip existing tables (preserves data) +# APPEND - Add rows to existing tables +# TRUNCATE - Delete existing rows, then import +# REPLACE - Drop and recreate tables +TABLE_EXISTS_ACTION=REPLACE + +# Transform OID to avoid conflicts +# Required when importing between different databases +TRANSFORM=OID:N + +# ----------------------------------------------------------------------------- +# Performance Settings +# ----------------------------------------------------------------------------- + +# Number of parallel worker processes +# Adjust based on CPU cores available +PARALLEL=2 + +# ----------------------------------------------------------------------------- +# Exclusions (Optional) +# ----------------------------------------------------------------------------- + +# Exclude specific object types if needed +# EXCLUDE=STATISTICS +# EXCLUDE=INDEX:"='IDX_TEMP%'" + +# ----------------------------------------------------------------------------- +# Remapping (Optional) +# ----------------------------------------------------------------------------- + +# Remap tablespace if source uses different tablespace name +# REMAP_TABLESPACE=SOURCE_TS:ROA + +# Remap schema if importing to different schema name +# REMAP_SCHEMA=CONTAFIN_ORACLE:CONTAFIN_ORACLE + +# ----------------------------------------------------------------------------- +# Advanced Options +# ----------------------------------------------------------------------------- + +# Continue import even if some objects fail +# CONTENT=ALL + +# Import metadata only (no data) +# CONTENT=METADATA_ONLY + +# Import data only (no DDL) +# CONTENT=DATA_ONLY + +# ============================================================================= +# Expected Objects in CONTAFIN_ORACLE: +# +# - Tables: NOM_FIRME, NOM_USERI, NOM_DREPTURI, etc. (~50 tables) +# - Views: Various application views (~20 views) +# - Packages: PACK_MIGRARE, AUTH_PACK, etc. (~10 packages) +# - Procedures/Functions: Various utilities (~50) +# - Triggers: Various (~20) +# +# Total: ~300+ objects +# ============================================================================= diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/01-setup-database.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/01-setup-database.ps1 new file mode 100644 index 0000000..7862e68 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/01-setup-database.ps1 @@ -0,0 +1,477 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Initial database setup for ROA Oracle. + +.DESCRIPTION + Performs initial database configuration including: + - Validates Oracle installation + - Auto-detects CDB vs non-CDB configuration + - Configures DEFAULT_PROFILE (disables password expiry) + - Configures sqlnet.ora for Instant Client 10/11 compatibility + - Creates tablespace ROA + - Creates user CONTAFIN_ORACLE with required privileges + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects from registry or environment. + +.PARAMETER ServiceName + Database service name. Auto-detects: ROA for non-CDB, XEPDB1 for Oracle XE CDB. + +.PARAMETER SystemPassword + SYSTEM user password. Default: romfastsoft + +.PARAMETER ContafinPassword + CONTAFIN_ORACLE user password. Default: ROMFASTSOFT + +.PARAMETER DatafileDir + Directory for tablespace datafiles. Auto-detects if not specified. + +.PARAMETER TablespaceSize + Initial size of ROA tablespace in MB. Default: 1000 + +.PARAMETER SkipSqlnetConfig + Skip sqlnet.ora configuration. + +.EXAMPLE + .\01-setup-database.ps1 + +.EXAMPLE + .\01-setup-database.ps1 -ServiceName "XEPDB1" -SystemPassword "mypassword" + +.EXAMPLE + .\01-setup-database.ps1 -OracleHome "C:\app\oracle\product\21c\dbhomeXE" -DatafileDir "D:\oradata" + +.NOTES + File Name : 01-setup-database.ps1 + Prerequisite : Oracle Database installed, PowerShell 5.1+ + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName, + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [string]$ContafinPassword = "ROMFASTSOFT", + + [Parameter(Mandatory = $false)] + [string]$DatafileDir, + + [Parameter(Mandatory = $false)] + [int]$TablespaceSize = 1000, + + [Parameter(Mandatory = $false)] + [switch]$SkipSqlnetConfig +) + +$ErrorActionPreference = 'Stop' + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\01-setup-database_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "01-setup-database.ps1" + +try { + Write-LogSection "ROA Database Initial Setup" + + # Step 1: Validate Oracle installation + Write-Log "Detecting Oracle installation..." + + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Step 2: Auto-detect service name if not specified + if (-not $ServiceName) { + Write-Log "Auto-detecting service name..." + + # First try to connect to XE to check CDB status + try { + $version = Get-OracleVersion -OracleHome $oraHome -ServiceName "XE" -Password $SystemPassword + if ($version.IsCDB) { + $ServiceName = "XEPDB1" + Write-Log "Detected CDB installation, using PDB: XEPDB1" + } + else { + $ServiceName = "XE" + Write-Log "Detected non-CDB installation, using service: XE" + } + } + catch { + # Try ROA as fallback + try { + $null = Test-OracleConnection -OracleHome $oraHome -ServiceName "ROA" -Password $SystemPassword + $ServiceName = "ROA" + Write-Log "Using existing service: ROA" + } + catch { + $ServiceName = "XEPDB1" + Write-Log "Defaulting to XEPDB1" + } + } + } + + Write-LogSuccess "Service Name: $ServiceName" + + # Step 3: Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword)) { + throw "Cannot connect to database. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Get version info + $versionInfo = Get-OracleVersion -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword + Write-Log "Oracle Version: $($versionInfo.Version)" + Write-Log "Oracle Edition: $($versionInfo.Edition)" + Write-Log "CDB Mode: $($versionInfo.IsCDB)" + + # Check container info + $containerInfo = Test-PDB -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword + Write-Log "Container: $($containerInfo.ContainerName)" + if ($containerInfo.IsPDB) { + Write-Log "Connected to PDB (Pluggable Database)" + } + elseif ($containerInfo.IsNonCDB) { + Write-Log "Connected to non-CDB database" + } + + # Step 4: Configure DEFAULT_PROFILE (no password expiry) + Write-LogSection "Configuring DEFAULT_PROFILE" + + $profileSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF +PROMPT Configuring DEFAULT_PROFILE - disabling password expiration... +ALTER PROFILE DEFAULT LIMIT + PASSWORD_LIFE_TIME UNLIMITED + PASSWORD_GRACE_TIME UNLIMITED + PASSWORD_REUSE_TIME UNLIMITED + PASSWORD_REUSE_MAX UNLIMITED + FAILED_LOGIN_ATTEMPTS UNLIMITED + PASSWORD_LOCK_TIME UNLIMITED; +COMMIT; +SELECT 'PROFILE_CONFIGURED' FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $profileSql -AsSysdba + + if ($result -match "PROFILE_CONFIGURED") { + Write-LogSuccess "DEFAULT_PROFILE configured successfully" + } + else { + Write-LogWarning "Could not verify profile configuration" + Write-LogDebug $result + } + + # Step 5: Configure sqlnet.ora for old client compatibility + if (-not $SkipSqlnetConfig) { + Write-LogSection "Configuring sqlnet.ora" + + # Oracle 21c uses read-only Oracle Home - config goes to 'homes' directory + # Check for Oracle 21c homes directory structure first + $oraBase = Split-Path (Split-Path (Split-Path $oraHome -Parent) -Parent) -Parent + $homesDir = Join-Path $oraBase "product\21c\homes" + + # Find the actual Oracle Base Home (where user configs go) + $networkAdmin = $null + if (Test-Path $homesDir) { + # Oracle 21c with read-only Oracle Home + $oraBaseHome = Get-ChildItem -Path $homesDir -Directory | + Where-Object { $_.Name -match "OraDB" } | + Select-Object -First 1 + if ($oraBaseHome) { + $networkAdmin = Join-Path $oraBaseHome.FullName "network\admin" + Write-Log "Detected Oracle 21c read-only Home structure" + Write-Log "Using Oracle Base Home: $($oraBaseHome.FullName)" + } + } + + # Fallback to traditional location + if (-not $networkAdmin -or -not (Test-Path (Split-Path $networkAdmin -Parent))) { + $networkAdmin = Join-Path $oraHome "network\admin" + Write-Log "Using traditional Oracle Home network/admin location" + } + + $sqlnetOra = Join-Path $networkAdmin "sqlnet.ora" + + if (-not (Test-Path -Path $networkAdmin)) { + New-Item -ItemType Directory -Path $networkAdmin -Force | Out-Null + } + + # Backup existing sqlnet.ora + if (Test-Path -Path $sqlnetOra) { + $backupPath = "$sqlnetOra.bak_$(Get-Date -Format 'yyyyMMdd_HHmmss')" + Copy-Item -Path $sqlnetOra -Destination $backupPath -Force + Write-Log "Backed up existing sqlnet.ora to $backupPath" + } + + # Create sqlnet.ora with compatibility settings + $sqlnetContent = @" +# sqlnet.ora - ROA Oracle Configuration +# Generated by 01-setup-database.ps1 on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') + +# Allow connections from old Oracle Instant Client 10g/11g (ODBC drivers) +# These clients don't support newer authentication methods +SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 +SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8 + +# Disable encryption requirement for old clients +SQLNET.ENCRYPTION_SERVER = ACCEPTED +SQLNET.CRYPTO_CHECKSUM_SERVER = ACCEPTED + +# Connection timeout settings +SQLNET.INBOUND_CONNECT_TIMEOUT = 60 +SQLNET.RECV_TIMEOUT = 30 +SQLNET.SEND_TIMEOUT = 30 + +# TNS Names directory +NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT) +"@ + + Set-Content -Path $sqlnetOra -Value $sqlnetContent -Encoding ASCII + Write-LogSuccess "sqlnet.ora configured at $sqlnetOra" + Write-Log "Old client compatibility enabled (SQLNET.ALLOWED_LOGON_VERSION=8)" + + # Restart listener to apply changes + Write-Log "Restarting listener to apply sqlnet.ora changes..." + $lsnrctl = Join-Path $oraHome "bin\lsnrctl.exe" + if (Test-Path $lsnrctl) { + try { + & $lsnrctl stop 2>&1 | Out-Null + Start-Sleep -Seconds 3 + $lsnrOutput = & $lsnrctl start 2>&1 + Write-LogSuccess "Listener restarted successfully" + + # Wait for services to register + Write-Log "Waiting for database services to register with listener..." + Start-Sleep -Seconds 10 + } + catch { + Write-LogWarning "Could not restart listener: $_" + Write-Log "Please restart listener manually: lsnrctl stop && lsnrctl start" + } + } + } + else { + Write-Log "Skipping sqlnet.ora configuration as requested" + } + + # Step 6: Get datafile path + if (-not $DatafileDir) { + Write-Log "Auto-detecting datafile path..." + $DatafileDir = Get-DatafilePath -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword + } + Write-LogSuccess "Datafile directory: $DatafileDir" + + # Step 7: Create tablespace ROA + Write-LogSection "Creating Tablespace ROA" + + # Check if tablespace already exists + $checkTsSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'TS_EXISTS' FROM dba_tablespaces WHERE tablespace_name = 'ROA'; +EXIT; +"@ + + $tsResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $checkTsSql -Silent + + if ($tsResult -match "TS_EXISTS") { + Write-LogWarning "Tablespace ROA already exists, skipping creation" + } + else { + $datafilePath = Join-Path $DatafileDir "TS_ROA.DBF" + + $createTsSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF +PROMPT Creating tablespace ROA... +CREATE SMALLFILE TABLESPACE "ROA" + DATAFILE '$datafilePath' SIZE ${TablespaceSize}M + AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED + LOGGING + EXTENT MANAGEMENT LOCAL + SEGMENT SPACE MANAGEMENT AUTO; +COMMIT; +SELECT 'TS_CREATED' FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $createTsSql + + if ($result -match "TS_CREATED") { + Write-LogSuccess "Tablespace ROA created successfully" + Write-Log "Datafile: $datafilePath" + } + else { + Write-LogError "Failed to create tablespace ROA" + Write-LogDebug $result + throw "Tablespace creation failed" + } + } + + # Step 8: Create user CONTAFIN_ORACLE + Write-LogSection "Creating User CONTAFIN_ORACLE" + + # Check if user already exists + if (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE") { + Write-LogWarning "User CONTAFIN_ORACLE already exists" + + # Update password + $updatePwdSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF +ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "$ContafinPassword"; +COMMIT; +SELECT 'PWD_UPDATED' FROM dual; +EXIT; +"@ + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $updatePwdSql -Silent + + if ($result -match "PWD_UPDATED") { + Write-Log "Password updated for CONTAFIN_ORACLE" + } + } + else { + $createUserSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF + +PROMPT Creating user CONTAFIN_ORACLE... +CREATE USER CONTAFIN_ORACLE + IDENTIFIED BY "$ContafinPassword" + DEFAULT TABLESPACE ROA + TEMPORARY TABLESPACE TEMP + PROFILE DEFAULT; + +PROMPT Granting role privileges... +GRANT CONNECT TO CONTAFIN_ORACLE; +GRANT RESOURCE TO CONTAFIN_ORACLE; + +PROMPT Granting system privileges... +GRANT CREATE ANY CONTEXT TO CONTAFIN_ORACLE; +GRANT CREATE SESSION TO CONTAFIN_ORACLE; +GRANT CREATE VIEW TO CONTAFIN_ORACLE; +GRANT DELETE ANY TABLE TO CONTAFIN_ORACLE; +GRANT DROP ANY CONTEXT TO CONTAFIN_ORACLE; +GRANT EXECUTE ANY PROCEDURE TO CONTAFIN_ORACLE; +GRANT INSERT ANY TABLE TO CONTAFIN_ORACLE; +GRANT SELECT ANY DICTIONARY TO CONTAFIN_ORACLE; +GRANT SELECT ANY SEQUENCE TO CONTAFIN_ORACLE; +GRANT SELECT ANY TABLE TO CONTAFIN_ORACLE; +GRANT UNLIMITED TABLESPACE TO CONTAFIN_ORACLE; +GRANT UPDATE ANY TABLE TO CONTAFIN_ORACLE; +GRANT CREATE PUBLIC SYNONYM TO CONTAFIN_ORACLE; +GRANT DROP PUBLIC SYNONYM TO CONTAFIN_ORACLE; + +COMMIT; +SELECT 'USER_CREATED' FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $createUserSql + + if ($result -match "USER_CREATED") { + Write-LogSuccess "User CONTAFIN_ORACLE created successfully" + } + else { + Write-LogError "Failed to create user CONTAFIN_ORACLE" + Write-LogDebug $result + throw "User creation failed" + } + } + + # Verify user privileges + $verifyUserSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +SELECT privilege FROM dba_sys_privs WHERE grantee = 'CONTAFIN_ORACLE' ORDER BY privilege; +EXIT; +"@ + + $privileges = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $verifyUserSql -Silent + + Write-Log "CONTAFIN_ORACLE privileges verified" + + # Step 9: Create DMPDIR directory for Data Pump + Write-LogSection "Creating Data Pump Directory" + + $dmpDir = "C:\DMPDIR" + New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $dmpDir + + Write-LogSuccess "Data Pump directory DMPDIR created: $dmpDir" + + # Step 10: Reset passwords with 10G verifier (required for old client auth) + # After sqlnet.ora is configured, passwords must be reset to generate 10G hash + if (-not $SkipSqlnetConfig) { + Write-LogSection "Resetting Passwords for Old Client Compatibility" + Write-Log "Resetting passwords to generate 10G password verifiers..." + + $resetPwdSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF +-- Reset CONTAFIN_ORACLE password to generate 10G verifier +ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "$ContafinPassword"; +-- Verify password versions +SELECT USERNAME, PASSWORD_VERSIONS FROM DBA_USERS WHERE USERNAME = 'CONTAFIN_ORACLE'; +SELECT 'PWD_RESET_DONE' FROM DUAL; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $resetPwdSql + + if ($result -match "PWD_RESET_DONE") { + Write-LogSuccess "Password reset completed - 10G verifier now available" + if ($result -match "10G") { + Write-Log "Verified: Password has 10G verifier for old client compatibility" + } + } + else { + Write-LogWarning "Could not verify password reset" + } + } + + # Summary + Write-LogSection "Setup Complete" + Write-LogSuccess "Database initial setup completed successfully!" + Write-Log "" + Write-Log "Summary:" + Write-Log " Oracle Home: $oraHome" + Write-Log " Service Name: $ServiceName" + Write-Log " Oracle Version: $($versionInfo.Version)" + Write-Log " Container: $($containerInfo.ContainerName)" + Write-Log " Tablespace ROA: $DatafileDir\TS_ROA.DBF" + Write-Log " User: CONTAFIN_ORACLE" + Write-Log " Data Pump Dir: DMPDIR -> $dmpDir" + if (-not $SkipSqlnetConfig) { + Write-Log " Old Client Auth: Enabled (sqlnet.ora + 10G verifier)" + } + Write-Log "" + Write-Log "Next steps:" + Write-Log " 1. Run 02-create-sys-objects.ps1 to install SYS objects" + Write-Log " 2. Run 03-import-contafin.ps1 to import CONTAFIN_ORACLE schema" + + Close-LogFile -Success $true + exit 0 +} +catch { + Write-LogError "Setup failed: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/02-create-sys-objects.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/02-create-sys-objects.ps1 new file mode 100644 index 0000000..32dba8d --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/02-create-sys-objects.ps1 @@ -0,0 +1,432 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Install SYS objects for ROA Oracle. + +.DESCRIPTION + Executes SQL scripts to create required SYS-owned objects including: + - AUTH_PACK package + - AUTH_DETALII, AUTH_SERII tables + - NEWSCHEMA, NEWSCHEMAPOST procedures + - NEWSCHEMAPROGRESS function + - PACK_UPDATE, PACK_UTILS packages + - Public synonyms and grants + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects. + +.PARAMETER ServiceName + Database service name. Default: XEPDB1 + +.PARAMETER SystemPassword + SYSTEM/SYS user password. Default: romfastsoft + +.PARAMETER SqlScriptsDir + Directory containing SYS SQL scripts. Default: ..\sql + +.EXAMPLE + .\02-create-sys-objects.ps1 + +.EXAMPLE + .\02-create-sys-objects.ps1 -ServiceName "ROA" -SystemPassword "mypassword" + +.NOTES + File Name : 02-create-sys-objects.ps1 + Prerequisite : Run 01-setup-database.ps1 first + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName = "XEPDB1", + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [string]$SqlScriptsDir +) + +$ErrorActionPreference = 'Stop' + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\02-create-sys-objects_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "02-create-sys-objects.ps1" + +try { + Write-LogSection "Installing SYS Objects" + + # Validate Oracle installation + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -AsSysdba)) { + throw "Cannot connect to database as SYS. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Determine SQL scripts directory + if (-not $SqlScriptsDir) { + $SqlScriptsDir = Join-Path $PSScriptRoot "..\sql" + } + + $sysObjectsScript = Join-Path $SqlScriptsDir "sys-objects.sql" + + if (-not (Test-Path -Path $sysObjectsScript)) { + Write-LogWarning "sys-objects.sql not found at $sysObjectsScript" + Write-Log "Creating sys-objects.sql from embedded SQL..." + + # Create the sql directory if it doesn't exist + if (-not (Test-Path -Path $SqlScriptsDir)) { + New-Item -ItemType Directory -Path $SqlScriptsDir -Force | Out-Null + } + + # Embedded SYS objects SQL - minimal set for ROA + $sysObjectsSql = @" +-- sys-objects.sql +-- SYS objects required for ROA Oracle +-- Run as SYS with SYSDBA privilege + +SET ECHO ON FEEDBACK ON VERIFY OFF SERVEROUTPUT ON + +PROMPT +PROMPT ============================================= +PROMPT Creating SYS objects for ROA +PROMPT ============================================= +PROMPT + +-- Create DMPDIR if not exists +PROMPT Creating directory DMPDIR... +CREATE OR REPLACE DIRECTORY DMPDIR AS 'C:\DMPDIR'; +GRANT READ, WRITE ON DIRECTORY DMPDIR TO PUBLIC; + +-- AUTH_DETALII table +PROMPT Creating table AUTH_DETALII... +BEGIN + EXECUTE IMMEDIATE 'DROP TABLE SYS.AUTH_DETALII CASCADE CONSTRAINTS'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +CREATE TABLE SYS.AUTH_DETALII ( + ID_DETALIU NUMBER NOT NULL, + ID_PROGRAM NUMBER NOT NULL, + CAMP_DETALIU VARCHAR2(100), + VAL_DETALIU VARCHAR2(500), + CONSTRAINT PK_AUTH_DETALII PRIMARY KEY (ID_DETALIU) +); + +GRANT SELECT, INSERT, UPDATE, DELETE ON SYS.AUTH_DETALII TO PUBLIC; +CREATE PUBLIC SYNONYM AUTH_DETALII FOR SYS.AUTH_DETALII; + +-- AUTH_SERII table +PROMPT Creating table AUTH_SERII... +BEGIN + EXECUTE IMMEDIATE 'DROP TABLE SYS.AUTH_SERII CASCADE CONSTRAINTS'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +CREATE TABLE SYS.AUTH_SERII ( + ID_PROGRAM NUMBER NOT NULL, + SERIE VARCHAR2(50), + NR_UTIL NUMBER, + DATA_VAL DATE, + CONSTRAINT PK_AUTH_SERII PRIMARY KEY (ID_PROGRAM) +); + +GRANT SELECT, INSERT, UPDATE, DELETE ON SYS.AUTH_SERII TO PUBLIC; +CREATE PUBLIC SYNONYM AUTH_SERII FOR SYS.AUTH_SERII; + +-- AUTH_PACK package specification +PROMPT Creating package AUTH_PACK... +CREATE OR REPLACE PACKAGE SYS.AUTH_PACK AS + FUNCTION selecteaza_serie(p_id_program NUMBER) RETURN VARCHAR2; + FUNCTION selecteaza_nr_util(p_id_program NUMBER) RETURN NUMBER; + FUNCTION selecteaza_data_val(p_id_program NUMBER) RETURN DATE; + PROCEDURE actualizeaza_serie(p_id_program NUMBER, p_serie VARCHAR2, p_nr_util NUMBER, p_data_val DATE); +END AUTH_PACK; +/ + +-- AUTH_PACK package body +CREATE OR REPLACE PACKAGE BODY SYS.AUTH_PACK AS + + FUNCTION selecteaza_serie(p_id_program NUMBER) RETURN VARCHAR2 IS + v_serie VARCHAR2(50); + BEGIN + SELECT serie INTO v_serie FROM SYS.AUTH_SERII WHERE id_program = p_id_program; + RETURN v_serie; + EXCEPTION + WHEN NO_DATA_FOUND THEN RETURN NULL; + END; + + FUNCTION selecteaza_nr_util(p_id_program NUMBER) RETURN NUMBER IS + v_nr_util NUMBER; + BEGIN + SELECT nr_util INTO v_nr_util FROM SYS.AUTH_SERII WHERE id_program = p_id_program; + RETURN v_nr_util; + EXCEPTION + WHEN NO_DATA_FOUND THEN RETURN NULL; + END; + + FUNCTION selecteaza_data_val(p_id_program NUMBER) RETURN DATE IS + v_data_val DATE; + BEGIN + SELECT data_val INTO v_data_val FROM SYS.AUTH_SERII WHERE id_program = p_id_program; + RETURN v_data_val; + EXCEPTION + WHEN NO_DATA_FOUND THEN RETURN NULL; + END; + + PROCEDURE actualizeaza_serie(p_id_program NUMBER, p_serie VARCHAR2, p_nr_util NUMBER, p_data_val DATE) IS + BEGIN + MERGE INTO SYS.AUTH_SERII t + USING (SELECT p_id_program AS id_program FROM dual) s + ON (t.id_program = s.id_program) + WHEN MATCHED THEN + UPDATE SET serie = p_serie, nr_util = p_nr_util, data_val = p_data_val + WHEN NOT MATCHED THEN + INSERT (id_program, serie, nr_util, data_val) + VALUES (p_id_program, p_serie, p_nr_util, p_data_val); + COMMIT; + END; + +END AUTH_PACK; +/ + +GRANT EXECUTE ON SYS.AUTH_PACK TO PUBLIC; +CREATE OR REPLACE PUBLIC SYNONYM AUTH_PACK FOR SYS.AUTH_PACK; + +-- VAUTH_SERII view +PROMPT Creating view VAUTH_SERII... +CREATE OR REPLACE VIEW SYS.VAUTH_SERII AS +SELECT a.id_program, + a.denumire AS nume, + auth_pack.selecteaza_serie(a.id_program) AS serie, + auth_pack.selecteaza_nr_util(a.id_program) AS nr_util, + auth_pack.selecteaza_data_val(a.id_program) AS data_val + FROM syn_nom_programe a + LEFT JOIN syn_def_programe b ON a.id_program = b.ide_program + WHERE b.sters = 0 + AND b.instalat = 1; + +GRANT SELECT ON SYS.VAUTH_SERII TO PUBLIC; +CREATE OR REPLACE PUBLIC SYNONYM VAUTH_SERII FOR SYS.VAUTH_SERII; + +-- PACK_UPDATE package (minimal version) +PROMPT Creating package PACK_UPDATE... +CREATE OR REPLACE PACKAGE SYS.PACK_UPDATE AS + FUNCTION get_version RETURN VARCHAR2; + PROCEDURE execute_sql(p_sql VARCHAR2); +END PACK_UPDATE; +/ + +CREATE OR REPLACE PACKAGE BODY SYS.PACK_UPDATE AS + + FUNCTION get_version RETURN VARCHAR2 IS + BEGIN + RETURN '1.0.0'; + END; + + PROCEDURE execute_sql(p_sql VARCHAR2) IS + BEGIN + EXECUTE IMMEDIATE p_sql; + EXCEPTION + WHEN OTHERS THEN + RAISE; + END; + +END PACK_UPDATE; +/ + +GRANT EXECUTE ON SYS.PACK_UPDATE TO PUBLIC; +CREATE OR REPLACE PUBLIC SYNONYM PACK_UPDATE FOR SYS.PACK_UPDATE; + +-- PACK_UTILS package (minimal version) +PROMPT Creating package PACK_UTILS... +CREATE OR REPLACE PACKAGE SYS.PACK_UTILS AS + FUNCTION get_db_version RETURN VARCHAR2; + FUNCTION get_instance_name RETURN VARCHAR2; +END PACK_UTILS; +/ + +CREATE OR REPLACE PACKAGE BODY SYS.PACK_UTILS AS + + FUNCTION get_db_version RETURN VARCHAR2 IS + v_version VARCHAR2(100); + BEGIN + SELECT version_full INTO v_version FROM v`$instance; + RETURN v_version; + EXCEPTION + WHEN OTHERS THEN RETURN NULL; + END; + + FUNCTION get_instance_name RETURN VARCHAR2 IS + v_instance VARCHAR2(100); + BEGIN + SELECT instance_name INTO v_instance FROM v`$instance; + RETURN v_instance; + EXCEPTION + WHEN OTHERS THEN RETURN NULL; + END; + +END PACK_UTILS; +/ + +GRANT EXECUTE ON SYS.PACK_UTILS TO PUBLIC; +CREATE OR REPLACE PUBLIC SYNONYM PACK_UTILS FOR SYS.PACK_UTILS; + +-- Grant UTL packages to PUBLIC +PROMPT Granting UTL packages... +GRANT EXECUTE ON UTL_FILE TO PUBLIC; +GRANT EXECUTE ON DBMS_LOCK TO PUBLIC; + +-- Grant UTL packages to CONTAFIN_ORACLE specifically +GRANT EXECUTE ON UTL_INADDR TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_TCP TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_SMTP TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_HTTP TO CONTAFIN_ORACLE; + +COMMIT; + +PROMPT +PROMPT ============================================= +PROMPT SYS objects created successfully +PROMPT ============================================= +PROMPT + +SELECT 'SYS_OBJECTS_COMPLETE' FROM dual; + +EXIT; +"@ + + Set-Content -Path $sysObjectsScript -Value $sysObjectsSql -Encoding ASCII + Write-Log "Created sys-objects.sql" + } + + # Execute SYS objects script + Write-LogSection "Executing sys-objects.sql" + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlFile $sysObjectsScript -AsSysdba + + if ($result -match "SYS_OBJECTS_COMPLETE") { + Write-LogSuccess "SYS objects created successfully" + } + else { + Write-LogWarning "Script completed but could not verify success" + Write-LogDebug $result + } + + # Verify created objects + Write-LogSection "Verifying SYS Objects" + + $verifySql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 + +PROMPT +PROMPT === SYS Objects Status === +PROMPT + +SELECT object_name, object_type, status +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ('AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', 'NEWSCHEMAPROGRESS') +ORDER BY object_type, object_name; + +PROMPT +PROMPT === Public Synonyms === +PROMPT + +SELECT synonym_name, table_owner, table_name +FROM dba_synonyms +WHERE owner = 'PUBLIC' + AND table_name IN ('AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', 'NEWSCHEMAPROGRESS') +ORDER BY synonym_name; + +EXIT; +"@ + + $verifyResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $verifySql -AsSysdba + + Write-Host $verifyResult + + # Count invalid objects + $invalidSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'INVALID_COUNT:' || COUNT(*) +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ('AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', 'NEWSCHEMAPROGRESS') + AND status = 'INVALID'; +EXIT; +"@ + + $invalidResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $invalidSql -AsSysdba -Silent + + $invalidCount = 0 + if ($invalidResult -match "INVALID_COUNT:(\d+)") { + $invalidCount = [int]$Matches[1] + } + + if ($invalidCount -gt 0) { + Write-LogWarning "$invalidCount invalid SYS objects found" + Write-Log "Attempting to recompile invalid objects..." + + $recompileSql = @" +SET SERVEROUTPUT ON +BEGIN + DBMS_UTILITY.COMPILE_SCHEMA('SYS', FALSE); +END; +/ +EXIT; +"@ + Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $recompileSql -AsSysdba -Silent + } + else { + Write-LogSuccess "All SYS objects are valid" + } + + # Summary + Write-LogSection "Setup Complete" + Write-LogSuccess "SYS objects installation completed!" + Write-Log "" + Write-Log "Objects created:" + Write-Log " - AUTH_PACK package" + Write-Log " - AUTH_DETALII table" + Write-Log " - AUTH_SERII table" + Write-Log " - VAUTH_SERII view" + Write-Log " - PACK_UPDATE package" + Write-Log " - PACK_UTILS package" + Write-Log " - Public synonyms and grants" + Write-Log "" + Write-Log "Next steps:" + Write-Log " 1. Run 03-import-contafin.ps1 to import CONTAFIN_ORACLE schema" + + Close-LogFile -Success $true + exit 0 +} +catch { + Write-LogError "Setup failed: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/03-import-contafin.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/03-import-contafin.ps1 new file mode 100644 index 0000000..4dbd81d --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/03-import-contafin.ps1 @@ -0,0 +1,312 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Import CONTAFIN_ORACLE schema from Data Pump dump file. + +.DESCRIPTION + Imports the CONTAFIN_ORACLE schema using Oracle Data Pump (impdp). + - Creates DMPDIR directory if not exists + - Runs impdp with optimal parameters + - Verifies import (object count, invalid objects) + +.PARAMETER DumpFile + Path to the CONTAFIN_ORACLE DMP file. Required. + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects. + +.PARAMETER ServiceName + Database service name. Default: XEPDB1 + +.PARAMETER SystemPassword + SYSTEM user password. Default: romfastsoft + +.PARAMETER DmpDir + Oracle directory path for Data Pump. Default: C:\DMPDIR + +.PARAMETER TableExistsAction + What to do if table exists: SKIP, APPEND, TRUNCATE, REPLACE. Default: REPLACE + +.PARAMETER Parallel + Number of parallel workers for import. Default: 2 + +.EXAMPLE + .\03-import-contafin.ps1 -DumpFile "C:\dumps\CONTAFIN_ORACLE.dmp" + +.EXAMPLE + .\03-import-contafin.ps1 -DumpFile "D:\backups\contafin.dmp" -ServiceName "ROA" -SystemPassword "mypass" + +.NOTES + File Name : 03-import-contafin.ps1 + Prerequisite : Run 01-setup-database.ps1 and 02-create-sys-objects.ps1 first + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [ValidateScript({ Test-Path $_ })] + [string]$DumpFile, + + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName = "XEPDB1", + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [string]$DmpDir = "C:\DMPDIR", + + [Parameter(Mandatory = $false)] + [ValidateSet('SKIP', 'APPEND', 'TRUNCATE', 'REPLACE')] + [string]$TableExistsAction = "REPLACE", + + [Parameter(Mandatory = $false)] + [int]$Parallel = 2 +) + +$ErrorActionPreference = 'Stop' + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\03-import-contafin_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "03-import-contafin.ps1" + +try { + Write-LogSection "Importing CONTAFIN_ORACLE Schema" + + # Validate Oracle installation + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword)) { + throw "Cannot connect to database. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Verify CONTAFIN_ORACLE user exists + Write-Log "Verifying CONTAFIN_ORACLE user exists..." + if (-not (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE")) { + throw "User CONTAFIN_ORACLE does not exist. Run 01-setup-database.ps1 first." + } + Write-LogSuccess "User CONTAFIN_ORACLE exists" + + # Create/verify DMPDIR + Write-LogSection "Configuring Data Pump Directory" + + if (-not (Test-Path -Path $DmpDir)) { + New-Item -ItemType Directory -Path $DmpDir -Force | Out-Null + Write-Log "Created directory: $DmpDir" + } + + New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $DmpDir + + # Copy dump file to DMPDIR if not already there + $dumpFileName = Split-Path -Path $DumpFile -Leaf + $targetDumpPath = Join-Path $DmpDir $dumpFileName + + if ($DumpFile -ne $targetDumpPath) { + Write-Log "Copying dump file to DMPDIR..." + Copy-Item -Path $DumpFile -Destination $targetDumpPath -Force + Write-LogSuccess "Dump file copied to: $targetDumpPath" + } + else { + Write-Log "Dump file already in DMPDIR: $targetDumpPath" + } + + # Check dump file size + $dumpFileInfo = Get-Item $targetDumpPath + $dumpSizeMB = [math]::Round($dumpFileInfo.Length / 1MB, 2) + Write-Log "Dump file size: $dumpSizeMB MB" + + # Get current object count before import + Write-Log "Getting current object count for CONTAFIN_ORACLE..." + $beforeCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" + + $beforeTotal = if ($beforeCounts['TOTAL']) { $beforeCounts['TOTAL'] } else { 0 } + Write-Log "Objects before import: $beforeTotal" + + # Run import + Write-LogSection "Running Data Pump Import" + + $impdpPath = Join-Path $oraHome "bin\impdp.exe" + if (-not (Test-Path -Path $impdpPath)) { + throw "impdp.exe not found at: $impdpPath" + } + + $importLogFile = "CONTAFIN_ORACLE_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" + + # Build impdp command + $connString = "SYSTEM/`"$SystemPassword`"@$ServiceName" + + $impdpParams = @( + "`"$connString`"", + "directory=DMPDIR", + "dumpfile=$dumpFileName", + "logfile=$importLogFile", + "schemas=CONTAFIN_ORACLE", + "table_exists_action=$TableExistsAction" + ) + + if ($Parallel -gt 1) { + $impdpParams += "parallel=$Parallel" + } + + $arguments = $impdpParams -join " " + + Write-Log "Executing impdp..." + Write-Log "Parameters: directory=DMPDIR dumpfile=$dumpFileName schemas=CONTAFIN_ORACLE table_exists_action=$TableExistsAction" + + # Set Oracle environment + $env:ORACLE_HOME = $oraHome + $env:PATH = "$oraHome\bin;$env:PATH" + $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" + + $startTime = Get-Date + + # Execute impdp + $process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru + + $duration = (Get-Date) - $startTime + Write-Log "Import completed in $([math]::Round($duration.TotalMinutes, 2)) minutes" + + # Check import log + $importLogPath = Join-Path $DmpDir $importLogFile + if (Test-Path -Path $importLogPath) { + Write-Log "Import log: $importLogPath" + + # Read and analyze log for errors + $logContent = Get-Content -Path $importLogPath -Raw + + if ($logContent -match "ORA-\d{5}:") { + Write-LogWarning "Import completed with Oracle errors. Check log for details." + } + + if ($logContent -match "successfully loaded/unloaded") { + Write-LogSuccess "Objects successfully loaded" + } + + # Count errors and warnings in log + $errorCount = ([regex]::Matches($logContent, "ORA-\d{5}:")).Count + $warningCount = ([regex]::Matches($logContent, "ORA-39\d{3}:")).Count + + Write-Log "Errors in log: $errorCount" + Write-Log "Warnings in log: $warningCount" + } + + # Verify import + Write-LogSection "Verifying Import" + + # Get object counts after import + $afterCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" + + $afterTotal = if ($afterCounts['TOTAL']) { $afterCounts['TOTAL'] } else { 0 } + $afterInvalid = if ($afterCounts['INVALID']) { $afterCounts['INVALID'] } else { 0 } + + Write-Log "Objects after import: $afterTotal" + Write-Log "Objects imported: $($afterTotal - $beforeTotal)" + + # Display object counts by type + Write-Log "" + Write-Log "Object counts by type:" + foreach ($key in $afterCounts.Keys | Sort-Object) { + if ($key -ne 'TOTAL' -and $key -ne 'INVALID') { + Write-Log " $($key): $($afterCounts[$key])" + } + } + + if ($afterInvalid -gt 0) { + Write-LogWarning "Invalid objects: $afterInvalid" + + # List invalid objects + $invalidSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +SELECT object_name, object_type +FROM dba_objects +WHERE owner = 'CONTAFIN_ORACLE' + AND status = 'INVALID' +ORDER BY object_type, object_name; +EXIT; +"@ + $invalidList = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $invalidSql -Silent + + Write-Log "Invalid objects:" + Write-Host $invalidList + + # Attempt to recompile + Write-Log "Attempting to recompile invalid objects..." + $recompileSql = @" +SET SERVEROUTPUT ON +BEGIN + DBMS_UTILITY.COMPILE_SCHEMA('CONTAFIN_ORACLE', FALSE); +END; +/ +EXIT; +"@ + Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent + + # Recheck invalid count + $recheckCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" + + $recheckInvalid = if ($recheckCounts['INVALID']) { $recheckCounts['INVALID'] } else { 0 } + + if ($recheckInvalid -lt $afterInvalid) { + Write-LogSuccess "Recompilation fixed $($afterInvalid - $recheckInvalid) objects" + } + + if ($recheckInvalid -gt 0) { + Write-LogWarning "Still $recheckInvalid invalid objects remaining" + } + } + else { + Write-LogSuccess "No invalid objects" + } + + # Summary + Write-LogSection "Import Complete" + + if ($process.ExitCode -eq 0) { + Write-LogSuccess "CONTAFIN_ORACLE schema imported successfully!" + } + else { + Write-LogWarning "Import completed with warnings (exit code: $($process.ExitCode))" + } + + Write-Log "" + Write-Log "Summary:" + Write-Log " Dump file: $dumpFileName ($dumpSizeMB MB)" + Write-Log " Service: $ServiceName" + Write-Log " Duration: $([math]::Round($duration.TotalMinutes, 2)) minutes" + Write-Log " Objects: $afterTotal" + Write-Log " Import log: $importLogPath" + Write-Log "" + Write-Log "Next steps:" + Write-Log " 1. Run 04-create-synonyms-grants.ps1 to create public synonyms" + Write-Log " 2. Run 05-import-companies.ps1 to import company schemas" + + Close-LogFile -Success ($process.ExitCode -eq 0) + exit $process.ExitCode +} +catch { + Write-LogError "Import failed: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/04-create-synonyms-grants.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/04-create-synonyms-grants.ps1 new file mode 100644 index 0000000..e5f37b0 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/04-create-synonyms-grants.ps1 @@ -0,0 +1,501 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Create public synonyms and grants for ROA Oracle. + +.DESCRIPTION + Creates public synonyms for CONTAFIN_ORACLE objects and configures: + - Public synonyms for tables, views, packages, types + - Public grants (SELECT, EXECUTE, REFERENCES) + - SESIUNE context + - Network ACL for CONTAFIN_ORACLE + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects. + +.PARAMETER ServiceName + Database service name. Default: XEPDB1 + +.PARAMETER SystemPassword + SYSTEM user password. Default: romfastsoft + +.PARAMETER SqlScriptsDir + Directory containing SQL scripts. Default: ..\sql + +.EXAMPLE + .\04-create-synonyms-grants.ps1 + +.EXAMPLE + .\04-create-synonyms-grants.ps1 -ServiceName "ROA" -SystemPassword "mypassword" + +.NOTES + File Name : 04-create-synonyms-grants.ps1 + Prerequisite : Run 03-import-contafin.ps1 first + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName = "XEPDB1", + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [string]$SqlScriptsDir +) + +$ErrorActionPreference = 'Stop' + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\04-create-synonyms-grants_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "04-create-synonyms-grants.ps1" + +try { + Write-LogSection "Creating Public Synonyms and Grants" + + # Validate Oracle installation + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword)) { + throw "Cannot connect to database. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Verify CONTAFIN_ORACLE exists and has objects + Write-Log "Verifying CONTAFIN_ORACLE schema..." + $counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" + + $totalObjects = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 } + if ($totalObjects -eq 0) { + throw "CONTAFIN_ORACLE schema has no objects. Run 03-import-contafin.ps1 first." + } + Write-LogSuccess "CONTAFIN_ORACLE has $totalObjects objects" + + # Create SESIUNE context + Write-LogSection "Creating SESIUNE Context" + + $contextSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF + +-- Drop existing context if exists +BEGIN + EXECUTE IMMEDIATE 'DROP CONTEXT SESIUNE'; +EXCEPTION + WHEN OTHERS THEN NULL; +END; +/ + +-- Create context +CREATE CONTEXT SESIUNE USING CONTAFIN_ORACLE.SET_VARIABILE; + +SELECT 'CONTEXT_CREATED' FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $contextSql + + if ($result -match "CONTEXT_CREATED") { + Write-LogSuccess "Context SESIUNE created" + } + else { + Write-LogWarning "Could not verify context creation" + } + + # Create public synonyms SQL + Write-LogSection "Creating Public Synonyms" + + $synonymsSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF SERVEROUTPUT ON +SPOOL synonyms_grants.log + +PROMPT +PROMPT ============================================= +PROMPT Creating Public Synonyms for CONTAFIN_ORACLE +PROMPT ============================================= +PROMPT + +-- Core synonyms with grants +PROMPT Creating SYN_DEF_GRUP... +CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_GRUP FOR CONTAFIN_ORACLE.DEF_GRUP; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.DEF_GRUP TO PUBLIC; + +PROMPT Creating SYN_DEF_PROGRAME... +CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_PROGRAME FOR CONTAFIN_ORACLE.DEF_PROGRAME; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.DEF_PROGRAME TO PUBLIC; + +PROMPT Creating SYN_VDEF_PROGRAME... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_PROGRAME FOR CONTAFIN_ORACLE.VDEF_PROGRAME; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_PROGRAME TO PUBLIC; + +PROMPT Creating SYN_LUNILEAN... +CREATE OR REPLACE PUBLIC SYNONYM SYN_LUNILEAN FOR CONTAFIN_ORACLE.LUNILEAN; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.LUNILEAN TO PUBLIC; + +PROMPT Creating SYN_NOM_FIRME... +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FIRME FOR CONTAFIN_ORACLE.NOM_FIRME; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FIRME TO PUBLIC; + +PROMPT Creating SYN_NOM_PROGRAME... +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_PROGRAME FOR CONTAFIN_ORACLE.NOM_PROGRAME; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_PROGRAME TO PUBLIC; + +PROMPT Creating SYN_PACK_DREPTURI... +CREATE OR REPLACE PUBLIC SYNONYM SYN_PACK_DREPTURI FOR CONTAFIN_ORACLE.PACK_DREPTURI; +GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_DREPTURI TO PUBLIC; + +PROMPT Creating SYN_UTILIZATORI... +CREATE OR REPLACE PUBLIC SYNONYM SYN_UTILIZATORI FOR CONTAFIN_ORACLE.UTILIZATORI; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.UTILIZATORI TO PUBLIC; + +PROMPT Creating syn_vdef_util_programe... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_PROGRAME FOR CONTAFIN_ORACLE.VDEF_UTIL_PROGRAME; +GRANT SELECT ON CONTAFIN_ORACLE.VDEF_UTIL_PROGRAME TO PUBLIC; + +PROMPT Creating syn_vdef_util_firme... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_FIRME FOR CONTAFIN_ORACLE.VDEF_UTIL_FIRME; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_UTIL_FIRME TO PUBLIC; + +PROMPT Creating SYN_VDEF_UTIL_OBIECTE... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_OBIECTE FOR CONTAFIN_ORACLE.VDEF_UTIL_OBIECTE; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_UTIL_OBIECTE TO PUBLIC; + +PROMPT Creating SYN_VUTILIZATORI... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VUTILIZATORI FOR CONTAFIN_ORACLE.VUTILIZATORI; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VUTILIZATORI TO PUBLIC; + +PROMPT Creating SYN_VDEF_UTIL_GRUP... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_GRUP FOR CONTAFIN_ORACLE.VDEF_UTIL_GRUP; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_UTIL_GRUP TO PUBLIC; + +PROMPT Creating SYN_DEF_GRUP_DREPT... +CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_GRUP_DREPT FOR CONTAFIN_ORACLE.DEF_GRUP_DREPT; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.DEF_GRUP_DREPT TO PUBLIC; + +PROMPT Creating SYN_OPTIUNI_PROGRAME... +CREATE OR REPLACE PUBLIC SYNONYM SYN_OPTIUNI_PROGRAME FOR CONTAFIN_ORACLE.OPTIUNI_PROGRAME; +GRANT SELECT ON CONTAFIN_ORACLE.OPTIUNI_PROGRAME TO PUBLIC; + +PROMPT Creating SYN_HELPCONT... +CREATE OR REPLACE PUBLIC SYNONYM SYN_HELPCONT FOR CONTAFIN_ORACLE.HELPCONT; +GRANT SELECT ON CONTAFIN_ORACLE.HELPCONT TO PUBLIC; + +PROMPT Creating SYN_V_NOM_FIRME... +CREATE OR REPLACE PUBLIC SYNONYM SYN_V_NOM_FIRME FOR CONTAFIN_ORACLE.V_NOM_FIRME; +GRANT SELECT ON CONTAFIN_ORACLE.V_NOM_FIRME TO PUBLIC; + +-- Nomenclators +PROMPT Creating nomenclator synonyms... +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_JURIDICE FOR CONTAFIN_ORACLE.NOM_FORME_JURIDICE; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FORME_JURIDICE TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_ORGANIZARE FOR CONTAFIN_ORACLE.NOM_FORME_ORGANIZARE; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FORME_ORGANIZARE TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TIP_SOCIETATE FOR CONTAFIN_ORACLE.NOM_TIP_SOCIETATE; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_TIP_SOCIETATE TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_PROPRIETATE FOR CONTAFIN_ORACLE.NOM_FORME_PROPRIETATE; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FORME_PROPRIETATE TO PUBLIC; + +-- String aggregation +PROMPT Creating stringAgg synonym... +CREATE OR REPLACE PUBLIC SYNONYM STRINGAGG FOR CONTAFIN_ORACLE.STRINGAGG; +GRANT EXECUTE ON CONTAFIN_ORACLE.STRINGAGG TO PUBLIC; + +-- Types +PROMPT Creating type synonyms... +BEGIN + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.STRINGAGGTYPE TO PUBLIC'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +CREATE OR REPLACE PUBLIC SYNONYM CHAR_ROW FOR CONTAFIN_ORACLE.CHAR_ROW; +CREATE OR REPLACE PUBLIC SYNONYM CHAR_TAB FOR CONTAFIN_ORACLE.CHAR_TAB; +CREATE OR REPLACE PUBLIC SYNONYM NUM_ROW FOR CONTAFIN_ORACLE.NUM_ROW; +CREATE OR REPLACE PUBLIC SYNONYM NUM_TAB FOR CONTAFIN_ORACLE.NUM_TAB; + +BEGIN + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.NUM_ROW TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.NUM_TAB TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHAR_ROW TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHAR_TAB TO PUBLIC'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +CREATE OR REPLACE PUBLIC SYNONYM UW_SEL_ROW FOR CONTAFIN_ORACLE.UW_SEL_ROW; +CREATE OR REPLACE PUBLIC SYNONYM UW_SEL_TAB FOR CONTAFIN_ORACLE.UW_SEL_TAB; + +BEGIN + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.UW_SEL_ROW TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.UW_SEL_TAB TO PUBLIC'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +-- Functions +PROMPT Creating function synonyms... +CREATE OR REPLACE PUBLIC SYNONYM VALOARETAG FOR CONTAFIN_ORACLE.VALOARETAG; +CREATE OR REPLACE PUBLIC SYNONYM GETWORDCOUNT FOR CONTAFIN_ORACLE.GETWORDCOUNT; +CREATE OR REPLACE PUBLIC SYNONYM GETWORDNUM FOR CONTAFIN_ORACLE.GETWORDNUM; +CREATE OR REPLACE PUBLIC SYNONYM CHARC2COLLECTION FOR CONTAFIN_ORACLE.CHARC2COLLECTION; +CREATE OR REPLACE PUBLIC SYNONYM CHARN2COLLECTION FOR CONTAFIN_ORACLE.CHARN2COLLECTION; + +BEGIN + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.VALOARETAG TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.GETWORDCOUNT TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.GETWORDNUM TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHARC2COLLECTION TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHARN2COLLECTION TO PUBLIC'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +-- VAUTH_SERII synonym for CONTAFIN_ORACLE +PROMPT Creating VDEF_PROGRAME_SERII synonym... +BEGIN + EXECUTE IMMEDIATE 'DROP SYNONYM CONTAFIN_ORACLE.VDEF_PROGRAME_SERII'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ +CREATE SYNONYM CONTAFIN_ORACLE.VDEF_PROGRAME_SERII FOR SYS.VAUTH_SERII; +GRANT SELECT ON CONTAFIN_ORACLE.VDEF_PROGRAME_SERII TO CONTAFIN_ORACLE; + +-- Currency and location synonyms +PROMPT Creating currency/location synonyms... +CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_VALUTE_ISO FOR CONTAFIN_ORACLE.VNOM_VALUTE_ISO; +GRANT SELECT ON CONTAFIN_ORACLE.VNOM_VALUTE_ISO TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_CURS_ACTUALIZARI FOR CONTAFIN_ORACLE.CURS_ACTUALIZARI; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.CURS_ACTUALIZARI TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_VALUTE_ISO FOR CONTAFIN_ORACLE.NOM_VALUTE_ISO; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_VALUTE_ISO TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_CURS_COTATII FOR CONTAFIN_ORACLE.CURS_COTATII; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.CURS_COTATII TO PUBLIC; + +-- Location synonyms +PROMPT Creating location synonyms... +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_JUDETE FOR CONTAFIN_ORACLE.NOM_JUDETE; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_JUDETE TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_LOCALITATI FOR CONTAFIN_ORACLE.NOM_LOCALITATI; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_LOCALITATI TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_JUDETE FOR CONTAFIN_ORACLE.VNOM_JUDETE; +GRANT SELECT ON CONTAFIN_ORACLE.VNOM_JUDETE TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_LOCALITATI FOR CONTAFIN_ORACLE.VNOM_LOCALITATI; +GRANT SELECT ON CONTAFIN_ORACLE.VNOM_LOCALITATI TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_TARI FOR CONTAFIN_ORACLE.VNOM_TARI; +GRANT SELECT ON CONTAFIN_ORACLE.VNOM_TARI TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_CETATENII FOR CONTAFIN_ORACLE.NOM_CETATENII; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_CETATENII TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TARI FOR CONTAFIN_ORACLE.NOM_TARI; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_TARI TO PUBLIC; + +-- Packages +PROMPT Creating package synonyms... +CREATE OR REPLACE PUBLIC SYNONYM SYN_PACK_DEF_CO FOR CONTAFIN_ORACLE.PACK_DEF_CO; +GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_DEF_CO TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM PACK_UTILS FOR CONTAFIN_ORACLE.PACK_UTILS; +GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_UTILS TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM PACK_UTILS_FILE FOR CONTAFIN_ORACLE.PACK_UTILS_FILE; +GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_UTILS_FILE TO PUBLIC; + +CREATE OR REPLACE PUBLIC SYNONYM PACK_ROARTVAI FOR CONTAFIN_ORACLE.PACK_ROARTVAI; +GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_ROARTVAI TO PUBLIC; + +-- More types and synonyms +PROMPT Creating additional type synonyms... +CREATE OR REPLACE PUBLIC SYNONYM CONTRACT_M FOR CONTAFIN_ORACLE.CONTRACT_M; +CREATE OR REPLACE PUBLIC SYNONYM SAL_CONTRACT_M FOR CONTAFIN_ORACLE.SAL_CONTRACT_M; +CREATE OR REPLACE PUBLIC SYNONYM SAL_RED FOR CONTAFIN_ORACLE.SAL_RED; +CREATE OR REPLACE PUBLIC SYNONYM SAL_CAMPURI_RED FOR CONTAFIN_ORACLE.SAL_CAMPURI_RED; +CREATE OR REPLACE PUBLIC SYNONYM TABSTERS FOR CONTAFIN_ORACLE.TABSTERS; +CREATE OR REPLACE PUBLIC SYNONYM SAL_TABELESTERS FOR CONTAFIN_ORACLE.SAL_TABELESTERS; +CREATE OR REPLACE PUBLIC SYNONYM FF_SUME FOR CONTAFIN_ORACLE.FF_SUME; +CREATE OR REPLACE PUBLIC SYNONYM FF_PERSINTRET FOR CONTAFIN_ORACLE.FF_PERSINTRET; +CREATE OR REPLACE PUBLIC SYNONYM VANZARI_DETALII_TAB FOR CONTAFIN_ORACLE.VANZARI_DETALII_TAB; +CREATE OR REPLACE PUBLIC SYNONYM PIVOT_TABLE FOR CONTAFIN_ORACLE.PIVOT_TABLE; +CREATE OR REPLACE PUBLIC SYNONYM PIVOT_ROW FOR CONTAFIN_ORACLE.PIVOT_ROW; + +BEGIN + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CONTRACT_M TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_CONTRACT_M TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_RED TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_CAMPURI_RED TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.TABSTERS TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_TABELESTERS TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.FF_SUME TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.FF_PERSINTRET TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.VANZARI_DETALII_TAB TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.PIVOT_TABLE TO PUBLIC'; + EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.PIVOT_ROW TO PUBLIC'; +EXCEPTION WHEN OTHERS THEN NULL; +END; +/ + +-- SERVER_INFO +PROMPT Creating SERVER_INFO synonym... +CREATE OR REPLACE PUBLIC SYNONYM SERVER_INFO FOR CONTAFIN_ORACLE.SERVER_INFO; +GRANT SELECT, UPDATE ON CONTAFIN_ORACLE.SERVER_INFO TO PUBLIC; + +-- CAEN codes +PROMPT Creating SYN_NOM_CODURI_CAEN... +CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_CODURI_CAEN FOR CONTAFIN_ORACLE.NOM_CODURI_CAEN; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_CODURI_CAEN TO PUBLIC; + +-- Directory grants +PROMPT Granting directory access... +GRANT ALL ON DIRECTORY DMPDIR TO PUBLIC; +GRANT EXECUTE ON UTL_FILE TO PUBLIC; +GRANT EXECUTE ON DBMS_LOCK TO PUBLIC; + +COMMIT; + +SPOOL OFF + +SELECT 'SYNONYMS_COMPLETE' FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $synonymsSql + + if ($result -match "SYNONYMS_COMPLETE") { + Write-LogSuccess "Public synonyms created successfully" + } + else { + Write-LogWarning "Could not verify synonym creation" + Write-LogDebug $result + } + + # Configure Network ACL + Write-LogSection "Configuring Network ACL" + + $aclSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF SERVEROUTPUT ON + +PROMPT Configuring Network ACL for CONTAFIN_ORACLE... + +-- Drop existing ACL +BEGIN + DBMS_NETWORK_ACL_ADMIN.DROP_ACL(acl => 'roaupdate.xml'); +EXCEPTION + WHEN OTHERS THEN NULL; +END; +/ + +-- Create new ACL +BEGIN + DBMS_NETWORK_ACL_ADMIN.CREATE_ACL( + acl => 'roaupdate.xml', + description => 'Permissions to connect and resolve for ROA', + principal => 'CONTAFIN_ORACLE', + is_grant => TRUE, + privilege => 'connect' + ); + + DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE( + acl => 'roaupdate.xml', + principal => 'CONTAFIN_ORACLE', + is_grant => TRUE, + privilege => 'resolve' + ); + + DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL( + acl => 'roaupdate.xml', + host => '*' + ); +END; +/ +COMMIT; + +-- Grant UTL packages to CONTAFIN_ORACLE +GRANT EXECUTE ON UTL_INADDR TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_TCP TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_SMTP TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_HTTP TO CONTAFIN_ORACLE; + +SELECT 'ACL_CONFIGURED' FROM dual; +EXIT; +"@ + + $aclResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $aclSql -AsSysdba + + if ($aclResult -match "ACL_CONFIGURED") { + Write-LogSuccess "Network ACL configured" + } + else { + Write-LogWarning "Could not verify ACL configuration" + } + + # Count synonyms created + Write-LogSection "Verifying Synonyms" + + $countSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'SYNONYM_COUNT:' || COUNT(*) +FROM dba_synonyms +WHERE owner = 'PUBLIC' + AND table_owner = 'CONTAFIN_ORACLE'; +EXIT; +"@ + + $countResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $countSql -Silent + + $synonymCount = 0 + if ($countResult -match "SYNONYM_COUNT:(\d+)") { + $synonymCount = [int]$Matches[1] + } + + Write-Log "Public synonyms for CONTAFIN_ORACLE: $synonymCount" + + # Summary + Write-LogSection "Setup Complete" + Write-LogSuccess "Public synonyms and grants configured!" + Write-Log "" + Write-Log "Summary:" + Write-Log " Public synonyms created: $synonymCount" + Write-Log " SESIUNE context: Created" + Write-Log " Network ACL: Configured (roaupdate.xml)" + Write-Log " UTL packages granted: UTL_INADDR, UTL_TCP, UTL_SMTP, UTL_HTTP" + Write-Log "" + Write-Log "Next steps:" + Write-Log " 1. Run 05-import-companies.ps1 to import company schemas" + + Close-LogFile -Success $true + exit 0 +} +catch { + Write-LogError "Setup failed: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/05-import-companies.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/05-import-companies.ps1 new file mode 100644 index 0000000..06c4248 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/05-import-companies.ps1 @@ -0,0 +1,424 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Batch import company schemas from Data Pump dump files. + +.DESCRIPTION + Imports company schemas from dump files. CRITICAL: Reads passwords from + CONTAFIN_ORACLE.NOM_FIRME table to ensure correct authentication. + + For each company: + 1. Queries NOM_FIRME for schema name and password + 2. Finds matching DMP file in DumpDirectory + 3. Creates user with password from NOM_FIRME + 4. Runs impdp to import schema + 5. Logs progress + +.PARAMETER DumpDirectory + Directory containing company DMP files. Required. + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects. + +.PARAMETER ServiceName + Database service name. Default: XEPDB1 + +.PARAMETER SystemPassword + SYSTEM user password. Default: romfastsoft + +.PARAMETER ParallelJobs + Number of parallel import jobs. Default: 2 + +.PARAMETER Companies + Optional array of specific company names to import. If not specified, imports all. + +.PARAMETER DryRun + Show what would be imported without actually importing. + +.EXAMPLE + .\05-import-companies.ps1 -DumpDirectory "C:\dumps\companies" + +.EXAMPLE + .\05-import-companies.ps1 -DumpDirectory "D:\backups" -Companies "FIRMA1","FIRMA2" + +.EXAMPLE + .\05-import-companies.ps1 -DumpDirectory "C:\dumps" -DryRun + +.NOTES + File Name : 05-import-companies.ps1 + Prerequisite : Run 04-create-synonyms-grants.ps1 first + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [ValidateScript({ Test-Path $_ -PathType Container })] + [string]$DumpDirectory, + + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName = "XEPDB1", + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [int]$ParallelJobs = 2, + + [Parameter(Mandatory = $false)] + [string[]]$Companies, + + [Parameter(Mandatory = $false)] + [switch]$DryRun +) + +$ErrorActionPreference = 'Stop' + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\05-import-companies_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "05-import-companies.ps1" + +try { + Write-LogSection "Batch Import Company Schemas" + + if ($DryRun) { + Write-LogWarning "DRY RUN MODE - No changes will be made" + } + + # Validate Oracle installation + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword)) { + throw "Cannot connect to database. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Get company list from NOM_FIRME + Write-LogSection "Reading Company List from NOM_FIRME" + + $companySql = @" +SET PAGESIZE 10000 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500 +SELECT schema || '|' || parola +FROM CONTAFIN_ORACLE.NOM_FIRME +WHERE sters = 0 + AND schema IS NOT NULL +ORDER BY schema; +EXIT; +"@ + + $companyResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $companySql -Silent + + # Parse company data + $companyData = @{} + foreach ($line in $companyResult -split "`n") { + $line = $line.Trim() + if ($line -match "^([A-Z0-9_]+)\|(.*)$") { + $schema = $Matches[1] + $password = $Matches[2] + if (-not $password) { $password = "ROMFASTSOFT" } + $companyData[$schema] = $password + } + } + + Write-Log "Found $($companyData.Count) companies in NOM_FIRME" + + if ($companyData.Count -eq 0) { + Write-LogWarning "No companies found in NOM_FIRME" + Close-LogFile -Success $true + exit 0 + } + + # Filter companies if specified + if ($Companies) { + $filteredData = @{} + foreach ($company in $Companies) { + $companyUpper = $company.ToUpper() + if ($companyData.ContainsKey($companyUpper)) { + $filteredData[$companyUpper] = $companyData[$companyUpper] + } + else { + Write-LogWarning "Company $companyUpper not found in NOM_FIRME" + } + } + $companyData = $filteredData + Write-Log "Filtered to $($companyData.Count) companies" + } + + # Find matching dump files + Write-LogSection "Scanning Dump Files" + + $dumpFiles = Get-ChildItem -Path $DumpDirectory -Filter "*.dmp" -File + Write-Log "Found $($dumpFiles.Count) DMP files in $DumpDirectory" + + # Match companies with dump files + $importList = @() + $notFoundList = @() + + foreach ($schema in $companyData.Keys) { + # Try to find matching dump file (case-insensitive) + $matchingFile = $dumpFiles | Where-Object { + $_.BaseName -ieq $schema -or + $_.BaseName -imatch "^$schema[_\.]" -or + $_.BaseName -imatch "^${schema}$" + } | Select-Object -First 1 + + if ($matchingFile) { + $importList += [PSCustomObject]@{ + Schema = $schema + Password = $companyData[$schema] + DumpFile = $matchingFile.FullName + DumpSize = [math]::Round($matchingFile.Length / 1MB, 2) + } + } + else { + $notFoundList += $schema + } + } + + Write-Log "Companies to import: $($importList.Count)" + if ($notFoundList.Count -gt 0) { + Write-LogWarning "Companies without matching dump file: $($notFoundList.Count)" + foreach ($schema in $notFoundList) { + Write-Log " - $schema (no DMP file found)" + } + } + + if ($importList.Count -eq 0) { + Write-LogWarning "No companies to import" + Close-LogFile -Success $true + exit 0 + } + + # Display import plan + Write-LogSection "Import Plan" + + $totalSize = ($importList | Measure-Object -Property DumpSize -Sum).Sum + Write-Log "Total data to import: $totalSize MB" + Write-Log "" + Write-Log "Companies to import:" + foreach ($item in $importList) { + Write-Log " - $($item.Schema): $($item.DumpFile) ($($item.DumpSize) MB)" + } + + if ($DryRun) { + Write-LogSection "Dry Run Complete" + Write-Log "Would import $($importList.Count) company schemas" + Close-LogFile -Success $true + exit 0 + } + + # Ensure DMPDIR exists + $dmpDir = "C:\DMPDIR" + if (-not (Test-Path -Path $dmpDir)) { + New-Item -ItemType Directory -Path $dmpDir -Force | Out-Null + } + + # Process each company + Write-LogSection "Importing Companies" + + $successCount = 0 + $failCount = 0 + $startTime = Get-Date + + foreach ($item in $importList) { + Write-LogSection "Importing $($item.Schema)" + + try { + # Check if user already exists + $userExists = Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $item.Schema + + if ($userExists) { + Write-Log "User $($item.Schema) already exists" + + # Get current object count + $beforeCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $item.Schema + + $beforeTotal = if ($beforeCounts['TOTAL']) { $beforeCounts['TOTAL'] } else { 0 } + Write-Log "Existing objects: $beforeTotal" + } + else { + # Create user + Write-Log "Creating user $($item.Schema)..." + + $createUserSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF + +CREATE USER $($item.Schema) + IDENTIFIED BY "$($item.Password)" + DEFAULT TABLESPACE ROA + TEMPORARY TABLESPACE TEMP + PROFILE DEFAULT; + +GRANT CONNECT TO $($item.Schema); +GRANT RESOURCE TO $($item.Schema); +GRANT CREATE MATERIALIZED VIEW TO $($item.Schema); +GRANT CREATE PROCEDURE TO $($item.Schema); +GRANT CREATE SEQUENCE TO $($item.Schema); +GRANT CREATE TABLE TO $($item.Schema); +GRANT CREATE TRIGGER TO $($item.Schema); +GRANT CREATE VIEW TO $($item.Schema); +GRANT DEBUG CONNECT SESSION TO $($item.Schema); +GRANT SELECT ANY TABLE TO $($item.Schema); +GRANT CREATE TYPE TO $($item.Schema); +GRANT UNLIMITED TABLESPACE TO $($item.Schema); + +COMMIT; +SELECT 'USER_CREATED' FROM dual; +EXIT; +"@ + + $createResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $createUserSql -Silent + + if ($createResult -match "USER_CREATED") { + Write-LogSuccess "User $($item.Schema) created" + } + else { + throw "Failed to create user $($item.Schema)" + } + } + + # Copy dump file to DMPDIR if not already there + $dumpFileName = Split-Path -Path $item.DumpFile -Leaf + $targetDumpPath = Join-Path $dmpDir $dumpFileName + + if ($item.DumpFile -ne $targetDumpPath) { + Write-Log "Copying dump file to DMPDIR..." + Copy-Item -Path $item.DumpFile -Destination $targetDumpPath -Force + } + + # Run import + Write-Log "Running impdp for $($item.Schema)..." + + $impdpPath = Join-Path $oraHome "bin\impdp.exe" + $importLogFile = "$($item.Schema)_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" + + $connString = "SYSTEM/`"$SystemPassword`"@$ServiceName" + + # Check if dump has different schema name (remapping needed) + $remapParam = "" + $dumpBaseName = [System.IO.Path]::GetFileNameWithoutExtension($dumpFileName).ToUpper() + if ($dumpBaseName -ne $item.Schema) { + $remapParam = "remap_schema=$dumpBaseName`:$($item.Schema)" + Write-Log "Schema remap: $dumpBaseName -> $($item.Schema)" + } + + $impdpParams = @( + "`"$connString`"", + "directory=DMPDIR", + "dumpfile=$dumpFileName", + "logfile=$importLogFile", + "schemas=$($item.Schema)", + "table_exists_action=REPLACE" + ) + + if ($remapParam) { + $impdpParams += $remapParam + } + + $arguments = $impdpParams -join " " + + # Set Oracle environment + $env:ORACLE_HOME = $oraHome + $env:PATH = "$oraHome\bin;$env:PATH" + $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" + + $importStart = Get-Date + $process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru + + $importDuration = (Get-Date) - $importStart + Write-Log "Import completed in $([math]::Round($importDuration.TotalMinutes, 2)) minutes" + + # Verify import + $afterCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $item.Schema + + $afterTotal = if ($afterCounts['TOTAL']) { $afterCounts['TOTAL'] } else { 0 } + $afterInvalid = if ($afterCounts['INVALID']) { $afterCounts['INVALID'] } else { 0 } + + Write-Log "Objects after import: $afterTotal" + + if ($afterInvalid -gt 0) { + Write-LogWarning "Invalid objects: $afterInvalid" + + # Recompile + $recompileSql = @" +BEGIN + DBMS_UTILITY.COMPILE_SCHEMA('$($item.Schema)', FALSE); +END; +/ +EXIT; +"@ + Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent + } + + if ($process.ExitCode -eq 0) { + Write-LogSuccess "$($item.Schema) imported successfully ($afterTotal objects)" + $successCount++ + } + else { + Write-LogWarning "$($item.Schema) import completed with warnings" + $successCount++ + } + + # Clean up copied dump file + if ($item.DumpFile -ne $targetDumpPath -and (Test-Path -Path $targetDumpPath)) { + Remove-Item -Path $targetDumpPath -Force -ErrorAction SilentlyContinue + } + } + catch { + Write-LogError "Failed to import $($item.Schema): $_" + $failCount++ + } + } + + $totalDuration = (Get-Date) - $startTime + + # Summary + Write-LogSection "Import Complete" + + Write-LogSuccess "Company import batch completed!" + Write-Log "" + Write-Log "Summary:" + Write-Log " Total companies: $($importList.Count)" + Write-Log " Successful: $successCount" + Write-Log " Failed: $failCount" + Write-Log " Total duration: $([math]::Round($totalDuration.TotalMinutes, 2)) minutes" + Write-Log "" + + if ($notFoundList.Count -gt 0) { + Write-Log "Companies skipped (no dump file):" + foreach ($schema in $notFoundList) { + Write-Log " - $schema" + } + } + + Write-Log "" + Write-Log "Next steps:" + Write-Log " 1. Run 07-verify-installation.ps1 to verify all schemas" + + Close-LogFile -Success ($failCount -eq 0) + exit $(if ($failCount -eq 0) { 0 } else { 1 }) +} +catch { + Write-LogError "Import failed: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/06-add-company.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/06-add-company.ps1 new file mode 100644 index 0000000..2906c42 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/06-add-company.ps1 @@ -0,0 +1,327 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Add a new company schema to ROA Oracle. + +.DESCRIPTION + Creates a new company user/schema with either: + - Import from a template DMP file + - Empty schema with basic structures + +.PARAMETER CompanyName + Schema name for the new company. Required. Must be uppercase alphanumeric. + +.PARAMETER Password + Password for the new company schema. Default: ROMFASTSOFT + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects. + +.PARAMETER ServiceName + Database service name. Default: XEPDB1 + +.PARAMETER SystemPassword + SYSTEM user password. Default: romfastsoft + +.PARAMETER TemplateDump + Optional path to a template DMP file to import. + +.PARAMETER TemplateSchema + Schema name in the template DMP file if different from target (for remap). + +.PARAMETER Force + Drop and recreate if user already exists. + +.EXAMPLE + .\06-add-company.ps1 -CompanyName "NEWCOMPANY" + +.EXAMPLE + .\06-add-company.ps1 -CompanyName "FIRMA2024" -Password "SecurePass123" + +.EXAMPLE + .\06-add-company.ps1 -CompanyName "NEWFIRMA" -TemplateDump "C:\dumps\FIRMANOUA.dmp" -TemplateSchema "FIRMANOUA" + +.NOTES + File Name : 06-add-company.ps1 + Prerequisite : Run 04-create-synonyms-grants.ps1 first + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [ValidatePattern('^[A-Z0-9_]+$')] + [string]$CompanyName, + + [Parameter(Mandatory = $false)] + [string]$Password = "ROMFASTSOFT", + + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName = "XEPDB1", + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [ValidateScript({ Test-Path $_ })] + [string]$TemplateDump, + + [Parameter(Mandatory = $false)] + [string]$TemplateSchema, + + [Parameter(Mandatory = $false)] + [switch]$Force +) + +$ErrorActionPreference = 'Stop' + +# Ensure company name is uppercase +$CompanyName = $CompanyName.ToUpper() + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\06-add-company_${CompanyName}_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "06-add-company.ps1" + +try { + Write-LogSection "Adding New Company: $CompanyName" + + # Validate Oracle installation + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword)) { + throw "Cannot connect to database. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Check if user already exists + Write-Log "Checking if user $CompanyName exists..." + $userExists = Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $CompanyName + + if ($userExists) { + if ($Force) { + Write-LogWarning "User $CompanyName exists. Dropping due to -Force flag..." + + $dropSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF +DROP USER $CompanyName CASCADE; +SELECT 'USER_DROPPED' FROM dual; +EXIT; +"@ + $dropResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $dropSql + + if ($dropResult -match "USER_DROPPED") { + Write-Log "User $CompanyName dropped" + } + else { + throw "Failed to drop user $CompanyName" + } + } + else { + throw "User $CompanyName already exists. Use -Force to drop and recreate." + } + } + + # Create user + Write-LogSection "Creating User $CompanyName" + + $createUserSql = @" +SET ECHO OFF FEEDBACK ON VERIFY OFF + +PROMPT Creating user $CompanyName... +CREATE USER $CompanyName + IDENTIFIED BY "$Password" + DEFAULT TABLESPACE ROA + TEMPORARY TABLESPACE TEMP + PROFILE DEFAULT; + +PROMPT Granting role privileges... +GRANT CONNECT TO $CompanyName; +GRANT RESOURCE TO $CompanyName; + +PROMPT Granting system privileges... +GRANT CREATE MATERIALIZED VIEW TO $CompanyName; +GRANT CREATE PROCEDURE TO $CompanyName; +GRANT CREATE SEQUENCE TO $CompanyName; +GRANT CREATE TABLE TO $CompanyName; +GRANT CREATE TRIGGER TO $CompanyName; +GRANT CREATE VIEW TO $CompanyName; +GRANT DEBUG CONNECT SESSION TO $CompanyName; +GRANT SELECT ANY TABLE TO $CompanyName; +GRANT CREATE TYPE TO $CompanyName; +GRANT UNLIMITED TABLESPACE TO $CompanyName; + +COMMIT; +SELECT 'USER_CREATED' FROM dual; +EXIT; +"@ + + $createResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $createUserSql + + if ($createResult -match "USER_CREATED") { + Write-LogSuccess "User $CompanyName created successfully" + } + else { + Write-LogError "Failed to create user" + Write-LogDebug $createResult + throw "User creation failed" + } + + # Import from template if specified + if ($TemplateDump) { + Write-LogSection "Importing from Template" + + Write-Log "Template dump: $TemplateDump" + + # Determine template schema for remapping + if (-not $TemplateSchema) { + $TemplateSchema = [System.IO.Path]::GetFileNameWithoutExtension($TemplateDump).ToUpper() + Write-Log "Assuming template schema: $TemplateSchema" + } + + # Setup DMPDIR + $dmpDir = "C:\DMPDIR" + if (-not (Test-Path -Path $dmpDir)) { + New-Item -ItemType Directory -Path $dmpDir -Force | Out-Null + } + + New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $dmpDir + + # Copy dump to DMPDIR + $dumpFileName = Split-Path -Path $TemplateDump -Leaf + $targetDumpPath = Join-Path $dmpDir $dumpFileName + + if ($TemplateDump -ne $targetDumpPath) { + Write-Log "Copying dump file to DMPDIR..." + Copy-Item -Path $TemplateDump -Destination $targetDumpPath -Force + } + + # Run import with remap + Write-Log "Running impdp..." + + $impdpPath = Join-Path $oraHome "bin\impdp.exe" + $importLogFile = "${CompanyName}_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" + + $connString = "SYSTEM/`"$SystemPassword`"@$ServiceName" + + $impdpParams = @( + "`"$connString`"", + "directory=DMPDIR", + "dumpfile=$dumpFileName", + "logfile=$importLogFile", + "remap_schema=$TemplateSchema`:$CompanyName", + "table_exists_action=REPLACE" + ) + + $arguments = $impdpParams -join " " + + # Set Oracle environment + $env:ORACLE_HOME = $oraHome + $env:PATH = "$oraHome\bin;$env:PATH" + $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" + + $importStart = Get-Date + $process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru + + $importDuration = (Get-Date) - $importStart + Write-Log "Import completed in $([math]::Round($importDuration.TotalMinutes, 2)) minutes" + + if ($process.ExitCode -eq 0) { + Write-LogSuccess "Template imported successfully" + } + else { + Write-LogWarning "Import completed with warnings (exit code: $($process.ExitCode))" + } + + # Clean up copied dump file + if ($TemplateDump -ne $targetDumpPath -and (Test-Path -Path $targetDumpPath)) { + Remove-Item -Path $targetDumpPath -Force -ErrorAction SilentlyContinue + } + } + + # Get final object count + Write-LogSection "Verifying Schema" + + $counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $CompanyName + + $totalObjects = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 } + $invalidObjects = if ($counts['INVALID']) { $counts['INVALID'] } else { 0 } + + Write-Log "Total objects: $totalObjects" + + if ($invalidObjects -gt 0) { + Write-LogWarning "Invalid objects: $invalidObjects" + + # Recompile + Write-Log "Recompiling invalid objects..." + $recompileSql = @" +BEGIN + DBMS_UTILITY.COMPILE_SCHEMA('$CompanyName', FALSE); +END; +/ +EXIT; +"@ + Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent + + # Recheck + $recheckCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $CompanyName + + $recheckInvalid = if ($recheckCounts['INVALID']) { $recheckCounts['INVALID'] } else { 0 } + if ($recheckInvalid -lt $invalidObjects) { + Write-LogSuccess "Recompilation fixed $($invalidObjects - $recheckInvalid) objects" + } + } + + # Test connection with new user + Write-Log "Testing connection as $CompanyName..." + if (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Username $CompanyName -Password $Password) { + Write-LogSuccess "Connection test successful" + } + else { + Write-LogWarning "Could not connect as $CompanyName" + } + + # Summary + Write-LogSection "Company Added" + + Write-LogSuccess "Company $CompanyName added successfully!" + Write-Log "" + Write-Log "Summary:" + Write-Log " Schema name: $CompanyName" + Write-Log " Service: $ServiceName" + Write-Log " Objects: $totalObjects" + if ($TemplateDump) { + Write-Log " Template: $TemplateDump" + } + Write-Log "" + Write-Log "Connection string:" + Write-Log " $CompanyName/$Password@$ServiceName" + + Close-LogFile -Success $true + exit 0 +} +catch { + Write-LogError "Failed to add company: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/07-verify-installation.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/07-verify-installation.ps1 new file mode 100644 index 0000000..ede2d9d --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/07-verify-installation.ps1 @@ -0,0 +1,515 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Verify ROA Oracle installation. + +.DESCRIPTION + Performs comprehensive verification of the ROA Oracle installation: + - Database info (version, CDB/non-CDB, service name) + - Tablespace ROA status + - User CONTAFIN_ORACLE status and object count + - SYS custom objects status + - Public synonyms count + - Invalid objects count + - Company schemas list with object counts + +.PARAMETER OracleHome + Oracle home directory. If not specified, auto-detects. + +.PARAMETER ServiceName + Database service name. Default: XEPDB1 + +.PARAMETER SystemPassword + SYSTEM user password. Default: romfastsoft + +.PARAMETER Detailed + Show detailed object counts per schema. + +.PARAMETER OutputFile + Optional path to save verification report. + +.EXAMPLE + .\07-verify-installation.ps1 + +.EXAMPLE + .\07-verify-installation.ps1 -Detailed -OutputFile "C:\reports\verification.txt" + +.EXAMPLE + .\07-verify-installation.ps1 -ServiceName "ROA" -SystemPassword "mypassword" + +.NOTES + File Name : 07-verify-installation.ps1 + Prerequisite : ROA Oracle installation completed + Copyright 2024 : ROMFAST +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $false)] + [string]$ServiceName = "XEPDB1", + + [Parameter(Mandatory = $false)] + [string]$SystemPassword = "romfastsoft", + + [Parameter(Mandatory = $false)] + [switch]$Detailed, + + [Parameter(Mandatory = $false)] + [string]$OutputFile +) + +$ErrorActionPreference = 'Stop' + +# Source library functions +. "$PSScriptRoot\lib\logging-functions.ps1" +. "$PSScriptRoot\lib\oracle-functions.ps1" + +# Initialize logging +$logPath = Join-Path $PSScriptRoot "..\logs\07-verify-installation_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" +Initialize-LogFile -LogPath $logPath -ScriptName "07-verify-installation.ps1" + +# Initialize report +$report = [System.Text.StringBuilder]::new() + +function Add-ReportLine { + param([string]$Line) + [void]$report.AppendLine($Line) + Write-Host $Line +} + +function Add-ReportSection { + param([string]$Title) + Add-ReportLine "" + Add-ReportLine ("=" * 60) + Add-ReportLine " $Title" + Add-ReportLine ("=" * 60) + Add-ReportLine "" +} + +try { + Add-ReportSection "ROA Oracle Installation Verification Report" + Add-ReportLine "Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" + Add-ReportLine "Computer: $env:COMPUTERNAME" + + # Validate Oracle installation + $oraHome = Get-OracleHome -OracleHome $OracleHome + Write-LogSuccess "Oracle Home: $oraHome" + + # Test connection + Write-Log "Testing database connection..." + if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword)) { + throw "Cannot connect to database. Please verify ServiceName and SystemPassword." + } + Write-LogSuccess "Database connection successful" + + # Database Information + Add-ReportSection "Database Information" + + $dbInfoSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500 +SELECT 'VERSION:' || version_full FROM v`$instance; +SELECT 'EDITION:' || edition FROM v`$instance; +SELECT 'INSTANCE:' || instance_name FROM v`$instance; +SELECT 'HOST:' || host_name FROM v`$instance; +SELECT 'STARTUP:' || TO_CHAR(startup_time, 'YYYY-MM-DD HH24:MI:SS') FROM v`$instance; +SELECT 'STATUS:' || status FROM v`$instance; +SELECT 'CDB:' || CDB FROM v`$database; +SELECT 'DBNAME:' || name FROM v`$database; +SELECT 'OPEN_MODE:' || open_mode FROM v`$database; +EXIT; +"@ + + $dbInfo = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $dbInfoSql -Silent + + $dbData = @{} + foreach ($line in $dbInfo -split "`n") { + if ($line -match "^([A-Z_]+):(.*)$") { + $dbData[$Matches[1]] = $Matches[2].Trim() + } + } + + Add-ReportLine "Oracle Version: $($dbData['VERSION'])" + Add-ReportLine "Edition: $($dbData['EDITION'])" + Add-ReportLine "Instance Name: $($dbData['INSTANCE'])" + Add-ReportLine "Host Name: $($dbData['HOST'])" + Add-ReportLine "Database Name: $($dbData['DBNAME'])" + Add-ReportLine "CDB Mode: $($dbData['CDB'])" + Add-ReportLine "Open Mode: $($dbData['OPEN_MODE'])" + Add-ReportLine "Instance Status: $($dbData['STATUS'])" + Add-ReportLine "Startup Time: $($dbData['STARTUP'])" + Add-ReportLine "Service Name: $ServiceName" + Add-ReportLine "Oracle Home: $oraHome" + + # Container Information + $containerInfo = Test-PDB -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword + Add-ReportLine "Container: $($containerInfo.ContainerName)" + Add-ReportLine "Container ID: $($containerInfo.ConId)" + + # Tablespace ROA Status + Add-ReportSection "Tablespace ROA Status" + + $tsSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +COLUMN tablespace_name FORMAT A20 +COLUMN status FORMAT A10 +COLUMN contents FORMAT A10 +COLUMN allocation_type FORMAT A10 + +SELECT tablespace_name, status, contents, allocation_type +FROM dba_tablespaces +WHERE tablespace_name = 'ROA'; + +COLUMN file_name FORMAT A60 +COLUMN size_mb FORMAT 999,999.99 +COLUMN maxsize_mb FORMAT 999,999.99 +COLUMN autoextensible FORMAT A5 + +SELECT file_name, + ROUND(bytes/1024/1024, 2) AS size_mb, + ROUND(maxbytes/1024/1024, 2) AS maxsize_mb, + autoextensible +FROM dba_data_files +WHERE tablespace_name = 'ROA'; +EXIT; +"@ + + $tsResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $tsSql -Silent + + Add-ReportLine $tsResult + + # Check if ROA tablespace exists + if ($tsResult -notmatch "ROA") { + Add-ReportLine "" + Add-ReportLine "[WARNING] Tablespace ROA not found!" + } + + # CONTAFIN_ORACLE Status + Add-ReportSection "CONTAFIN_ORACLE Schema Status" + + $coExistsSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'USER_EXISTS' FROM dba_users WHERE username = 'CONTAFIN_ORACLE'; +EXIT; +"@ + + $coExists = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $coExistsSql -Silent + + if ($coExists -match "USER_EXISTS") { + Add-ReportLine "Status: EXISTS" + + $coCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" + + $coTotal = if ($coCounts['TOTAL']) { $coCounts['TOTAL'] } else { 0 } + $coInvalid = if ($coCounts['INVALID']) { $coCounts['INVALID'] } else { 0 } + + Add-ReportLine "Total Objects: $coTotal" + Add-ReportLine "Invalid Objects: $coInvalid" + + if ($Detailed) { + Add-ReportLine "" + Add-ReportLine "Object counts by type:" + foreach ($key in $coCounts.Keys | Sort-Object) { + if ($key -ne 'TOTAL' -and $key -ne 'INVALID') { + Add-ReportLine " $($key.PadRight(25)) $($coCounts[$key])" + } + } + } + } + else { + Add-ReportLine "Status: NOT FOUND" + Add-ReportLine "[WARNING] CONTAFIN_ORACLE user does not exist!" + } + + # SYS Custom Objects + Add-ReportSection "SYS Custom Objects" + + $sysObjSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +COLUMN object_name FORMAT A30 +COLUMN object_type FORMAT A15 +COLUMN status FORMAT A10 + +SELECT object_name, object_type, status +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ( + 'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', + 'NEWSCHEMAPROGRESS', 'DMPDIR' + ) +ORDER BY object_type, object_name; +EXIT; +"@ + + $sysResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $sysObjSql -AsSysdba -Silent + + Add-ReportLine $sysResult + + # Public Synonyms Count + Add-ReportSection "Public Synonyms" + + $synSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'TOTAL_SYNONYMS:' || COUNT(*) FROM dba_synonyms WHERE owner = 'PUBLIC'; +SELECT 'CO_SYNONYMS:' || COUNT(*) FROM dba_synonyms WHERE owner = 'PUBLIC' AND table_owner = 'CONTAFIN_ORACLE'; +SELECT 'SYS_SYNONYMS:' || COUNT(*) FROM dba_synonyms WHERE owner = 'PUBLIC' AND table_owner = 'SYS' AND table_name LIKE 'AUTH%'; +EXIT; +"@ + + $synResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $synSql -Silent + + $synData = @{} + foreach ($line in $synResult -split "`n") { + if ($line -match "^([A-Z_]+):(\d+)$") { + $synData[$Matches[1]] = [int]$Matches[2] + } + } + + Add-ReportLine "Total public synonyms: $($synData['TOTAL_SYNONYMS'])" + Add-ReportLine "CONTAFIN_ORACLE synonyms: $($synData['CO_SYNONYMS'])" + Add-ReportLine "SYS AUTH synonyms: $($synData['SYS_SYNONYMS'])" + + # All Invalid Objects + Add-ReportSection "Invalid Objects Summary" + + $invalidSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +COLUMN owner FORMAT A20 +COLUMN invalid_count FORMAT 999,999 + +SELECT owner, COUNT(*) AS invalid_count +FROM dba_objects +WHERE status = 'INVALID' + AND owner NOT IN ('SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'XDB', 'ORDSYS', + 'ORDDATA', 'MDSYS', 'CTXSYS', 'WMSYS', 'APEX_PUBLIC_USER') +GROUP BY owner +ORDER BY invalid_count DESC; +EXIT; +"@ + + $invalidResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $invalidSql -Silent + + if ($invalidResult.Trim() -eq "" -or $invalidResult -match "no rows selected") { + Add-ReportLine "No invalid objects found in application schemas." + } + else { + Add-ReportLine $invalidResult + } + + # Company Schemas + Add-ReportSection "Company Schemas" + + # Get company list from NOM_FIRME + $companySql = @" +SET PAGESIZE 1000 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200 +SELECT schema FROM CONTAFIN_ORACLE.NOM_FIRME WHERE sters = 0 AND schema IS NOT NULL ORDER BY schema; +EXIT; +"@ + + $companyList = @() + try { + $companyResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $companySql -Silent + + foreach ($line in $companyResult -split "`n") { + $schema = $line.Trim() + if ($schema -match "^[A-Z0-9_]+$") { + $companyList += $schema + } + } + } + catch { + Add-ReportLine "[WARNING] Could not query NOM_FIRME table" + } + + Add-ReportLine "Companies registered in NOM_FIRME: $($companyList.Count)" + Add-ReportLine "" + + if ($companyList.Count -gt 0) { + # Check which schemas exist + $existingSql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200 +SELECT username FROM dba_users WHERE username NOT IN ( + 'SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'XDB', 'ORDSYS', 'ORDDATA', 'MDSYS', + 'CTXSYS', 'WMSYS', 'APEX_PUBLIC_USER', 'CONTAFIN_ORACLE', 'ANONYMOUS', + 'APEX_040200', 'APEX_050000', 'APPQOSSYS', 'AUDSYS', 'DIP', 'DVF', 'DVSYS', + 'FLOWS_FILES', 'GGSYS', 'GSMADMIN_INTERNAL', 'GSMCATUSER', 'GSMUSER', + 'LBACSYS', 'MDDATA', 'OJVMSYS', 'OLAPSYS', 'ORACLE_OCM', 'REMOTE_SCHEDULER_AGENT', + 'SI_INFORMTN_SCHEMA', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR', + 'SYSBACKUP', 'SYSDG', 'SYSKM', 'SYSRAC', 'XS`$NULL' +) ORDER BY username; +EXIT; +"@ + + $existingResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $existingSql -Silent + + $existingSchemas = @() + foreach ($line in $existingResult -split "`n") { + $schema = $line.Trim() + if ($schema -match "^[A-Z0-9_]+$") { + $existingSchemas += $schema + } + } + + Add-ReportLine "Existing company schemas: $($existingSchemas.Count)" + Add-ReportLine "" + + # Show details + Add-ReportLine ("Schema".PadRight(25) + "Status".PadRight(12) + "Objects".PadRight(10) + "Invalid") + Add-ReportLine ("-" * 60) + + foreach ($schema in $companyList) { + $status = if ($existingSchemas -contains $schema) { "EXISTS" } else { "MISSING" } + + if ($status -eq "EXISTS") { + $counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $schema + + $total = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 } + $invalid = if ($counts['INVALID']) { $counts['INVALID'] } else { 0 } + + Add-ReportLine ("$schema".PadRight(25) + "$status".PadRight(12) + "$total".PadRight(10) + "$invalid") + } + else { + Add-ReportLine ("$schema".PadRight(25) + "$status".PadRight(12) + "-".PadRight(10) + "-") + } + } + + # Check for orphan schemas (exist in DB but not in NOM_FIRME) + $orphanSchemas = $existingSchemas | Where-Object { $companyList -notcontains $_ } + if ($orphanSchemas.Count -gt 0) { + Add-ReportLine "" + Add-ReportLine "Orphan schemas (not in NOM_FIRME):" + foreach ($schema in $orphanSchemas) { + $counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` + -Password $SystemPassword -SchemaName $schema + + $total = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 } + Add-ReportLine " - $schema ($total objects)" + } + } + } + + # Network ACL Status + Add-ReportSection "Network ACL Status" + + $aclSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +COLUMN acl FORMAT A30 +COLUMN principal FORMAT A20 +COLUMN privilege FORMAT A15 +COLUMN is_grant FORMAT A8 + +SELECT acl, principal, privilege, is_grant +FROM dba_network_acl_privileges +WHERE principal = 'CONTAFIN_ORACLE'; +EXIT; +"@ + + $aclResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYS" -Password $SystemPassword -SqlCommand $aclSql -AsSysdba -Silent + + if ($aclResult.Trim() -eq "" -or $aclResult -match "no rows selected") { + Add-ReportLine "No ACL configured for CONTAFIN_ORACLE" + } + else { + Add-ReportLine $aclResult + } + + # Context Status + Add-ReportSection "Context Status" + + $ctxSql = @" +SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 +COLUMN namespace FORMAT A20 +COLUMN schema FORMAT A25 +COLUMN package FORMAT A25 + +SELECT namespace, schema, package +FROM dba_context +WHERE namespace = 'SESIUNE'; +EXIT; +"@ + + $ctxResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $SystemPassword -SqlCommand $ctxSql -Silent + + if ($ctxResult.Trim() -eq "" -or $ctxResult -match "no rows selected") { + Add-ReportLine "SESIUNE context not found" + } + else { + Add-ReportLine $ctxResult + } + + # Final Summary + Add-ReportSection "Verification Summary" + + $issues = @() + + # Check for issues + if ($tsResult -notmatch "ROA") { + $issues += "Tablespace ROA not found" + } + + if ($coExists -notmatch "USER_EXISTS") { + $issues += "CONTAFIN_ORACLE user not found" + } + elseif ($coCounts -and $coCounts['INVALID'] -gt 0) { + $issues += "CONTAFIN_ORACLE has $($coCounts['INVALID']) invalid objects" + } + + if ($synData['CO_SYNONYMS'] -eq 0) { + $issues += "No public synonyms for CONTAFIN_ORACLE" + } + + $missingCompanies = $companyList | Where-Object { $existingSchemas -notcontains $_ } + if ($missingCompanies.Count -gt 0) { + $issues += "$($missingCompanies.Count) company schemas are missing" + } + + if ($issues.Count -eq 0) { + Add-ReportLine "[OK] All checks passed!" + Add-ReportLine "" + Add-ReportLine "The ROA Oracle installation appears to be complete and functional." + } + else { + Add-ReportLine "[WARNING] Issues found:" + Add-ReportLine "" + foreach ($issue in $issues) { + Add-ReportLine " - $issue" + } + } + + Add-ReportLine "" + Add-ReportLine ("=" * 60) + Add-ReportLine " End of Verification Report" + Add-ReportLine ("=" * 60) + + # Save report if requested + if ($OutputFile) { + Set-Content -Path $OutputFile -Value $report.ToString() -Encoding UTF8 + Write-LogSuccess "Report saved to: $OutputFile" + } + + Close-LogFile -Success ($issues.Count -eq 0) + exit $(if ($issues.Count -eq 0) { 0 } else { 1 }) +} +catch { + Write-LogError "Verification failed: $_" + Write-LogError $_.ScriptStackTrace + Close-LogFile -Success $false + exit 1 +} diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/logging-functions.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/logging-functions.ps1 new file mode 100644 index 0000000..34da2f5 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/logging-functions.ps1 @@ -0,0 +1,300 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Logging utility functions for ROA Oracle setup scripts. + +.DESCRIPTION + Provides standardized logging functions with timestamps, colors, and file output. + All log messages are written to both console and optional log file. + +.NOTES + File Name : logging-functions.ps1 + Prerequisite : PowerShell 5.1 or higher + Copyright 2024 : ROMFAST +#> + +# Script-level variables for logging +$script:LogFile = $null +$script:LogLevel = 'Info' + +<# +.SYNOPSIS + Initialize the log file with a header. + +.DESCRIPTION + Creates or clears a log file and writes a header with timestamp and script info. + +.PARAMETER LogPath + Path to the log file. + +.PARAMETER ScriptName + Name of the calling script for the header. + +.EXAMPLE + Initialize-LogFile -LogPath "C:\logs\setup.log" -ScriptName "01-setup-database.ps1" +#> +function Initialize-LogFile { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$LogPath, + + [Parameter(Mandatory = $false)] + [string]$ScriptName = "ROA Setup" + ) + + $script:LogFile = $LogPath + + # Create directory if it doesn't exist + $logDir = Split-Path -Path $LogPath -Parent + if ($logDir -and -not (Test-Path -Path $logDir)) { + New-Item -ItemType Directory -Path $logDir -Force | Out-Null + } + + # Write header + $header = @" +================================================================================ + ROA Oracle Setup Log + Script: $ScriptName + Started: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') + Computer: $env:COMPUTERNAME + User: $env:USERNAME +================================================================================ + +"@ + + Set-Content -Path $LogPath -Value $header -Encoding UTF8 +} + +<# +.SYNOPSIS + Write a log message with timestamp. + +.DESCRIPTION + Writes a timestamped message to console and log file. Supports different + message types (Info, Warning, Error, Success, Debug). + +.PARAMETER Message + The message to log. + +.PARAMETER Level + The log level: Info, Warning, Error, Success, Debug. + +.PARAMETER NoConsole + If specified, only writes to log file. + +.EXAMPLE + Write-Log "Starting database setup" -Level Info +#> +function Write-Log { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Message, + + [Parameter(Mandatory = $false)] + [ValidateSet('Info', 'Warning', 'Error', 'Success', 'Debug')] + [string]$Level = 'Info', + + [Parameter(Mandatory = $false)] + [switch]$NoConsole + ) + + $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' + $logMessage = "[$timestamp] [$Level] $Message" + + # Write to log file if initialized + if ($script:LogFile) { + Add-Content -Path $script:LogFile -Value $logMessage -Encoding UTF8 + } + + # Write to console with appropriate color + if (-not $NoConsole) { + $color = switch ($Level) { + 'Info' { 'White' } + 'Warning' { 'Yellow' } + 'Error' { 'Red' } + 'Success' { 'Green' } + 'Debug' { 'Cyan' } + default { 'White' } + } + + $prefix = switch ($Level) { + 'Info' { '[INFO] ' } + 'Warning' { '[WARN] ' } + 'Error' { '[ERROR] ' } + 'Success' { '[OK] ' } + 'Debug' { '[DEBUG] ' } + default { '[INFO] ' } + } + + Write-Host "$prefix$Message" -ForegroundColor $color + } +} + +<# +.SYNOPSIS + Write an error message in red. + +.DESCRIPTION + Convenience function for logging error messages. + +.PARAMETER Message + The error message to log. + +.EXAMPLE + Write-LogError "Failed to connect to database" +#> +function Write-LogError { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Message + ) + + Write-Log -Message $Message -Level Error +} + +<# +.SYNOPSIS + Write a success message in green. + +.DESCRIPTION + Convenience function for logging success messages. + +.PARAMETER Message + The success message to log. + +.EXAMPLE + Write-LogSuccess "Database created successfully" +#> +function Write-LogSuccess { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Message + ) + + Write-Log -Message $Message -Level Success +} + +<# +.SYNOPSIS + Write a warning message in yellow. + +.DESCRIPTION + Convenience function for logging warning messages. + +.PARAMETER Message + The warning message to log. + +.EXAMPLE + Write-LogWarning "User already exists, skipping creation" +#> +function Write-LogWarning { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Message + ) + + Write-Log -Message $Message -Level Warning +} + +<# +.SYNOPSIS + Write a debug message in cyan. + +.DESCRIPTION + Convenience function for logging debug messages. + +.PARAMETER Message + The debug message to log. + +.EXAMPLE + Write-LogDebug "SQL command: SELECT * FROM dual" +#> +function Write-LogDebug { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Message + ) + + Write-Log -Message $Message -Level Debug +} + +<# +.SYNOPSIS + Write a section header to the log. + +.DESCRIPTION + Writes a formatted section header for visual separation in logs. + +.PARAMETER Title + The section title. + +.EXAMPLE + Write-LogSection "Creating Tablespace ROA" +#> +function Write-LogSection { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Title + ) + + $separator = "=" * 60 + $message = @" + +$separator + $Title +$separator +"@ + + if ($script:LogFile) { + Add-Content -Path $script:LogFile -Value $message -Encoding UTF8 + } + + Write-Host "" + Write-Host $separator -ForegroundColor Cyan + Write-Host " $Title" -ForegroundColor Cyan + Write-Host $separator -ForegroundColor Cyan +} + +<# +.SYNOPSIS + Close the log file with a footer. + +.DESCRIPTION + Writes a closing footer to the log file with completion status. + +.PARAMETER Success + Indicates if the script completed successfully. + +.EXAMPLE + Close-LogFile -Success $true +#> +function Close-LogFile { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [bool]$Success = $true + ) + + if ($script:LogFile) { + $status = if ($Success) { "COMPLETED SUCCESSFULLY" } else { "COMPLETED WITH ERRORS" } + $footer = @" + +================================================================================ + $status + Finished: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') +================================================================================ +"@ + Add-Content -Path $script:LogFile -Value $footer -Encoding UTF8 + } +} + +# Note: Functions are available when dot-sourced (. .\logging-functions.ps1) +# Do NOT use Export-ModuleMember - it only works inside .psm1 modules diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/oracle-functions.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/oracle-functions.ps1 new file mode 100644 index 0000000..ee7b73c --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/oracle-functions.ps1 @@ -0,0 +1,952 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Oracle connectivity and operations functions for ROA setup scripts. + +.DESCRIPTION + Provides functions for Oracle database connectivity, SQL*Plus execution, + version detection, and Data Pump operations. + +.NOTES + File Name : oracle-functions.ps1 + Prerequisite : PowerShell 5.1 or higher, Oracle Client installed + Copyright 2024 : ROMFAST +#> + +# Source logging functions +. "$PSScriptRoot\logging-functions.ps1" + +<# +.SYNOPSIS + Find Oracle Home directory. + +.DESCRIPTION + Auto-detects Oracle Home from registry, environment variable, or common paths. + +.PARAMETER OracleHome + Optional explicit Oracle Home path. If not specified, auto-detects. + +.OUTPUTS + String. The Oracle Home path. + +.EXAMPLE + $oracleHome = Get-OracleHome +#> +function Get-OracleHome { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome + ) + + # If explicitly provided, validate and return + if ($OracleHome) { + if (Test-Path -Path "$OracleHome\bin\sqlplus.exe") { + return $OracleHome + } + throw "Invalid Oracle Home: sqlplus.exe not found at $OracleHome\bin\sqlplus.exe" + } + + # Try ORACLE_HOME environment variable + if ($env:ORACLE_HOME -and (Test-Path -Path "$env:ORACLE_HOME\bin\sqlplus.exe")) { + return $env:ORACLE_HOME + } + + # Try registry for Oracle XE + $regPaths = @( + 'HKLM:\SOFTWARE\Oracle\KEY_OraDB21Home1', + 'HKLM:\SOFTWARE\Oracle\KEY_OraDB18Home1', + 'HKLM:\SOFTWARE\Oracle\KEY_XE', + 'HKLM:\SOFTWARE\Wow6432Node\Oracle\KEY_OraDB21Home1', + 'HKLM:\SOFTWARE\Wow6432Node\Oracle\KEY_OraDB18Home1' + ) + + foreach ($regPath in $regPaths) { + if (Test-Path -Path $regPath) { + $oraHome = (Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue).ORACLE_HOME + if ($oraHome -and (Test-Path -Path "$oraHome\bin\sqlplus.exe")) { + return $oraHome + } + } + } + + # Try common installation paths (including user-specific paths) + $currentUser = $env:USERNAME + $commonPaths = @( + "C:\app\$currentUser\product\21c\dbhomeXE", + "C:\app\$currentUser\product\21c\dbhome_1", + "C:\app\$currentUser\product\18c\dbhomeXE", + 'C:\app\oracle\product\21c\dbhomeXE', + 'C:\app\oracle\product\21c\dbhome_1', + 'C:\app\oracle\product\18c\dbhomeXE', + 'C:\app\romfast\product\21c\dbhomeXE', + 'C:\app\romfast\product\21c\dbhome_1', + 'C:\oraclexe\app\oracle\product\11.2.0\server', + "D:\app\$currentUser\product\21c\dbhomeXE", + 'D:\app\oracle\product\21c\dbhomeXE', + 'D:\app\oracle\product\18c\dbhomeXE' + ) + + foreach ($path in $commonPaths) { + if (Test-Path -Path "$path\bin\sqlplus.exe") { + return $path + } + } + + throw "Oracle Home not found. Please specify -OracleHome parameter or set ORACLE_HOME environment variable." +} + +<# +.SYNOPSIS + Get Oracle version information. + +.DESCRIPTION + Detects Oracle version (XE vs SE), edition, and whether it's a Container Database (CDB). + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Username + Username for connection (default: SYSTEM). + +.PARAMETER Password + Password for connection. + +.OUTPUTS + PSCustomObject with Version, Edition, IsCDB, IsXE properties. + +.EXAMPLE + $version = Get-OracleVersion -ServiceName "XE" -Password "oracle" +#> +function Get-OracleVersion { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $false)] + [string]$Username = "SYSTEM", + + [Parameter(Mandatory = $true)] + [string]$Password + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + + $sql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'VERSION:' || version_full FROM v`$instance; +SELECT 'EDITION:' || edition FROM v`$instance; +SELECT 'CDB:' || CDB FROM v`$database; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username $Username -Password $Password -SqlCommand $sql -Silent + + $versionInfo = [PSCustomObject]@{ + Version = "" + Edition = "" + IsCDB = $false + IsXE = $false + FullInfo = $result + } + + foreach ($line in $result -split "`n") { + if ($line -match "^VERSION:(.+)$") { + $versionInfo.Version = $Matches[1].Trim() + } + elseif ($line -match "^EDITION:(.+)$") { + $versionInfo.Edition = $Matches[1].Trim() + $versionInfo.IsXE = $versionInfo.Edition -match "XE|Express" + } + elseif ($line -match "^CDB:(.+)$") { + $versionInfo.IsCDB = $Matches[1].Trim() -eq "YES" + } + } + + return $versionInfo +} + +<# +.SYNOPSIS + Get the default service name based on Oracle configuration. + +.DESCRIPTION + Auto-detects the appropriate service name. Returns XEPDB1 for Oracle XE CDB, + or ROA for traditional non-CDB installations. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER SystemPassword + SYSTEM user password. + +.OUTPUTS + String. The service name. + +.EXAMPLE + $serviceName = Get-ServiceName -SystemPassword "oracle" +#> +function Get-ServiceName { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$SystemPassword + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + + # First try to connect to XE and check if it's CDB + try { + $version = Get-OracleVersion -OracleHome $oraHome -ServiceName "XE" ` + -Password $SystemPassword -ErrorAction Stop + + if ($version.IsCDB) { + # For CDB, use XEPDB1 (the default pluggable database) + return "XEPDB1" + } + else { + return "XE" + } + } + catch { + # Try ROA as service name + try { + $null = Test-OracleConnection -OracleHome $oraHome -ServiceName "ROA" ` + -Username "SYSTEM" -Password $SystemPassword -ErrorAction Stop + return "ROA" + } + catch { + # Default to XEPDB1 for modern XE installations + return "XEPDB1" + } + } +} + +<# +.SYNOPSIS + Test Oracle database connection. + +.DESCRIPTION + Attempts to connect to Oracle and verifies the connection is successful. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Username + Username for connection. + +.PARAMETER Password + Password for connection. + +.OUTPUTS + Boolean. True if connection successful. + +.EXAMPLE + if (Test-OracleConnection -ServiceName "XEPDB1" -Username "SYSTEM" -Password "oracle") { + Write-Host "Connected!" + } +#> +function Test-OracleConnection { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $false)] + [string]$Username = "SYSTEM", + + [Parameter(Mandatory = $true)] + [string]$Password, + + [Parameter(Mandatory = $false)] + [switch]$AsSysdba + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + + $sql = "SELECT 'CONNECTED' FROM dual; EXIT;" + + try { + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username $Username -Password $Password -SqlCommand $sql -AsSysdba:$AsSysdba -Silent + + return $result -match "CONNECTED" + } + catch { + return $false + } +} + +<# +.SYNOPSIS + Test if connected to a PDB or non-CDB. + +.DESCRIPTION + Checks the current container type to determine if connected to a PDB, + the CDB root, or a non-CDB database. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Username + Username for connection. + +.PARAMETER Password + Password for connection. + +.OUTPUTS + PSCustomObject with ContainerName, IsPDB, IsCDBRoot, IsNonCDB properties. + +.EXAMPLE + $containerInfo = Test-PDB -ServiceName "XEPDB1" -Password "oracle" +#> +function Test-PDB { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $false)] + [string]$Username = "SYSTEM", + + [Parameter(Mandatory = $true)] + [string]$Password + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + + $sql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'CONTAINER:' || SYS_CONTEXT('USERENV', 'CON_NAME') FROM dual; +SELECT 'CON_ID:' || SYS_CONTEXT('USERENV', 'CON_ID') FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username $Username -Password $Password -SqlCommand $sql -Silent + + $containerInfo = [PSCustomObject]@{ + ContainerName = "" + ConId = 0 + IsPDB = $false + IsCDBRoot = $false + IsNonCDB = $false + } + + foreach ($line in $result -split "`n") { + if ($line -match "^CONTAINER:(.+)$") { + $containerInfo.ContainerName = $Matches[1].Trim() + } + elseif ($line -match "^CON_ID:(.+)$") { + $containerInfo.ConId = [int]$Matches[1].Trim() + } + } + + if ($containerInfo.ConId -eq 0) { + $containerInfo.IsNonCDB = $true + } + elseif ($containerInfo.ConId -eq 1) { + $containerInfo.IsCDBRoot = $true + } + else { + $containerInfo.IsPDB = $true + } + + return $containerInfo +} + +<# +.SYNOPSIS + Execute SQL via SQL*Plus. + +.DESCRIPTION + Runs a SQL command or file using SQL*Plus and returns the output. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Username + Username for connection. + +.PARAMETER Password + Password for connection. + +.PARAMETER SqlCommand + SQL command(s) to execute. + +.PARAMETER SqlFile + Path to SQL file to execute. + +.PARAMETER AsSysdba + Connect as SYSDBA. + +.PARAMETER Silent + Suppress console output. + +.OUTPUTS + String. The SQL*Plus output. + +.EXAMPLE + Invoke-SqlPlus -ServiceName "XEPDB1" -Username "SYSTEM" -Password "oracle" -SqlCommand "SELECT * FROM dual;" + +.EXAMPLE + Invoke-SqlPlus -ServiceName "XEPDB1" -Username "SYS" -Password "oracle" -SqlFile "C:\scripts\setup.sql" -AsSysdba +#> +function Invoke-SqlPlus { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $false)] + [string]$Username = "SYSTEM", + + [Parameter(Mandatory = $true)] + [string]$Password, + + [Parameter(Mandatory = $false)] + [string]$SqlCommand, + + [Parameter(Mandatory = $false)] + [string]$SqlFile, + + [Parameter(Mandatory = $false)] + [switch]$AsSysdba, + + [Parameter(Mandatory = $false)] + [switch]$Silent + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + $sqlplus = Join-Path $oraHome "bin\sqlplus.exe" + + if (-not (Test-Path -Path $sqlplus)) { + throw "SQL*Plus not found at: $sqlplus" + } + + # Build connection string + $sysdba = if ($AsSysdba) { " as sysdba" } else { "" } + $connString = "$Username/`"$Password`"@$ServiceName$sysdba" + + $tempFile = $null + + try { + if ($SqlFile) { + # Execute SQL file + if (-not (Test-Path -Path $SqlFile)) { + throw "SQL file not found: $SqlFile" + } + + $arguments = "-S `"$connString`" @`"$SqlFile`"" + } + else { + # Create temp file for SQL command + $tempFile = [System.IO.Path]::GetTempFileName() + $tempFile = [System.IO.Path]::ChangeExtension($tempFile, ".sql") + Set-Content -Path $tempFile -Value $SqlCommand -Encoding ASCII + + $arguments = "-S `"$connString`" @`"$tempFile`"" + } + + # Set Oracle environment + $env:ORACLE_HOME = $oraHome + $env:PATH = "$oraHome\bin;$env:PATH" + $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" + + # Execute SQL*Plus + $processInfo = New-Object System.Diagnostics.ProcessStartInfo + $processInfo.FileName = $sqlplus + $processInfo.Arguments = "-S `"$connString`"" + $processInfo.RedirectStandardInput = $true + $processInfo.RedirectStandardOutput = $true + $processInfo.RedirectStandardError = $true + $processInfo.UseShellExecute = $false + $processInfo.CreateNoWindow = $true + + $process = New-Object System.Diagnostics.Process + $process.StartInfo = $processInfo + $process.Start() | Out-Null + + # Send SQL + if ($SqlFile) { + $process.StandardInput.WriteLine("@`"$SqlFile`"") + } + else { + $process.StandardInput.WriteLine($SqlCommand) + } + $process.StandardInput.Close() + + $output = $process.StandardOutput.ReadToEnd() + $errorOutput = $process.StandardError.ReadToEnd() + $process.WaitForExit() + + if ($errorOutput) { + $output += "`n$errorOutput" + } + + # Check for Oracle errors + if ($output -match "ORA-\d{5}:|SP2-\d{4}:") { + if (-not $Silent) { + Write-LogWarning "SQL*Plus returned errors:" + Write-Host $output -ForegroundColor Yellow + } + } + + return $output + } + finally { + if ($tempFile -and (Test-Path -Path $tempFile)) { + Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue + } + } +} + +<# +.SYNOPSIS + Create Oracle directory object for Data Pump. + +.DESCRIPTION + Creates a directory object in Oracle for Data Pump operations if it doesn't exist. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Password + SYS or SYSTEM password. + +.PARAMETER DirectoryName + Oracle directory object name (default: DMPDIR). + +.PARAMETER DirectoryPath + File system path for the directory (default: C:\DMPDIR). + +.EXAMPLE + New-OracleDirectory -ServiceName "XEPDB1" -Password "oracle" -DirectoryPath "D:\Dumps" +#> +function New-OracleDirectory { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $true)] + [string]$Password, + + [Parameter(Mandatory = $false)] + [string]$DirectoryName = "DMPDIR", + + [Parameter(Mandatory = $false)] + [string]$DirectoryPath = "C:\DMPDIR" + ) + + # Create physical directory if it doesn't exist + if (-not (Test-Path -Path $DirectoryPath)) { + New-Item -ItemType Directory -Path $DirectoryPath -Force | Out-Null + Write-Log "Created directory: $DirectoryPath" + } + + $sql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +CREATE OR REPLACE DIRECTORY $DirectoryName AS '$DirectoryPath'; +GRANT READ, WRITE ON DIRECTORY $DirectoryName TO PUBLIC; +COMMIT; +SELECT 'DIRECTORY_CREATED' FROM dual; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName ` + -Username "SYS" -Password $Password -SqlCommand $sql -AsSysdba -Silent + + if ($result -match "DIRECTORY_CREATED") { + Write-Log "Oracle directory $DirectoryName created pointing to $DirectoryPath" + return $true + } + else { + Write-LogWarning "Could not verify directory creation" + return $false + } +} + +<# +.SYNOPSIS + Get the default datafile path based on Oracle installation. + +.DESCRIPTION + Determines the appropriate datafile location based on Oracle Home and version. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Password + SYSTEM password. + +.OUTPUTS + String. The datafile directory path. + +.EXAMPLE + $datafilePath = Get-DatafilePath -ServiceName "XEPDB1" -Password "oracle" +#> +function Get-DatafilePath { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $true)] + [string]$Password + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + + # Query Oracle for default datafile location + $sql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500 +SELECT 'DATAFILE_PATH:' || SUBSTR(file_name, 1, INSTR(file_name, '\', -1)) +FROM dba_data_files +WHERE tablespace_name = 'SYSTEM' +AND ROWNUM = 1; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent + + foreach ($line in $result -split "`n") { + if ($line -match "^DATAFILE_PATH:(.+)$") { + $path = $Matches[1].Trim() + # Remove trailing backslash if present + return $path.TrimEnd('\') + } + } + + # Fallback to common paths based on Oracle Home + $version = Get-OracleVersion -OracleHome $oraHome -ServiceName $ServiceName -Password $Password + + if ($version.IsXE) { + if ($version.Version -match "^21") { + return "C:\app\oracle\oradata\XE\XEPDB1" + } + elseif ($version.Version -match "^18") { + return "C:\app\oracle\oradata\XE" + } + } + + # Default fallback + return "C:\app\oracle\oradata" +} + +<# +.SYNOPSIS + Execute Data Pump import. + +.DESCRIPTION + Runs impdp with specified parameters. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Username + Username for connection (default: SYSTEM). + +.PARAMETER Password + Password for connection. + +.PARAMETER DumpFile + Name of the dump file (in DMPDIR). + +.PARAMETER LogFile + Name of the log file. + +.PARAMETER Schemas + Schema(s) to import. + +.PARAMETER RemapSchema + Remap schema mapping (e.g., "OLD_SCHEMA:NEW_SCHEMA"). + +.PARAMETER DirectoryName + Oracle directory object name (default: DMPDIR). + +.PARAMETER TableExists + Table exists action: SKIP, APPEND, TRUNCATE, REPLACE (default: REPLACE). + +.PARAMETER AdditionalParams + Additional impdp parameters. + +.OUTPUTS + PSCustomObject with Success, LogContent, ErrorMessage properties. + +.EXAMPLE + Invoke-DataPumpImport -ServiceName "XEPDB1" -Password "oracle" -DumpFile "CONTAFIN_ORACLE.dmp" -Schemas "CONTAFIN_ORACLE" +#> +function Invoke-DataPumpImport { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $false)] + [string]$Username = "SYSTEM", + + [Parameter(Mandatory = $true)] + [string]$Password, + + [Parameter(Mandatory = $true)] + [string]$DumpFile, + + [Parameter(Mandatory = $false)] + [string]$LogFile, + + [Parameter(Mandatory = $false)] + [string[]]$Schemas, + + [Parameter(Mandatory = $false)] + [string]$RemapSchema, + + [Parameter(Mandatory = $false)] + [string]$DirectoryName = "DMPDIR", + + [Parameter(Mandatory = $false)] + [ValidateSet('SKIP', 'APPEND', 'TRUNCATE', 'REPLACE')] + [string]$TableExists = "REPLACE", + + [Parameter(Mandatory = $false)] + [string]$AdditionalParams + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + $impdp = Join-Path $oraHome "bin\impdp.exe" + + if (-not (Test-Path -Path $impdp)) { + throw "impdp not found at: $impdp" + } + + # Build impdp command + if (-not $LogFile) { + $LogFile = [System.IO.Path]::GetFileNameWithoutExtension($DumpFile) + "_import.log" + } + + $connString = "$Username/`"$Password`"@$ServiceName" + + $params = @( + "`"$connString`"", + "directory=$DirectoryName", + "dumpfile=$DumpFile", + "logfile=$LogFile", + "table_exists_action=$TableExists" + ) + + if ($Schemas) { + $params += "schemas=$($Schemas -join ',')" + } + + if ($RemapSchema) { + $params += "remap_schema=$RemapSchema" + } + + if ($AdditionalParams) { + $params += $AdditionalParams + } + + $arguments = $params -join " " + + Write-Log "Executing: impdp $($params -join ' ' -replace $Password, '****')" + + # Set Oracle environment + $env:ORACLE_HOME = $oraHome + $env:PATH = "$oraHome\bin;$env:PATH" + $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" + + # Execute impdp + $process = Start-Process -FilePath $impdp -ArgumentList $arguments -Wait -NoNewWindow -PassThru ` + -RedirectStandardOutput "$env:TEMP\impdp_out.txt" -RedirectStandardError "$env:TEMP\impdp_err.txt" + + $stdout = Get-Content -Path "$env:TEMP\impdp_out.txt" -Raw -ErrorAction SilentlyContinue + $stderr = Get-Content -Path "$env:TEMP\impdp_err.txt" -Raw -ErrorAction SilentlyContinue + + $result = [PSCustomObject]@{ + Success = $process.ExitCode -eq 0 + ExitCode = $process.ExitCode + Output = $stdout + ErrorOutput = $stderr + LogFile = $LogFile + } + + # Clean up temp files + Remove-Item -Path "$env:TEMP\impdp_out.txt" -Force -ErrorAction SilentlyContinue + Remove-Item -Path "$env:TEMP\impdp_err.txt" -Force -ErrorAction SilentlyContinue + + return $result +} + +<# +.SYNOPSIS + Check if a user/schema exists in the database. + +.DESCRIPTION + Queries DBA_USERS to check if a user exists. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Password + SYSTEM password. + +.PARAMETER SchemaName + Name of the schema/user to check. + +.OUTPUTS + Boolean. True if user exists. + +.EXAMPLE + if (Test-OracleUser -ServiceName "XEPDB1" -Password "oracle" -SchemaName "CONTAFIN_ORACLE") { + Write-Host "User exists" + } +#> +function Test-OracleUser { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $true)] + [string]$Password, + + [Parameter(Mandatory = $true)] + [string]$SchemaName + ) + + $sql = @" +SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF +SELECT 'USER_EXISTS' FROM dba_users WHERE username = UPPER('$SchemaName'); +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent + + return $result -match "USER_EXISTS" +} + +<# +.SYNOPSIS + Get object count for a schema. + +.DESCRIPTION + Counts objects in a schema grouped by type. + +.PARAMETER OracleHome + Oracle Home directory. + +.PARAMETER ServiceName + Database service name. + +.PARAMETER Password + SYSTEM password. + +.PARAMETER SchemaName + Name of the schema. + +.OUTPUTS + Hashtable with object types and counts. + +.EXAMPLE + $counts = Get-SchemaObjectCount -ServiceName "XEPDB1" -Password "oracle" -SchemaName "CONTAFIN_ORACLE" +#> +function Get-SchemaObjectCount { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome, + + [Parameter(Mandatory = $true)] + [string]$ServiceName, + + [Parameter(Mandatory = $true)] + [string]$Password, + + [Parameter(Mandatory = $true)] + [string]$SchemaName + ) + + $sql = @" +SET PAGESIZE 1000 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200 +SELECT object_type || ':' || COUNT(*) +FROM dba_objects +WHERE owner = UPPER('$SchemaName') +GROUP BY object_type +ORDER BY object_type; +SELECT 'TOTAL:' || COUNT(*) FROM dba_objects WHERE owner = UPPER('$SchemaName'); +SELECT 'INVALID:' || COUNT(*) FROM dba_objects WHERE owner = UPPER('$SchemaName') AND status = 'INVALID'; +EXIT; +"@ + + $result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName ` + -Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent + + $counts = @{} + + foreach ($line in $result -split "`n") { + if ($line -match "^([A-Z_ ]+):(\d+)$") { + $counts[$Matches[1].Trim()] = [int]$Matches[2] + } + } + + return $counts +} + +# Note: Functions are available when dot-sourced (. .\oracle-functions.ps1) +# Do NOT use Export-ModuleMember - it only works inside .psm1 modules diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/configure-profile.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/configure-profile.sql new file mode 100644 index 0000000..e038a6d --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/configure-profile.sql @@ -0,0 +1,99 @@ +-- ============================================================================ +-- PASSWORD PROFILE CONFIGURATION +-- ============================================================================ +-- Configures DEFAULT profile for no password expiration +-- CRITICAL for ROA application compatibility +-- +-- This script disables all password restrictions to prevent: +-- - Password expiration issues during long-running installations +-- - Account lockouts from failed login attempts +-- - Password reuse restrictions +-- +-- WARNING: This reduces security. For production environments, consider +-- creating a custom profile with appropriate settings. +-- +-- Usage: +-- @configure-profile.sql +-- +-- Connect as: SYSDBA +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Configuring Password Profile +PROMPT ======================================== +PROMPT + +-- Show current profile settings +PROMPT Current DEFAULT profile settings: +SELECT resource_name, limit +FROM dba_profiles +WHERE profile = 'DEFAULT' +AND resource_type = 'PASSWORD' +ORDER BY resource_name; + +PROMPT +PROMPT Modifying DEFAULT profile for ROA compatibility... +PROMPT + +-- Disable password expiration +ALTER PROFILE DEFAULT LIMIT + PASSWORD_LIFE_TIME UNLIMITED + PASSWORD_REUSE_TIME UNLIMITED + PASSWORD_REUSE_MAX UNLIMITED + PASSWORD_VERIFY_FUNCTION NULL + PASSWORD_LOCK_TIME UNLIMITED + PASSWORD_GRACE_TIME UNLIMITED + FAILED_LOGIN_ATTEMPTS UNLIMITED; + +PROMPT +PROMPT ======================================== +PROMPT Profile Configuration Complete +PROMPT ======================================== +PROMPT + +-- Verify new settings +PROMPT New DEFAULT profile settings: +SELECT resource_name, limit +FROM dba_profiles +WHERE profile = 'DEFAULT' +AND resource_type = 'PASSWORD' +ORDER BY resource_name; + +PROMPT +PROMPT WARNING: Password restrictions have been disabled. +PROMPT For production environments, consider creating a custom +PROMPT profile with appropriate security settings. +PROMPT + +-- Unlock any locked accounts (optional) +PROMPT +PROMPT Unlocking ROA-related accounts if locked... +DECLARE + v_sql VARCHAR2(200); +BEGIN + FOR rec IN (SELECT username FROM dba_users + WHERE account_status LIKE '%LOCKED%' + AND username IN ('CONTAFIN_ORACLE', 'SYSTEM')) LOOP + v_sql := 'ALTER USER ' || rec.username || ' ACCOUNT UNLOCK'; + EXECUTE IMMEDIATE v_sql; + DBMS_OUTPUT.PUT_LINE('Unlocked user: ' || rec.username); + END LOOP; +END; +/ + +-- Reset expired passwords (optional - requires manual password) +PROMPT +PROMPT If any accounts show EXPIRED status, reset their passwords: +SELECT username, account_status +FROM dba_users +WHERE username IN ('CONTAFIN_ORACLE', 'SYSTEM', 'SYS') + OR username LIKE 'FIRMA%' + OR username LIKE 'TEST%'; + +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/create-tablespace.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/create-tablespace.sql new file mode 100644 index 0000000..668d043 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/create-tablespace.sql @@ -0,0 +1,88 @@ +-- ============================================================================ +-- ROA TABLESPACE CREATION +-- ============================================================================ +-- Creates ROA tablespace with 1GB initial size, autoextend enabled +-- Works for both non-CDB (Oracle SE) and PDB (Oracle XE in XEPDB1) +-- +-- Usage: +-- @create-tablespace.sql "D:\Oracle\oradata\ORCL" +-- @create-tablespace.sql "D:\Oracle\oradata\XE\XEPDB1" +-- +-- Parameters: +-- &1 - Datafile directory path (e.g., D:\Oracle\oradata\ORCL) +-- +-- Connect as: SYSDBA +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Creating ROA Tablespace +PROMPT ======================================== +PROMPT + +-- Define datafile path +DEFINE datafile_dir = "&1" + +PROMPT Datafile directory: &datafile_dir + +-- Check if tablespace already exists +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_tablespaces + WHERE tablespace_name = 'ROA'; + + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE('WARNING: Tablespace ROA already exists. Skipping creation.'); + ELSE + DBMS_OUTPUT.PUT_LINE('Creating tablespace ROA...'); + END IF; +END; +/ + +-- Create tablespace if it doesn't exist +DECLARE + v_count NUMBER; + v_sql VARCHAR2(1000); +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_tablespaces + WHERE tablespace_name = 'ROA'; + + IF v_count = 0 THEN + v_sql := 'CREATE SMALLFILE TABLESPACE "ROA" ' || + 'DATAFILE ''&datafile_dir\ROA.DBF'' ' || + 'SIZE 1000M ' || + 'AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED ' || + 'LOGGING ' || + 'EXTENT MANAGEMENT LOCAL ' || + 'SEGMENT SPACE MANAGEMENT AUTO'; + EXECUTE IMMEDIATE v_sql; + DBMS_OUTPUT.PUT_LINE('Tablespace ROA created successfully.'); + END IF; +END; +/ + +PROMPT +PROMPT Verifying tablespace creation: +SELECT tablespace_name, status, contents, extent_management, segment_space_management +FROM dba_tablespaces +WHERE tablespace_name = 'ROA'; + +PROMPT +PROMPT Datafile information: +SELECT file_name, bytes/1024/1024 AS size_mb, autoextensible, maxbytes/1024/1024 AS max_mb +FROM dba_data_files +WHERE tablespace_name = 'ROA'; + +PROMPT +PROMPT ======================================== +PROMPT ROA Tablespace Creation Complete +PROMPT ======================================== +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/create-user-company.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/create-user-company.sql new file mode 100644 index 0000000..384b4b9 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/create-user-company.sql @@ -0,0 +1,131 @@ +-- ============================================================================ +-- COMPANY SCHEMA USER CREATION (Template) +-- ============================================================================ +-- Creates a company schema user for ROA application +-- Each company in ROA has its own schema with identical structure +-- +-- Usage: +-- @create-user-company.sql "SCHEMA_NAME" "Password123" +-- +-- Parameters: +-- &1 - Schema/User name (e.g., FIRMA1, TESTFIRMA, ROMCONSTRUCT) +-- &2 - Password for the schema user +-- +-- Privileges granted: +-- - CONNECT, RESOURCE roles +-- - CREATE SESSION, TABLE, VIEW, SEQUENCE, PROCEDURE, TRIGGER, TYPE, SYNONYM +-- - CREATE MATERIALIZED VIEW, DATABASE LINK, JOB +-- - DEBUG CONNECT SESSION +-- - SELECT ANY TABLE (for cross-schema queries) +-- - UNLIMITED TABLESPACE +-- +-- Connect as: SYSDBA or SYSTEM +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Creating Company Schema User +PROMPT ======================================== +PROMPT + +-- Define parameters +DEFINE schema_name = "&1" +DEFINE schema_password = "&2" + +PROMPT Schema name: &schema_name + +-- Check if user already exists +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_users + WHERE username = UPPER('&schema_name'); + + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE('WARNING: User &schema_name already exists.'); + DBMS_OUTPUT.PUT_LINE('Use DROP USER &schema_name CASCADE to remove if needed.'); + ELSE + DBMS_OUTPUT.PUT_LINE('User &schema_name does not exist. Proceeding with creation.'); + END IF; +END; +/ + +-- Create user +PROMPT Creating user &schema_name... +CREATE USER &schema_name + IDENTIFIED BY "&schema_password" + DEFAULT TABLESPACE ROA + TEMPORARY TABLESPACE TEMP + QUOTA UNLIMITED ON ROA; + +-- Grant roles +PROMPT Granting roles... +GRANT CONNECT TO &schema_name; +GRANT RESOURCE TO &schema_name; + +-- Grant session and object creation privileges +PROMPT Granting system privileges... +GRANT CREATE SESSION TO &schema_name; +GRANT CREATE TABLE TO &schema_name; +GRANT CREATE VIEW TO &schema_name; +GRANT CREATE SEQUENCE TO &schema_name; +GRANT CREATE PROCEDURE TO &schema_name; +GRANT CREATE TRIGGER TO &schema_name; +GRANT CREATE TYPE TO &schema_name; +GRANT CREATE SYNONYM TO &schema_name; +GRANT CREATE MATERIALIZED VIEW TO &schema_name; +GRANT CREATE DATABASE LINK TO &schema_name; +GRANT CREATE JOB TO &schema_name; + +-- Grant debug capability +GRANT DEBUG CONNECT SESSION TO &schema_name; + +-- Grant select any table for cross-schema reporting +GRANT SELECT ANY TABLE TO &schema_name; + +-- Grant unlimited tablespace +GRANT UNLIMITED TABLESPACE TO &schema_name; + +PROMPT +PROMPT ======================================== +PROMPT Verifying User Creation +PROMPT ======================================== +PROMPT + +-- Verify user creation +SELECT username, default_tablespace, temporary_tablespace, account_status +FROM dba_users +WHERE username = UPPER('&schema_name'); + +-- Verify roles +PROMPT +PROMPT Granted roles: +SELECT granted_role +FROM dba_role_privs +WHERE grantee = UPPER('&schema_name'); + +-- Verify tablespace quota +PROMPT +PROMPT Tablespace quotas: +SELECT tablespace_name, + CASE WHEN max_bytes = -1 THEN 'UNLIMITED' + ELSE TO_CHAR(max_bytes/1024/1024) || ' MB' + END AS quota +FROM dba_ts_quotas +WHERE username = UPPER('&schema_name'); + +PROMPT +PROMPT ======================================== +PROMPT Company Schema &schema_name Created +PROMPT ======================================== +PROMPT +PROMPT Next steps: +PROMPT 1. Import schema data from FIRMANOUA.dmp or existing backup +PROMPT 2. Run schema update scripts via PACK_UPDATE +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/create-user-contafin.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/create-user-contafin.sql new file mode 100644 index 0000000..d33db1b --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/create-user-contafin.sql @@ -0,0 +1,131 @@ +-- ============================================================================ +-- CONTAFIN_ORACLE USER CREATION +-- ============================================================================ +-- Creates CONTAFIN_ORACLE user with DBA-like privileges +-- This is the main administrative user for the ROA application +-- +-- Usage: +-- @create-user-contafin.sql "YourSecurePassword" +-- +-- Parameters: +-- &1 - Password for CONTAFIN_ORACLE user +-- +-- Privileges granted: +-- - CONNECT, RESOURCE roles +-- - CREATE ANY CONTEXT, DROP ANY CONTEXT +-- - EXECUTE ANY PROCEDURE +-- - SELECT ANY TABLE/DICTIONARY/SEQUENCE +-- - INSERT/UPDATE/DELETE ANY TABLE +-- - UNLIMITED TABLESPACE +-- - CREATE/DROP PUBLIC SYNONYM +-- - CREATE VIEW, CREATE SESSION +-- +-- Connect as: SYSDBA or SYSTEM +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Creating CONTAFIN_ORACLE User +PROMPT ======================================== +PROMPT + +-- Define password +DEFINE co_password = "&1" + +-- Drop user if exists (optional, comment out if you want to preserve data) +PROMPT Checking for existing CONTAFIN_ORACLE user... +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_users + WHERE username = 'CONTAFIN_ORACLE'; + + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE('WARNING: User CONTAFIN_ORACLE already exists.'); + DBMS_OUTPUT.PUT_LINE('Use DROP USER CONTAFIN_ORACLE CASCADE to remove if needed.'); + ELSE + DBMS_OUTPUT.PUT_LINE('User CONTAFIN_ORACLE does not exist. Proceeding with creation.'); + END IF; +END; +/ + +-- Create user +PROMPT Creating user CONTAFIN_ORACLE... +CREATE USER CONTAFIN_ORACLE + IDENTIFIED BY "&co_password" + DEFAULT TABLESPACE ROA + TEMPORARY TABLESPACE TEMP + PROFILE DEFAULT; + +-- Grant roles +PROMPT Granting roles... +GRANT CONNECT TO CONTAFIN_ORACLE; +GRANT RESOURCE TO CONTAFIN_ORACLE; + +-- Grant system privileges +PROMPT Granting system privileges... +GRANT CREATE ANY CONTEXT TO CONTAFIN_ORACLE; +GRANT DROP ANY CONTEXT TO CONTAFIN_ORACLE; +GRANT CREATE SESSION TO CONTAFIN_ORACLE; +GRANT CREATE VIEW TO CONTAFIN_ORACLE; +GRANT CREATE TABLE TO CONTAFIN_ORACLE; +GRANT CREATE SEQUENCE TO CONTAFIN_ORACLE; +GRANT CREATE PROCEDURE TO CONTAFIN_ORACLE; +GRANT CREATE TRIGGER TO CONTAFIN_ORACLE; +GRANT CREATE TYPE TO CONTAFIN_ORACLE; +GRANT CREATE SYNONYM TO CONTAFIN_ORACLE; +GRANT CREATE MATERIALIZED VIEW TO CONTAFIN_ORACLE; +GRANT CREATE DATABASE LINK TO CONTAFIN_ORACLE; +GRANT CREATE JOB TO CONTAFIN_ORACLE; + +-- Grant ANY privileges for application management +GRANT EXECUTE ANY PROCEDURE TO CONTAFIN_ORACLE; +GRANT SELECT ANY DICTIONARY TO CONTAFIN_ORACLE; +GRANT SELECT ANY SEQUENCE TO CONTAFIN_ORACLE; +GRANT SELECT ANY TABLE TO CONTAFIN_ORACLE; +GRANT INSERT ANY TABLE TO CONTAFIN_ORACLE; +GRANT UPDATE ANY TABLE TO CONTAFIN_ORACLE; +GRANT DELETE ANY TABLE TO CONTAFIN_ORACLE; + +-- Grant tablespace and synonym privileges +GRANT UNLIMITED TABLESPACE TO CONTAFIN_ORACLE; +GRANT CREATE PUBLIC SYNONYM TO CONTAFIN_ORACLE; +GRANT DROP PUBLIC SYNONYM TO CONTAFIN_ORACLE; + +PROMPT +PROMPT ======================================== +PROMPT Verifying User Creation +PROMPT ======================================== +PROMPT + +-- Verify user creation +SELECT username, default_tablespace, temporary_tablespace, account_status, profile +FROM dba_users +WHERE username = 'CONTAFIN_ORACLE'; + +-- Verify roles +PROMPT +PROMPT Granted roles: +SELECT granted_role, admin_option, default_role +FROM dba_role_privs +WHERE grantee = 'CONTAFIN_ORACLE'; + +-- Verify system privileges +PROMPT +PROMPT Granted system privileges: +SELECT privilege, admin_option +FROM dba_sys_privs +WHERE grantee = 'CONTAFIN_ORACLE' +ORDER BY privilege; + +PROMPT +PROMPT ======================================== +PROMPT CONTAFIN_ORACLE User Creation Complete +PROMPT ======================================== +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql new file mode 100644 index 0000000..a07633b --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql @@ -0,0 +1,393 @@ +-- ============================================================================ +-- PUBLIC GRANTS FOR ROA APPLICATION +-- ============================================================================ +-- Grants necessary permissions on CONTAFIN_ORACLE objects to PUBLIC +-- and configures network ACLs for CONTAFIN_ORACLE +-- +-- Usage: +-- @grants-public.sql +-- +-- Connect as: SYSTEM or SYS as SYSDBA +-- Must run AFTER: +-- 1. CONTAFIN_ORACLE schema objects are imported +-- 2. synonyms-public.sql has been executed +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Granting Permissions to PUBLIC +PROMPT ======================================== +PROMPT + +-- ============================================================================ +-- SECTION 1: GRANTS ON CORE USER/PROGRAM TABLES +-- ============================================================================ + +PROMPT [1/9] Granting SELECT/REFERENCES on core tables... + +-- DEF_GRUP +GRANT SELECT ON SYN_DEF_GRUP TO PUBLIC; +GRANT REFERENCES ON SYN_DEF_GRUP TO PUBLIC; + +-- DEF_PROGRAME +GRANT SELECT ON SYN_DEF_PROGRAME TO PUBLIC; +GRANT REFERENCES ON SYN_DEF_PROGRAME TO PUBLIC; + +-- VDEF_PROGRAME +GRANT SELECT ON SYN_VDEF_PROGRAME TO PUBLIC; +GRANT REFERENCES ON SYN_VDEF_PROGRAME TO PUBLIC; + +-- LUNILEAN +GRANT SELECT ON SYN_LUNILEAN TO PUBLIC; +GRANT REFERENCES ON SYN_LUNILEAN TO PUBLIC; + +-- NOM_FIRME +GRANT SELECT ON SYN_NOM_FIRME TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_FIRME TO PUBLIC; + +-- NOM_PROGRAME +GRANT SELECT ON SYN_NOM_PROGRAME TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_PROGRAME TO PUBLIC; + +-- UTILIZATORI +GRANT SELECT ON SYN_UTILIZATORI TO PUBLIC; +GRANT REFERENCES ON SYN_UTILIZATORI TO PUBLIC; + +-- VDEF_UTIL_PROGRAME +GRANT SELECT ON SYN_VDEF_UTIL_PROGRAME TO PUBLIC; + +-- VDEF_UTIL_FIRME +GRANT SELECT ON SYN_VDEF_UTIL_FIRME TO PUBLIC; +GRANT REFERENCES ON SYN_VDEF_UTIL_FIRME TO PUBLIC; + +-- VDEF_UTIL_OBIECTE +GRANT SELECT ON SYN_VDEF_UTIL_OBIECTE TO PUBLIC; +GRANT REFERENCES ON SYN_VDEF_UTIL_OBIECTE TO PUBLIC; + +-- VUTILIZATORI +GRANT SELECT ON SYN_VUTILIZATORI TO PUBLIC; +GRANT REFERENCES ON SYN_VUTILIZATORI TO PUBLIC; + +-- VDEF_UTIL_GRUP +GRANT SELECT ON SYN_VDEF_UTIL_GRUP TO PUBLIC; +GRANT REFERENCES ON SYN_VDEF_UTIL_GRUP TO PUBLIC; + +-- DEF_GRUP_DREPT +GRANT SELECT ON SYN_DEF_GRUP_DREPT TO PUBLIC; +GRANT REFERENCES ON SYN_DEF_GRUP_DREPT TO PUBLIC; + +-- OPTIUNI_PROGRAME +GRANT SELECT ON SYN_OPTIUNI_PROGRAME TO PUBLIC; + +-- HELPCONT +GRANT SELECT ON SYN_HELPCONT TO PUBLIC; + +-- V_NOM_FIRME +GRANT SELECT ON SYN_V_NOM_FIRME TO PUBLIC; + +-- ============================================================================ +-- SECTION 2: GRANTS ON UTILITY TYPES AND FUNCTIONS +-- ============================================================================ + +PROMPT [2/9] Granting EXECUTE on utility types/functions... + +GRANT EXECUTE ON STRINGAGG TO PUBLIC; +GRANT EXECUTE ON CONTAFIN_ORACLE.STRINGAGGTYPE TO PUBLIC; + +GRANT EXECUTE ON CHAR_ROW TO PUBLIC; +GRANT EXECUTE ON CHAR_TAB TO PUBLIC; +GRANT EXECUTE ON NUM_ROW TO PUBLIC; +GRANT EXECUTE ON NUM_TAB TO PUBLIC; + +GRANT EXECUTE ON UW_SEL_ROW TO PUBLIC; +GRANT EXECUTE ON UW_SEL_TAB TO PUBLIC; + +GRANT EXECUTE ON VALOARETAG TO PUBLIC; +GRANT EXECUTE ON GETWORDCOUNT TO PUBLIC; +GRANT EXECUTE ON GETWORDNUM TO PUBLIC; +GRANT EXECUTE ON CHARC2COLLECTION TO PUBLIC; +GRANT EXECUTE ON CHARN2COLLECTION TO PUBLIC; + +-- ============================================================================ +-- SECTION 3: GRANTS ON NOMENCLATURE TABLES +-- ============================================================================ + +PROMPT [3/9] Granting SELECT/REFERENCES on nomenclature tables... + +-- Legal forms +GRANT SELECT ON SYN_NOM_FORME_JURIDICE TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_FORME_JURIDICE TO PUBLIC; + +GRANT SELECT ON SYN_NOM_FORME_ORGANIZARE TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_FORME_ORGANIZARE TO PUBLIC; + +GRANT SELECT ON SYN_NOM_TIP_SOCIETATE TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_TIP_SOCIETATE TO PUBLIC; + +GRANT SELECT ON SYN_NOM_FORME_PROPRIETATE TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_FORME_PROPRIETATE TO PUBLIC; + +-- Geography +GRANT SELECT ON SYN_NOM_CETATENII TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_CETATENII TO PUBLIC; + +GRANT SELECT ON SYN_NOM_TARI TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_TARI TO PUBLIC; + +GRANT SELECT ON SYN_NOM_JUDETE TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_JUDETE TO PUBLIC; + +GRANT SELECT ON SYN_NOM_LOCALITATI TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_LOCALITATI TO PUBLIC; + +GRANT SELECT ON SYN_VNOM_JUDETE TO PUBLIC; +GRANT SELECT ON SYN_VNOM_LOCALITATI TO PUBLIC; +GRANT SELECT ON SYN_VNOM_TARI TO PUBLIC; + +GRANT SELECT ON SYN_NOM_CODURI_CAEN TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_CODURI_CAEN TO PUBLIC; + +GRANT SELECT ON SYN_NOM_TIPAPATRID TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_TIPAPATRID TO PUBLIC; + +-- ============================================================================ +-- SECTION 4: GRANTS ON CURRENCY/EXCHANGE TABLES +-- ============================================================================ + +PROMPT [4/9] Granting SELECT/REFERENCES on currency tables... + +GRANT SELECT ON SYN_VNOM_VALUTE_ISO TO PUBLIC; + +GRANT SELECT ON SYN_NOM_VALUTE_ISO TO PUBLIC; +GRANT REFERENCES ON SYN_NOM_VALUTE_ISO TO PUBLIC; + +GRANT SELECT ON SYN_CURS_COTATII TO PUBLIC; +GRANT REFERENCES ON SYN_CURS_COTATII TO PUBLIC; + +GRANT SELECT ON SYN_CURS_ACTUALIZARI TO PUBLIC; +GRANT REFERENCES ON SYN_CURS_ACTUALIZARI TO PUBLIC; + +GRANT SELECT, REFERENCES ON SYN_VNOM_UM_ISO TO PUBLIC; +GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_UM_ISO TO PUBLIC; + +-- ============================================================================ +-- SECTION 5: GRANTS ON SALARY MODULE TABLES AND TYPES +-- ============================================================================ + +PROMPT [5/9] Granting permissions on salary module objects... + +-- Nomenclature tables +GRANT SELECT ON SYN_SAL_NOM_TEMEI TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_TEMEI TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_TIPAUTORIZATIE TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_TIPAUTORIZATIE TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_TIP_SPOR TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_TIP_SPOR TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_TIP_NORME TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_TIP_NORME TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_STARI_CTR TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_STARI_CTR TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_DURATA_MUNCA TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_DURATA_MUNCA TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_REPARTIZARE_MUNCA TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_REPARTIZARE_MUNCA TO PUBLIC; + +GRANT SELECT ON SYN_SAL_NOM_INTERVALE_MUNCA TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_NOM_INTERVALE_MUNCA TO PUBLIC; + +GRANT SELECT ON SYN_SAL_COR TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_COR TO PUBLIC; + +GRANT SELECT ON SYN_SAL_ACTUALIZARE_COR TO PUBLIC; +GRANT REFERENCES ON SYN_SAL_ACTUALIZARE_COR TO PUBLIC; + +-- Salary types +GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_CONTRACT_M TO PUBLIC; +GRANT EXECUTE ON CONTAFIN_ORACLE.CONTRACT_M TO PUBLIC; +GRANT EXECUTE ON SAL_CONTRACT_M TO PUBLIC; +GRANT EXECUTE ON CONTRACT_M TO PUBLIC; +GRANT EXECUTE ON SAL_RED TO PUBLIC; +GRANT EXECUTE ON SAL_CAMPURI_RED TO PUBLIC; +GRANT EXECUTE ON TABSTERS TO PUBLIC; +GRANT EXECUTE ON SAL_TABELESTERS TO PUBLIC; + +-- ============================================================================ +-- SECTION 6: GRANTS ON ATTACHMENT TABLES +-- ============================================================================ + +PROMPT [6/9] Granting permissions on attachment tables... + +GRANT SELECT ON SYN_ATAS_ATASAMENTE TO PUBLIC; +GRANT REFERENCES ON SYN_ATAS_ATASAMENTE TO PUBLIC; + +GRANT SELECT ON SYN_ATAS_REFERINTE TO PUBLIC; +GRANT REFERENCES ON SYN_ATAS_REFERINTE TO PUBLIC; + +-- ============================================================================ +-- SECTION 7: GRANTS ON PACKAGES AND ADDITIONAL TYPES +-- ============================================================================ + +PROMPT [7/9] Granting EXECUTE on packages and types... + +-- Packages +GRANT EXECUTE ON SYN_PACK_DREPTURI TO PUBLIC; +GRANT EXECUTE ON PACK_UPDATE TO PUBLIC; +GRANT EXECUTE ON PACK_UTILS TO PUBLIC; +GRANT EXECUTE ON PACK_UTILS_FILE TO PUBLIC; +GRANT EXECUTE ON SYN_PACK_DEF_CO TO PUBLIC; +GRANT EXECUTE ON PACK_ROARTVAI TO PUBLIC; + +-- Additional types +GRANT EXECUTE ON FF_SUME TO PUBLIC; +GRANT EXECUTE ON FF_PERSINTRET TO PUBLIC; +GRANT EXECUTE ON VANZARI_DETALII_TAB TO PUBLIC; +GRANT EXECUTE ON PIVOT_TABLE TO PUBLIC; +GRANT EXECUTE ON PIVOT_ROW TO PUBLIC; +GRANT EXECUTE ON TABINCHIDERETVA TO PUBLIC; +GRANT EXECUTE ON TABELAVALORITAGURI TO PUBLIC; +GRANT EXECUTE ON RANDINCHIDERETVA TO PUBLIC; + +-- SERVER_INFO table +GRANT SELECT, UPDATE ON SERVER_INFO TO PUBLIC; + +-- RTVAI module +GRANT SELECT ON RTVAI_AGENTI TO PUBLIC; +GRANT SELECT ON RTVAI_ISTORIC TO PUBLIC; + +-- License view synonym +GRANT SELECT ON CONTAFIN_ORACLE.VDEF_PROGRAME_SERII TO CONTAFIN_ORACLE; + +-- ============================================================================ +-- SECTION 8: DIRECTORY AND SYSTEM GRANTS +-- ============================================================================ + +PROMPT [8/9] Granting directory and system permissions... + +-- Create DMPDIR directory if it doesn't exist (adjust path as needed) +BEGIN + EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY DMPDIR AS ''D:\Oracle\admin\ORCL\dpdump'''; +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE('Note: DMPDIR directory may already exist or path needs adjustment'); +END; +/ + +-- Grant directory access +GRANT ALL ON DIRECTORY DMPDIR TO PUBLIC; + +-- Grant UTL packages to PUBLIC +GRANT EXECUTE ON UTL_FILE TO PUBLIC; +GRANT EXECUTE ON DBMS_LOCK TO PUBLIC; + +-- Grant UTL packages to CONTAFIN_ORACLE specifically +GRANT EXECUTE ON UTL_INADDR TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_TCP TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_SMTP TO CONTAFIN_ORACLE; +GRANT EXECUTE ON UTL_HTTP TO CONTAFIN_ORACLE; + +-- UTL_MAIL may not exist in all Oracle editions +BEGIN + EXECUTE IMMEDIATE 'GRANT EXECUTE ON UTL_MAIL TO CONTAFIN_ORACLE'; +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE('Note: UTL_MAIL not available (requires configuration)'); +END; +/ + +-- ============================================================================ +-- SECTION 9: NETWORK ACL CONFIGURATION +-- ============================================================================ + +PROMPT [9/9] Configuring Network ACL for CONTAFIN_ORACLE... + +-- Drop existing ACL (if exists) +BEGIN + DBMS_NETWORK_ACL_ADMIN.DROP_ACL(acl => 'roaupdate.xml'); + DBMS_OUTPUT.PUT_LINE('Dropped existing roaupdate.xml ACL'); +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE('Note: roaupdate.xml ACL did not exist (this is OK)'); +END; +/ + +-- Create new ACL with permissions for CONTAFIN_ORACLE +BEGIN + DBMS_NETWORK_ACL_ADMIN.CREATE_ACL( + acl => 'roaupdate.xml', + description => 'Permissions for ROA application network access', + principal => 'CONTAFIN_ORACLE', + is_grant => TRUE, + privilege => 'connect' + ); + + DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE( + acl => 'roaupdate.xml', + principal => 'CONTAFIN_ORACLE', + is_grant => TRUE, + privilege => 'resolve' + ); + + -- Allow all hosts (use specific hosts in production) + DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL( + acl => 'roaupdate.xml', + host => '*' + ); + + DBMS_OUTPUT.PUT_LINE('Network ACL created successfully for CONTAFIN_ORACLE'); +END; +/ + +COMMIT; + +-- ============================================================================ +-- VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT Grants Complete - Verification +PROMPT ======================================== +PROMPT + +PROMPT Grants to PUBLIC on CONTAFIN_ORACLE objects: +SELECT grantee, table_name, privilege +FROM dba_tab_privs +WHERE grantee = 'PUBLIC' + AND grantor = 'SYS' + AND table_name LIKE 'SYN_%' +ORDER BY table_name, privilege; + +PROMPT +PROMPT Network ACL assignments for CONTAFIN_ORACLE: +SELECT host, lower_port, upper_port, acl +FROM dba_network_acls +WHERE acl LIKE '%roaupdate%'; + +PROMPT +PROMPT ACL privileges: +SELECT acl, principal, privilege, is_grant +FROM dba_network_acl_privileges +WHERE acl LIKE '%roaupdate%'; + +PROMPT +PROMPT Directory permissions: +SELECT grantee, table_name, privilege +FROM dba_tab_privs +WHERE table_name = 'DMPDIR'; + +PROMPT +PROMPT ======================================== +PROMPT Grant Configuration Complete +PROMPT ======================================== +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/synonyms-public.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/synonyms-public.sql new file mode 100644 index 0000000..402ca50 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/synonyms-public.sql @@ -0,0 +1,313 @@ +-- ============================================================================ +-- PUBLIC SYNONYMS FOR ROA APPLICATION +-- ============================================================================ +-- Creates all public synonyms required by the ROA application +-- These synonyms provide cross-schema access to CONTAFIN_ORACLE objects +-- +-- Usage: +-- @synonyms-public.sql +-- +-- Connect as: SYSTEM or user with CREATE PUBLIC SYNONYM privilege +-- Must run AFTER CONTAFIN_ORACLE schema objects are imported +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Creating Public Synonyms +PROMPT ======================================== +PROMPT + +-- ============================================================================ +-- SECTION 1: CLEANUP - Drop existing synonyms (optional, for idempotency) +-- ============================================================================ + +PROMPT Cleaning up existing synonyms... + +-- Core user/program synonyms +DROP PUBLIC SYNONYM SYN_LUNILEAN; +DROP PUBLIC SYNONYM SYN_PACK_DREPTURI; +DROP PUBLIC SYNONYM SYN_VDEF_UTIL_GRUP; +DROP PUBLIC SYNONYM SYN_DEF_GRUP_DREPT; +DROP PUBLIC SYNONYM SYN_UTILIZATORI; +DROP PUBLIC SYNONYM SYN_VDEF_UTIL_PROGRAME; +DROP PUBLIC SYNONYM SYN_VDEF_UTIL_OBIECTE; +DROP PUBLIC SYNONYM SYN_VUTILIZATORI; +DROP PUBLIC SYNONYM SYN_NOM_PROGRAME; +DROP PUBLIC SYNONYM SYN_DEF_PROGRAME; +DROP PUBLIC SYNONYM SYN_VDEF_PROGRAME; +DROP PUBLIC SYNONYM SYN_DEF_GRUP; +DROP PUBLIC SYNONYM SYN_NOM_FIRME; +DROP PUBLIC SYNONYM SYN_V_NOM_FIRME; +DROP PUBLIC SYNONYM SYN_VDEF_UTIL_FIRME; +DROP PUBLIC SYNONYM SYN_HELPCONT; +DROP PUBLIC SYNONYM SYN_OPTIUNI_PROGRAME; + +-- Utility types/functions +DROP PUBLIC SYNONYM STRINGAGG; +DROP PUBLIC SYNONYM CHAR_ROW; +DROP PUBLIC SYNONYM CHAR_TAB; +DROP PUBLIC SYNONYM NUM_ROW; +DROP PUBLIC SYNONYM NUM_TAB; +DROP PUBLIC SYNONYM UW_SEL_ROW; +DROP PUBLIC SYNONYM UW_SEL_TAB; +DROP PUBLIC SYNONYM GETWORDCOUNT; +DROP PUBLIC SYNONYM GETWORDNUM; +DROP PUBLIC SYNONYM CHARC2COLLECTION; +DROP PUBLIC SYNONYM CHARN2COLLECTION; +DROP PUBLIC SYNONYM VALOARETAG; + +-- Nomenclature synonyms +DROP PUBLIC SYNONYM SYN_NOM_FORME_JURIDICE; +DROP PUBLIC SYNONYM SYN_NOM_FORME_ORGANIZARE; +DROP PUBLIC SYNONYM SYN_NOM_TIP_SOCIETATE; +DROP PUBLIC SYNONYM SYN_NOM_FORME_PROPRIETATE; +DROP PUBLIC SYNONYM SYN_NOM_CETATENII; +DROP PUBLIC SYNONYM SYN_NOM_TARI; +DROP PUBLIC SYNONYM SYN_NOM_JUDETE; +DROP PUBLIC SYNONYM SYN_NOM_LOCALITATI; +DROP PUBLIC SYNONYM SYN_VNOM_JUDETE; +DROP PUBLIC SYNONYM SYN_VNOM_LOCALITATI; +DROP PUBLIC SYNONYM SYN_VNOM_TARI; +DROP PUBLIC SYNONYM SYN_NOM_CODURI_CAEN; +DROP PUBLIC SYNONYM SYN_NOM_TIPAPATRID; + +-- Currency/exchange synonyms +DROP PUBLIC SYNONYM SYN_VNOM_VALUTE_ISO; +DROP PUBLIC SYNONYM SYN_NOM_VALUTE_ISO; +DROP PUBLIC SYNONYM SYN_CURS_COTATII; +DROP PUBLIC SYNONYM SYN_CURS_ACTUALIZARI; + +-- Salary module synonyms +DROP PUBLIC SYNONYM SYN_SAL_NOM_TEMEI; +DROP PUBLIC SYNONYM SYN_SAL_NOM_TIPAUTORIZATIE; +DROP PUBLIC SYNONYM SYN_SAL_NOM_TIP_SPOR; +DROP PUBLIC SYNONYM SYN_SAL_NOM_TIP_NORME; +DROP PUBLIC SYNONYM SYN_SAL_NOM_STARI_CTR; +DROP PUBLIC SYNONYM SYN_SAL_NOM_DURATA_MUNCA; +DROP PUBLIC SYNONYM SYN_SAL_NOM_REPARTIZARE_MUNCA; +DROP PUBLIC SYNONYM SYN_SAL_NOM_INTERVALE_MUNCA; +DROP PUBLIC SYNONYM SYN_SAL_COR; +DROP PUBLIC SYNONYM SYN_SAL_ACTUALIZARE_COR; +DROP PUBLIC SYNONYM SAL_CONTRACT_M; +DROP PUBLIC SYNONYM CONTRACT_M; +DROP PUBLIC SYNONYM SAL_RED; +DROP PUBLIC SYNONYM SAL_CAMPURI_RED; +DROP PUBLIC SYNONYM TABSTERS; +DROP PUBLIC SYNONYM SAL_TABELESTERS; + +-- Attachment synonyms +DROP PUBLIC SYNONYM SYN_ATAS_ATASAMENTE; +DROP PUBLIC SYNONYM SYN_ATAS_REFERINTE; + +-- Utility packages +DROP PUBLIC SYNONYM PACK_UPDATE; +DROP PUBLIC SYNONYM PACK_UTILS; +DROP PUBLIC SYNONYM PACK_UTILS_FILE; +DROP PUBLIC SYNONYM SYN_PACK_DEF_CO; +DROP PUBLIC SYNONYM PACK_ROARTVAI; + +-- RTVAI module +DROP PUBLIC SYNONYM RTVAI_AGENTI; +DROP PUBLIC SYNONYM RTVAI_ISTORIC; + +-- Additional types +DROP PUBLIC SYNONYM FF_SUME; +DROP PUBLIC SYNONYM FF_PERSINTRET; +DROP PUBLIC SYNONYM VANZARI_DETALII_TAB; +DROP PUBLIC SYNONYM PIVOT_TABLE; +DROP PUBLIC SYNONYM PIVOT_ROW; +DROP PUBLIC SYNONYM TABINCHIDERETVA; +DROP PUBLIC SYNONYM TABELAVALORITAGURI; +DROP PUBLIC SYNONYM RANDINCHIDERETVA; +DROP PUBLIC SYNONYM SERVER_INFO; +DROP PUBLIC SYNONYM SYN_VNOM_UM_ISO; + +-- ============================================================================ +-- SECTION 2: CORE USER/PROGRAM MANAGEMENT SYNONYMS +-- ============================================================================ + +PROMPT +PROMPT [1/10] Creating core user/program synonyms... + +CREATE PUBLIC SYNONYM SYN_DEF_GRUP FOR CONTAFIN_ORACLE.DEF_GRUP; +CREATE PUBLIC SYNONYM SYN_DEF_PROGRAME FOR CONTAFIN_ORACLE.DEF_PROGRAME; +CREATE PUBLIC SYNONYM SYN_VDEF_PROGRAME FOR CONTAFIN_ORACLE.VDEF_PROGRAME; +CREATE PUBLIC SYNONYM SYN_LUNILEAN FOR CONTAFIN_ORACLE.LUNILEAN; +CREATE PUBLIC SYNONYM SYN_NOM_FIRME FOR CONTAFIN_ORACLE.NOM_FIRME; +CREATE PUBLIC SYNONYM SYN_NOM_PROGRAME FOR CONTAFIN_ORACLE.NOM_PROGRAME; +CREATE PUBLIC SYNONYM SYN_PACK_DREPTURI FOR CONTAFIN_ORACLE.PACK_DREPTURI; +CREATE PUBLIC SYNONYM SYN_UTILIZATORI FOR CONTAFIN_ORACLE.UTILIZATORI; +CREATE PUBLIC SYNONYM SYN_VDEF_UTIL_PROGRAME FOR CONTAFIN_ORACLE.VDEF_UTIL_PROGRAME; +CREATE PUBLIC SYNONYM SYN_VDEF_UTIL_FIRME FOR CONTAFIN_ORACLE.VDEF_UTIL_FIRME; +CREATE PUBLIC SYNONYM SYN_VDEF_UTIL_OBIECTE FOR CONTAFIN_ORACLE.VDEF_UTIL_OBIECTE; +CREATE PUBLIC SYNONYM SYN_VUTILIZATORI FOR CONTAFIN_ORACLE.VUTILIZATORI; +CREATE PUBLIC SYNONYM SYN_VDEF_UTIL_GRUP FOR CONTAFIN_ORACLE.VDEF_UTIL_GRUP; +CREATE PUBLIC SYNONYM SYN_DEF_GRUP_DREPT FOR CONTAFIN_ORACLE.DEF_GRUP_DREPT; +CREATE PUBLIC SYNONYM SYN_OPTIUNI_PROGRAME FOR CONTAFIN_ORACLE.OPTIUNI_PROGRAME; +CREATE PUBLIC SYNONYM SYN_HELPCONT FOR CONTAFIN_ORACLE.HELPCONT; +CREATE PUBLIC SYNONYM SYN_V_NOM_FIRME FOR CONTAFIN_ORACLE.V_NOM_FIRME; + +-- ============================================================================ +-- SECTION 3: UTILITY TYPES AND FUNCTIONS +-- ============================================================================ + +PROMPT [2/10] Creating utility type synonyms... + +CREATE PUBLIC SYNONYM STRINGAGG FOR CONTAFIN_ORACLE.STRINGAGG; +CREATE PUBLIC SYNONYM CHAR_ROW FOR CONTAFIN_ORACLE.CHAR_ROW; +CREATE PUBLIC SYNONYM CHAR_TAB FOR CONTAFIN_ORACLE.CHAR_TAB; +CREATE PUBLIC SYNONYM NUM_ROW FOR CONTAFIN_ORACLE.NUM_ROW; +CREATE PUBLIC SYNONYM NUM_TAB FOR CONTAFIN_ORACLE.NUM_TAB; +CREATE PUBLIC SYNONYM UW_SEL_ROW FOR CONTAFIN_ORACLE.UW_SEL_ROW; +CREATE PUBLIC SYNONYM UW_SEL_TAB FOR CONTAFIN_ORACLE.UW_SEL_TAB; +CREATE PUBLIC SYNONYM VALOARETAG FOR CONTAFIN_ORACLE.VALOARETAG; +CREATE PUBLIC SYNONYM GETWORDCOUNT FOR CONTAFIN_ORACLE.GETWORDCOUNT; +CREATE PUBLIC SYNONYM GETWORDNUM FOR CONTAFIN_ORACLE.GETWORDNUM; +CREATE PUBLIC SYNONYM CHARC2COLLECTION FOR CONTAFIN_ORACLE.CHARC2COLLECTION; +CREATE PUBLIC SYNONYM CHARN2COLLECTION FOR CONTAFIN_ORACLE.CHARN2COLLECTION; + +-- ============================================================================ +-- SECTION 4: NOMENCLATURE SYNONYMS (Legal Forms, Geography) +-- ============================================================================ + +PROMPT [3/10] Creating nomenclature synonyms... + +CREATE PUBLIC SYNONYM SYN_NOM_FORME_JURIDICE FOR CONTAFIN_ORACLE.NOM_FORME_JURIDICE; +CREATE PUBLIC SYNONYM SYN_NOM_FORME_ORGANIZARE FOR CONTAFIN_ORACLE.NOM_FORME_ORGANIZARE; +CREATE PUBLIC SYNONYM SYN_NOM_TIP_SOCIETATE FOR CONTAFIN_ORACLE.NOM_TIP_SOCIETATE; +CREATE PUBLIC SYNONYM SYN_NOM_FORME_PROPRIETATE FOR CONTAFIN_ORACLE.NOM_FORME_PROPRIETATE; +CREATE PUBLIC SYNONYM SYN_NOM_CETATENII FOR CONTAFIN_ORACLE.NOM_CETATENII; +CREATE PUBLIC SYNONYM SYN_NOM_TARI FOR CONTAFIN_ORACLE.NOM_TARI; +CREATE PUBLIC SYNONYM SYN_NOM_JUDETE FOR CONTAFIN_ORACLE.NOM_JUDETE; +CREATE PUBLIC SYNONYM SYN_NOM_LOCALITATI FOR CONTAFIN_ORACLE.NOM_LOCALITATI; +CREATE PUBLIC SYNONYM SYN_VNOM_JUDETE FOR CONTAFIN_ORACLE.VNOM_JUDETE; +CREATE PUBLIC SYNONYM SYN_VNOM_LOCALITATI FOR CONTAFIN_ORACLE.VNOM_LOCALITATI; +CREATE PUBLIC SYNONYM SYN_VNOM_TARI FOR CONTAFIN_ORACLE.VNOM_TARI; +CREATE PUBLIC SYNONYM SYN_NOM_CODURI_CAEN FOR CONTAFIN_ORACLE.NOM_CODURI_CAEN; +CREATE PUBLIC SYNONYM SYN_NOM_TIPAPATRID FOR CONTAFIN_ORACLE.NOM_TIPAPATRID; + +-- ============================================================================ +-- SECTION 5: CURRENCY AND EXCHANGE RATE SYNONYMS +-- ============================================================================ + +PROMPT [4/10] Creating currency/exchange synonyms... + +CREATE PUBLIC SYNONYM SYN_VNOM_VALUTE_ISO FOR CONTAFIN_ORACLE.VNOM_VALUTE_ISO; +CREATE PUBLIC SYNONYM SYN_NOM_VALUTE_ISO FOR CONTAFIN_ORACLE.NOM_VALUTE_ISO; +CREATE PUBLIC SYNONYM SYN_CURS_COTATII FOR CONTAFIN_ORACLE.CURS_COTATII; +CREATE PUBLIC SYNONYM SYN_CURS_ACTUALIZARI FOR CONTAFIN_ORACLE.CURS_ACTUALIZARI; +CREATE PUBLIC SYNONYM SYN_VNOM_UM_ISO FOR CONTAFIN_ORACLE.VNOM_UM_ISO; + +-- ============================================================================ +-- SECTION 6: SALARY MODULE SYNONYMS +-- ============================================================================ + +PROMPT [5/10] Creating salary module synonyms... + +CREATE PUBLIC SYNONYM SYN_SAL_NOM_TEMEI FOR CONTAFIN_ORACLE.SAL_NOM_TEMEI; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_TIPAUTORIZATIE FOR CONTAFIN_ORACLE.SAL_NOM_TIPAUTORIZATIE; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_TIP_SPOR FOR CONTAFIN_ORACLE.SAL_NOM_TIP_SPOR; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_TIP_NORME FOR CONTAFIN_ORACLE.SAL_NOM_TIP_NORME; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_STARI_CTR FOR CONTAFIN_ORACLE.SAL_NOM_STARI_CTR; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_DURATA_MUNCA FOR CONTAFIN_ORACLE.SAL_NOM_DURATA_MUNCA; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_REPARTIZARE_MUNCA FOR CONTAFIN_ORACLE.SAL_NOM_REPARTIZARE_MUNCA; +CREATE PUBLIC SYNONYM SYN_SAL_NOM_INTERVALE_MUNCA FOR CONTAFIN_ORACLE.SAL_NOM_INTERVALE_MUNCA; +CREATE PUBLIC SYNONYM SYN_SAL_COR FOR CONTAFIN_ORACLE.SAL_COR; +CREATE PUBLIC SYNONYM SYN_SAL_ACTUALIZARE_COR FOR CONTAFIN_ORACLE.SAL_ACTUALIZARE_COR; + +-- Salary types (must be created after CONTAFIN_ORACLE types exist) +PROMPT [6/10] Creating salary contract types... +CREATE PUBLIC SYNONYM SAL_CONTRACT_M FOR CONTAFIN_ORACLE.SAL_CONTRACT_M; +CREATE PUBLIC SYNONYM CONTRACT_M FOR CONTAFIN_ORACLE.CONTRACT_M; +CREATE PUBLIC SYNONYM SAL_RED FOR CONTAFIN_ORACLE.SAL_RED; +CREATE PUBLIC SYNONYM SAL_CAMPURI_RED FOR CONTAFIN_ORACLE.SAL_CAMPURI_RED; +CREATE PUBLIC SYNONYM TABSTERS FOR CONTAFIN_ORACLE.TABSTERS; +CREATE PUBLIC SYNONYM SAL_TABELESTERS FOR CONTAFIN_ORACLE.SAL_TABELESTERS; + +-- ============================================================================ +-- SECTION 7: ATTACHMENT SYNONYMS +-- ============================================================================ + +PROMPT [7/10] Creating attachment synonyms... + +CREATE PUBLIC SYNONYM SYN_ATAS_ATASAMENTE FOR CONTAFIN_ORACLE.ATAS_ATASAMENTE; +CREATE PUBLIC SYNONYM SYN_ATAS_REFERINTE FOR CONTAFIN_ORACLE.ATAS_REFERINTE; + +-- ============================================================================ +-- SECTION 8: UTILITY PACKAGES +-- ============================================================================ + +PROMPT [8/10] Creating utility package synonyms... + +CREATE PUBLIC SYNONYM PACK_UPDATE FOR CONTAFIN_ORACLE.PACK_UPDATE; +CREATE PUBLIC SYNONYM PACK_UTILS FOR CONTAFIN_ORACLE.PACK_UTILS; +CREATE PUBLIC SYNONYM PACK_UTILS_FILE FOR CONTAFIN_ORACLE.PACK_UTILS_FILE; +CREATE PUBLIC SYNONYM SYN_PACK_DEF_CO FOR CONTAFIN_ORACLE.PACK_DEF_CO; +CREATE PUBLIC SYNONYM PACK_ROARTVAI FOR CONTAFIN_ORACLE.PACK_ROARTVAI; + +-- ============================================================================ +-- SECTION 9: RTVAI MODULE AND ADDITIONAL TYPES +-- ============================================================================ + +PROMPT [9/10] Creating RTVAI and additional type synonyms... + +CREATE PUBLIC SYNONYM RTVAI_AGENTI FOR CONTAFIN_ORACLE.RTVAI_AGENTI; +CREATE PUBLIC SYNONYM RTVAI_ISTORIC FOR CONTAFIN_ORACLE.RTVAI_ISTORIC; + +CREATE PUBLIC SYNONYM FF_SUME FOR CONTAFIN_ORACLE.FF_SUME; +CREATE PUBLIC SYNONYM FF_PERSINTRET FOR CONTAFIN_ORACLE.FF_PERSINTRET; +CREATE PUBLIC SYNONYM VANZARI_DETALII_TAB FOR CONTAFIN_ORACLE.VANZARI_DETALII_TAB; +CREATE PUBLIC SYNONYM PIVOT_TABLE FOR CONTAFIN_ORACLE.PIVOT_TABLE; +CREATE PUBLIC SYNONYM PIVOT_ROW FOR CONTAFIN_ORACLE.PIVOT_ROW; +CREATE PUBLIC SYNONYM TABINCHIDERETVA FOR CONTAFIN_ORACLE.TABINCHIDERETVA; +CREATE PUBLIC SYNONYM TABELAVALORITAGURI FOR CONTAFIN_ORACLE.TABELAVALORITAGURI; +CREATE PUBLIC SYNONYM RANDINCHIDERETVA FOR CONTAFIN_ORACLE.RANDINCHIDERETVA; +CREATE PUBLIC SYNONYM SERVER_INFO FOR CONTAFIN_ORACLE.SERVER_INFO; + +-- ============================================================================ +-- SECTION 10: APPLICATION CONTEXT AND SPECIAL SYNONYMS +-- ============================================================================ + +PROMPT [10/10] Creating application context and special synonyms... + +-- Create application context for session variables +CREATE CONTEXT SESIUNE USING CONTAFIN_ORACLE.SET_VARIABILE; + +-- Private synonym for license view (in CONTAFIN_ORACLE schema) +-- This links to the SYS.VAUTH_SERII view +BEGIN + EXECUTE IMMEDIATE 'DROP SYNONYM CONTAFIN_ORACLE.VDEF_PROGRAME_SERII'; +EXCEPTION + WHEN OTHERS THEN NULL; +END; +/ + +CREATE SYNONYM CONTAFIN_ORACLE.VDEF_PROGRAME_SERII FOR SYS.VAUTH_SERII; + +PROMPT +PROMPT ======================================== +PROMPT Public Synonym Creation Complete +PROMPT ======================================== +PROMPT + +-- Verification +PROMPT Total public synonyms created: +SELECT COUNT(*) AS synonym_count +FROM dba_synonyms +WHERE owner = 'PUBLIC' + AND table_owner = 'CONTAFIN_ORACLE'; + +PROMPT +PROMPT Public synonyms list: +SELECT synonym_name, table_name +FROM dba_synonyms +WHERE owner = 'PUBLIC' + AND table_owner = 'CONTAFIN_ORACLE' +ORDER BY synonym_name; + +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/sys-objects.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/sys-objects.sql new file mode 100644 index 0000000..fec8b92 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/sys-objects.sql @@ -0,0 +1,952 @@ +-- ============================================================================ +-- SYS CUSTOM OBJECTS FOR ROA APPLICATION +-- ============================================================================ +-- Oracle 21c/18c Compatible Version +-- Updated: January 2026 +-- +-- This file contains all custom SYS objects required by the ROA application: +-- - Tables: AUTH_DETALII, AUTH_SERII, INFO +-- - View: VAUTH_SERII +-- - Sequence: SEQ_AUTH_SERII +-- - Package: AUTH_PACK (uses DBMS_CRYPTO for Oracle 21c compatibility) +-- - Procedures: EXECUTESCRIPTOS, NEWSCHEMA, NEWSCHEMAJOB, UPDATESQLPLUS, pINFO +-- +-- IMPORTANT: Run this script as SYS with SYSDBA privileges +-- +-- Usage: +-- sqlplus sys/password@service as sysdba @sys-objects.sql +-- +-- ============================================================================ + +SET SERVEROUTPUT ON +SET FEEDBACK ON +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ======================================== +PROMPT Installing SYS Custom Objects +PROMPT ======================================== +PROMPT + +-- ============================================================================ +-- SECTION 1: TABLES +-- ============================================================================ + +PROMPT [1/11] Creating SYS.AUTH_DETALII table... +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count FROM dba_tables + WHERE owner = 'SYS' AND table_name = 'AUTH_DETALII'; + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE(' Table AUTH_DETALII already exists, skipping.'); + ELSE + EXECUTE IMMEDIATE ' + CREATE TABLE SYS.AUTH_DETALII ( + DETALII VARCHAR2(15) NOT NULL + ) TABLESPACE SYSTEM'; + DBMS_OUTPUT.PUT_LINE(' Table AUTH_DETALII created.'); + END IF; +END; +/ + +PROMPT [2/11] Creating SYS.AUTH_SERII table... +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count FROM dba_tables + WHERE owner = 'SYS' AND table_name = 'AUTH_SERII'; + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE(' Table AUTH_SERII already exists, skipping.'); + ELSE + EXECUTE IMMEDIATE ' + CREATE TABLE SYS.AUTH_SERII ( + ID_SERIE NUMBER(5,0) NOT NULL, + ID_PROGRAM NUMBER(5,0) NOT NULL, + SERIE RAW(128) NOT NULL, + STERS NUMBER(1,0) DEFAULT 0 NOT NULL, + DATAORA DATE DEFAULT SYSDATE NOT NULL, + ID_UTIL NUMBER(5,0) NOT NULL, + DATAORAS DATE, + ID_UTILS NUMBER(5,0), + CONSTRAINT PK_AUTH_SERII PRIMARY KEY (ID_SERIE) + ) TABLESPACE SYSTEM'; + DBMS_OUTPUT.PUT_LINE(' Table AUTH_SERII created.'); + END IF; +END; +/ + +PROMPT [3/11] Creating SYS.INFO table (logging)... +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count FROM dba_tables + WHERE owner = 'SYS' AND table_name = 'INFO'; + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE(' Table INFO already exists, skipping.'); + ELSE + EXECUTE IMMEDIATE ' + CREATE TABLE SYS.INFO ( + INFO CLOB, + DATAORA TIMESTAMP(6) DEFAULT SYSTIMESTAMP, + LOCATIA VARCHAR2(200) NULL + ) TABLESPACE SYSTEM'; + DBMS_OUTPUT.PUT_LINE(' Table INFO created.'); + END IF; +END; +/ + +-- ============================================================================ +-- SECTION 2: SEQUENCE +-- ============================================================================ + +PROMPT [4/11] Creating SYS.SEQ_AUTH_SERII sequence... +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count FROM dba_sequences + WHERE sequence_owner = 'SYS' AND sequence_name = 'SEQ_AUTH_SERII'; + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE(' Sequence SEQ_AUTH_SERII already exists, skipping.'); + ELSE + EXECUTE IMMEDIATE ' + CREATE SEQUENCE SYS.SEQ_AUTH_SERII + MINVALUE 1 + MAXVALUE 99999 + INCREMENT BY 1 + START WITH 1 + NOCACHE + NOORDER + NOCYCLE'; + DBMS_OUTPUT.PUT_LINE(' Sequence SEQ_AUTH_SERII created.'); + END IF; +END; +/ + +-- ============================================================================ +-- SECTION 3: LOGGING PROCEDURE (pINFO) +-- ============================================================================ + +PROMPT [5/11] Creating SYS.pINFO procedure (logging)... +CREATE OR REPLACE PROCEDURE SYS.pINFO( + p_info IN CLOB, + p_locatia IN VARCHAR2 DEFAULT NULL +) IS + PRAGMA AUTONOMOUS_TRANSACTION; +BEGIN + INSERT INTO SYS.INFO (INFO, DATAORA, LOCATIA) + VALUES (p_info, SYSTIMESTAMP, p_locatia); + COMMIT; +EXCEPTION + WHEN OTHERS THEN + -- Silently fail to avoid breaking caller + ROLLBACK; +END pINFO; +/ + +-- ============================================================================ +-- SECTION 4: AUTH_PACK PACKAGE (Oracle 21c compatible with DBMS_CRYPTO) +-- ============================================================================ + +PROMPT [6/11] Creating SYS.AUTH_PACK package specification... +CREATE OR REPLACE PACKAGE SYS.AUTH_PACK IS + -- ======================================================================== + -- AUTH_PACK - License and Authentication Management + -- ======================================================================== + -- Author : MARIUS.ATANASIU + -- Created : 11/5/2005 + -- Updated : 2026-01-14 - Migrated to Oracle 21c with DBMS_CRYPTO + -- + -- Purpose: + -- Manages ROA application licensing, including: + -- - Program license verification on login + -- - User count verification per program + -- - License expiration checks + -- - Company count limits + -- ======================================================================== + + PROCEDURE verifica_program; + + PROCEDURE verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2); + + PROCEDURE verifica_licenta_luna( + v_an IN NUMBER, + v_luna IN NUMBER, + v_tip IN NUMBER + ); + + PROCEDURE verifica_numar_firme; + + PROCEDURE adauga_serie( + V_ID_PROGRAM IN NUMBER, + V_SERIE IN VARCHAR2, + V_ID_UTILAD IN NUMBER + ); + + PROCEDURE sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER); + + PROCEDURE verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW); + + FUNCTION selecteaza_serie(V_ID_PROGRAM IN NUMBER) RETURN VARCHAR2; + + FUNCTION selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) RETURN NUMBER; + + FUNCTION selecteaza_data_val(V_ID_PROGRAM IN NUMBER) RETURN DATE; + + FUNCTION decripteaza_serie( + V_ID_PROGRAM IN NUMBER, + V_SERIE IN RAW, + V_DATAORA IN DATE + ) RETURN VARCHAR2; + + FUNCTION decripteaza_nr_util(V_SERIEC IN VARCHAR2) RETURN NUMBER; + + FUNCTION decripteaza_data_val( + V_SERIEC IN VARCHAR2, + V_ZI IN VARCHAR2 + ) RETURN DATE; + + FUNCTION hextodec(V_HEXA IN VARCHAR2) RETURN NUMBER; + + FUNCTION dectohex(V_NUMAR IN NUMBER) RETURN VARCHAR2; + +END AUTH_PACK; +/ + +PROMPT [7/11] Creating SYS.AUTH_PACK package body... +CREATE OR REPLACE PACKAGE BODY SYS.AUTH_PACK IS + -- ======================================================================== + -- MODIFICATION HISTORY: + -- 2026-01-14: Migration Oracle 10g -> Oracle 21c + -- - Replaced DBMS_OBFUSCATION_TOOLKIT.DES3Decrypt with DBMS_CRYPTO.DECRYPT + -- - Using ENCRYPT_3DES_2KEY (16-byte key) + CHAIN_CBC + PAD_ZERO + -- - Added PINFO logging calls for debugging + -- ======================================================================== + + --------------------------------------------------------------------------- + -- VERIFICA_PROGRAM + -- Called on database login (via LOGON trigger) to verify license + --------------------------------------------------------------------------- + PROCEDURE verifica_program IS + v_program VARCHAR2(256); + v_modul VARCHAR2(256); + v_sid NUMBER(16); + BEGIN + BEGIN + SELECT sid, UPPER(TRIM(program)), UPPER(TRIM(module)) + INTO v_sid, v_program, v_modul + FROM v$session + WHERE audsid = USERENV('SESSIONID') + AND audsid != 0 + AND ROWNUM = 1 + AND STATUS <> 'KILLED'; + + PINFO('1 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH'); + + IF v_program NOT IN ( + 'ROASTART.EXE', + 'PLSQLDEV.EXE', + 'ROAGEN.EXE', + 'ROASUPORT.EXE', + 'EXPDP.EXE', + 'IMPDP.EXE', + 'APSNET_WP.EXE', + 'W3WP.EXE', + 'RUBY.EXE', + 'SQLPLUS.EXE', + 'TASKS.EXE', + 'VFP9.EXE', + 'ROAEFACTURA.EXE', + 'WEBDEV.WEBSERVER.EXE', + 'ROA2COCACOLA.EXE', + 'GENERARESCRIPT.EXE', + 'ROAACTUALIZARI.EXE', + 'EXP.EXE', + 'IMP.EXE' + ) AND USER NOT IN ( + 'SYS', + 'SYSTEM', + 'DBSNMP', + 'CTXSYS', + 'MDSYS', + 'DIP', + 'SYSMAN', + 'WMSYS' + ) THEN + PINFO('2 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH'); + + IF v_program <> v_modul THEN + RAISE_APPLICATION_ERROR(-20000, 'Acces interzis!'); + END IF; + + PINFO('3 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH'); + + IF NOT V_PROGRAM LIKE 'ORACLE%' THEN + auth_pack.verifica_licenta(v_sid, v_program); + END IF; + + PINFO('4 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH'); + END IF; + EXCEPTION + WHEN NO_DATA_FOUND THEN + v_program := NULL; + END; + END verifica_program; + + --------------------------------------------------------------------------- + -- VERIFICA_LICENTA + -- Verifies license exists for program and checks user count by IP + --------------------------------------------------------------------------- + PROCEDURE verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2) IS + v_serie VARCHAR2(256); + v_seriec VARCHAR2(256); + v_nr_util NUMBER(5); + v_utilizatori NUMBER(5); + v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE; + v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE; + v_dataora DATE; + v_data_val DATE; + v_zi VARCHAR2(2); + BEGIN + V_NUME_PROGRAM := TRIM(REPLACE(v_program, '.EXE')); + + BEGIN + SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA + INTO V_ID_PROGRAM, V_SERIE, V_DATAORA + FROM SYN_NOM_PROGRAME A + LEFT JOIN AUTH_SERII B ON A.ID_PROGRAM = B.ID_PROGRAM + WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM + AND B.STERS = 0; + EXCEPTION + WHEN NO_DATA_FOUND THEN + PINFO('1 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2'); + RAISE_APPLICATION_ERROR(-20000, + 'Nu aveti licenta pentru ' || V_NUME_PROGRAM || '!' || + CHR(13) || CHR(10) || + ' Licenta poate fi introdusa prin programul ROASUPORT!'); + END; + + PINFO('2 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2'); + + v_zi := LPAD(EXTRACT(DAY FROM v_dataora), 2, '0'); + v_seriec := auth_pack.decripteaza_serie(v_id_program, v_serie, v_dataora); + v_utilizatori := auth_pack.decripteaza_nr_util(v_seriec); + v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi); + + IF v_utilizatori > 0 THEN + -- Count distinct IPs (client_info) connected with same program + -- excluding current session's IP + SELECT COUNT(DISTINCT client_info) + INTO v_nr_util + FROM v$session + WHERE UPPER(TRIM(PROGRAM)) = v_program + AND SID != v_sid + AND STATUS <> 'KILLED' + AND NVL(client_info, 'x') <> SYS_CONTEXT('userenv', 'ip_address'); + + IF v_nr_util >= v_utilizatori THEN + RAISE_APPLICATION_ERROR(-20000, + 'Ati depasit numarul de licente (' || v_utilizatori || + ') pentru programul ' || v_nume_program || ' !' || + CHR(13) || CHR(10) || + ' Licenta poate fi reinnoita prin programul ROASUPORT!'); + END IF; + ELSE + RAISE_APPLICATION_ERROR(-20000, + 'Seria introdusa pentru acest program nu este corecta!' || + CHR(13) || CHR(10) || + ' Licenta poate fi modificata prin programul ROASUPORT!'); + END IF; + + PINFO('3 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2'); + END verifica_licenta; + + --------------------------------------------------------------------------- + -- VERIFICA_LICENTA_LUNA + -- Verifies license for opening a new month (triggered on CALENDAR insert) + --------------------------------------------------------------------------- + PROCEDURE verifica_licenta_luna( + v_an IN NUMBER, + v_luna IN NUMBER, + v_tip IN NUMBER + ) IS + v_serie VARCHAR2(256); + v_seriec VARCHAR2(256); + v_nume_program1 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART'; + v_nume_program2 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASAL'; + v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE; + v_dataora DATE; + v_data_val DATE; + v_zi VARCHAR2(2); + BEGIN + BEGIN + SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA + INTO V_ID_PROGRAM, V_SERIE, V_DATAORA + FROM SYN_NOM_PROGRAME A + LEFT JOIN AUTH_SERII B ON A.ID_PROGRAM = B.ID_PROGRAM + WHERE UPPER(TRIM(A.DENUMIRE)) = + DECODE(V_TIP, 1, V_NUME_PROGRAM1, 2, V_NUME_PROGRAM2, 'XYZ') + AND B.STERS = 0; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RAISE_APPLICATION_ERROR(-20000, + 'Nu aveti licenta pentru deschiderea de luna noua!' || + CHR(13) || CHR(10) || + ' Licenta poate fi introdusa prin programul ROASUPORT!'); + END; + + v_zi := LPAD(EXTRACT(DAY FROM v_dataora), 2, '0'); + v_seriec := auth_pack.decripteaza_serie(v_id_program, v_serie, v_dataora); + v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi); + + IF v_data_val < TO_DATE(v_an || v_luna, 'YYYYMM') THEN + RAISE_APPLICATION_ERROR(-20000, + 'Licenta pentru acest program a expirat!' || + CHR(13) || CHR(10) || + ' Licenta poate fi reinnoita prin programul ROASUPORT!'); + END IF; + END verifica_licenta_luna; + + --------------------------------------------------------------------------- + -- VERIFICA_NUMAR_FIRME + -- Verifies company count doesn't exceed license limit + --------------------------------------------------------------------------- + PROCEDURE verifica_numar_firme IS + v_serie VARCHAR2(256); + v_seriec VARCHAR2(256); + v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART'; + v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE; + v_dataora DATE; + V_NR_MAX_FIRME NUMBER(10) := 0; + V_NR_FIRME NUMBER(10) := 0; + BEGIN + BEGIN + SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA + INTO V_ID_PROGRAM, V_SERIE, V_DATAORA + FROM SYN_NOM_PROGRAME A + LEFT JOIN AUTH_SERII B ON A.ID_PROGRAM = B.ID_PROGRAM + WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM + AND B.STERS = 0; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RAISE_APPLICATION_ERROR(-20000, + 'Nu aveti licenta pentru deschiderea unei firme noi!' || + CHR(13) || CHR(10) || + ' Licenta poate fi introdusa prin programul ROASUPORT!'); + END; + + v_seriec := auth_pack.decripteaza_serie(v_id_program, v_serie, v_dataora); + V_NR_MAX_FIRME := auth_pack.decripteaza_nr_util(V_SERIEC); + + SELECT COUNT(*) + INTO V_NR_FIRME + FROM SYN_NOM_FIRME + WHERE STERS = 0 + AND NVL(ID_MAMA, 0) = 0; + + IF V_NR_FIRME >= V_NR_MAX_FIRME THEN + RAISE_APPLICATION_ERROR(-20000, + 'Aveti licenta pentru maxim ' || V_NR_MAX_FIRME || + ' firme (' || V_NR_FIRME || ' firme deja definite)!' || + CHR(13) || CHR(10) || + ' Licenta poate fi introdusa prin programul ROASUPORT!'); + END IF; + END verifica_numar_firme; + + --------------------------------------------------------------------------- + -- ADAUGA_SERIE + -- Adds a new license serial number for a program + --------------------------------------------------------------------------- + PROCEDURE adauga_serie( + V_ID_PROGRAM IN NUMBER, + V_SERIE IN VARCHAR2, + V_ID_UTILAD IN NUMBER + ) IS + V_ID_SERIE AUTH_SERII.ID_SERIE%TYPE; + V_SERIER AUTH_SERII.SERIE%TYPE; + eroare_de_conversie EXCEPTION; + PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502); + BEGIN + BEGIN + V_SERIER := HEXTORAW(V_SERIE); + EXCEPTION + WHEN eroare_de_conversie THEN + RAISE_APPLICATION_ERROR(-20000, 'Aceasta serie nu este valida!'); + END; + + auth_pack.verifica_serie(V_ID_PROGRAM, V_SERIER); + + SELECT SEQ_AUTH_SERII.NEXTVAL INTO V_ID_SERIE FROM DUAL; + + INSERT INTO AUTH_SERII (ID_SERIE, ID_PROGRAM, SERIE, ID_UTIL) + VALUES (V_ID_SERIE, V_ID_PROGRAM, V_SERIER, V_ID_UTILAD); + END adauga_serie; + + --------------------------------------------------------------------------- + -- STERGE_SERIE + -- Marks a license serial as deleted (soft delete) + --------------------------------------------------------------------------- + PROCEDURE sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER) IS + BEGIN + UPDATE AUTH_SERII + SET STERS = 1, ID_UTILS = V_ID_UTILS, DATAORAS = SYSDATE + WHERE ID_PROGRAM = V_ID_PROGRAM + AND STERS = 0; + END sterge_serie; + + --------------------------------------------------------------------------- + -- SELECTEAZA_SERIE + -- Returns the hex-encoded serial for a program + --------------------------------------------------------------------------- + FUNCTION selecteaza_serie(V_ID_PROGRAM IN NUMBER) RETURN VARCHAR2 IS + V_SERIE AUTH_SERII.SERIE%TYPE; + V_SERIEC VARCHAR2(256); + eroare_de_conversie EXCEPTION; + PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502); + BEGIN + BEGIN + SELECT SERIE + INTO V_SERIE + FROM AUTH_SERII + WHERE ID_PROGRAM = V_ID_PROGRAM + AND STERS = 0; + EXCEPTION + WHEN NO_DATA_FOUND THEN + V_SERIE := NULL; + END; + + BEGIN + V_SERIEC := TRIM(RAWTOHEX(V_SERIE)); + EXCEPTION + WHEN eroare_de_conversie THEN + V_SERIEC := NULL; + END; + + RETURN V_SERIEC; + END selecteaza_serie; + + --------------------------------------------------------------------------- + -- SELECTEAZA_NR_UTIL + -- Returns the number of licensed users for a program + --------------------------------------------------------------------------- + FUNCTION selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) RETURN NUMBER IS + V_SERIE AUTH_SERII.SERIE%TYPE; + V_DATAORA DATE; + V_NR_UTILIZATORI NUMBER(4); + V_SERIEC VARCHAR2(64); + BEGIN + BEGIN + SELECT SERIE, DATAORA + INTO V_SERIE, V_DATAORA + FROM AUTH_SERII + WHERE ID_PROGRAM = V_ID_PROGRAM + AND STERS = 0; + + V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM, V_SERIE, V_DATAORA); + V_NR_UTILIZATORI := auth_pack.decripteaza_nr_util(V_SERIEC); + EXCEPTION + WHEN NO_DATA_FOUND THEN + V_NR_UTILIZATORI := 0; + END; + + RETURN V_NR_UTILIZATORI; + END selecteaza_nr_util; + + --------------------------------------------------------------------------- + -- SELECTEAZA_DATA_VAL + -- Returns the license expiration date for a program + --------------------------------------------------------------------------- + FUNCTION selecteaza_data_val(V_ID_PROGRAM IN NUMBER) RETURN DATE IS + V_SERIE AUTH_SERII.SERIE%TYPE; + V_DATAORA DATE; + V_DATA_VAL DATE; + V_SERIEC VARCHAR2(64); + V_ZI VARCHAR2(2); + BEGIN + BEGIN + SELECT SERIE, DATAORA + INTO V_SERIE, V_DATAORA + FROM AUTH_SERII + WHERE ID_PROGRAM = V_ID_PROGRAM + AND STERS = 0; + + V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM, V_SERIE, V_DATAORA); + V_ZI := LPAD(EXTRACT(DAY FROM V_DATAORA), 2, '0'); + V_DATA_VAL := auth_pack.decripteaza_data_val(V_SERIEC, V_ZI); + EXCEPTION + WHEN NO_DATA_FOUND THEN + V_DATA_VAL := NULL; + END; + + RETURN V_DATA_VAL; + END selecteaza_data_val; + + --------------------------------------------------------------------------- + -- VERIFICA_SERIE + -- Validates a license serial checksum + --------------------------------------------------------------------------- + PROCEDURE verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW) IS + v_seriedec VARCHAR2(256); + v_checksum NUMBER(2); + v_suma NUMBER(2) := 0; + BEGIN + v_seriedec := auth_pack.decripteaza_serie(V_ID_PROGRAM, V_SERIE, SYSDATE); + + v_checksum := auth_pack.hextodec(SUBSTR(v_seriedec, LENGTH(v_seriedec), 1)); + + FOR i IN 1 .. LENGTH(v_seriedec) - 1 LOOP + v_suma := v_suma + auth_pack.hextodec(SUBSTR(v_seriedec, i, 1)); + END LOOP; + + IF MOD(v_suma + v_checksum, 16) <> 0 THEN + RAISE_APPLICATION_ERROR(-20000, 'Seria introdusa nu este valida!'); + END IF; + END verifica_serie; + + --------------------------------------------------------------------------- + -- DECRIPTEAZA_SERIE + -- Decrypts a license serial using DBMS_CRYPTO (Oracle 21c compatible) + -- Replaced DBMS_OBFUSCATION_TOOLKIT.DES3Decrypt + --------------------------------------------------------------------------- + FUNCTION decripteaza_serie( + V_ID_PROGRAM IN NUMBER, + V_SERIE IN RAW, + V_DATAORA IN DATE + ) RETURN VARCHAR2 IS + v_denumire CONTAFIN_ORACLE.NOM_PROGRAME.DENUMIRE%TYPE; + v_id_client NUMBER(4); + v_cheie RAW(16); + v_serieval RAW(256); + v_seriedec VARCHAR2(32); + v_valoare NUMBER(2); + eroare_de_conversie EXCEPTION; + PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502); + BEGIN + IF V_SERIE IS NOT NULL THEN + SELECT SUBSTR(a.denumire, 4, 5) + INTO V_DENUMIRE + FROM SYN_NOM_PROGRAME A + WHERE A.ID_PROGRAM = V_ID_PROGRAM; + + SELECT TO_NUMBER(DETALII) INTO V_ID_CLIENT FROM AUTH_DETALII; + + -- Build 16-byte key for 3DES-2KEY + v_cheie := UTL_RAW.CAST_TO_RAW( + RPAD( + LPAD(v_id_program, 3, '0') || + LPAD(v_id_client, 4, '0') || + RPAD(v_denumire, 5, CHR(4)) || + LPAD(TO_CHAR(v_dataora, 'IWYY'), 4, '0'), + 16, + 'X' + ) + ); + + -- Use DBMS_CRYPTO instead of DBMS_OBFUSCATION_TOOLKIT + -- ENCRYPT_3DES_2KEY for 16-byte keys, PAD_ZERO for compatibility + v_serieval := DBMS_CRYPTO.DECRYPT( + src => v_serie, + typ => DBMS_CRYPTO.ENCRYPT_3DES_2KEY + + DBMS_CRYPTO.CHAIN_CBC + + DBMS_CRYPTO.PAD_ZERO, + key => v_cheie + ); + + BEGIN + FOR i IN 1 .. LENGTH(v_serieval) / 2 LOOP + v_valoare := TO_NUMBER(SUBSTR(v_serieval, 2 * i - 1, 2)); + IF v_valoare > 40 THEN + v_seriedec := v_seriedec || auth_pack.dectohex(v_valoare - 31); + ELSE + v_seriedec := v_seriedec || (v_valoare - 30); + END IF; + END LOOP; + EXCEPTION + WHEN eroare_de_conversie THEN + RAISE_APPLICATION_ERROR(-20100, 'Seria introdusa nu este valida!'); + END; + ELSE + v_seriedec := NULL; + END IF; + + RETURN v_seriedec; + END decripteaza_serie; + + --------------------------------------------------------------------------- + -- DECRIPTEAZA_NR_UTIL + -- Extracts user count from decrypted serial + --------------------------------------------------------------------------- + FUNCTION decripteaza_nr_util(V_SERIEC IN VARCHAR2) RETURN NUMBER IS + BEGIN + IF V_SERIEC IS NOT NULL THEN + RETURN TO_NUMBER(SUBSTR(v_seriec, 1, 4)); + ELSE + RETURN 0; + END IF; + END decripteaza_nr_util; + + --------------------------------------------------------------------------- + -- DECRIPTEAZA_DATA_VAL + -- Extracts expiration date from decrypted serial + --------------------------------------------------------------------------- + FUNCTION decripteaza_data_val( + V_SERIEC IN VARCHAR2, + V_ZI IN VARCHAR2 + ) RETURN DATE IS + v_luna VARCHAR2(2); + BEGIN + IF V_SERIEC IS NOT NULL THEN + v_luna := LPAD(auth_pack.hextodec(SUBSTR(v_seriec, 5, 1)), 2, '0'); + RETURN LAST_DAY(TO_DATE(v_luna || SUBSTR(v_seriec, 6, 2), 'MMYY')); + ELSE + RETURN NULL; + END IF; + END decripteaza_data_val; + + --------------------------------------------------------------------------- + -- HEXTODEC + -- Converts a hex character to decimal + --------------------------------------------------------------------------- + FUNCTION hextodec(V_HEXA IN VARCHAR2) RETURN NUMBER IS + v_numar NUMBER(2); + BEGIN + IF ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 48 AND 57 OR + ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 65 AND 70 THEN + CASE UPPER(TRIM(V_HEXA)) + WHEN 'A' THEN v_numar := 10; + WHEN 'B' THEN v_numar := 11; + WHEN 'C' THEN v_numar := 12; + WHEN 'D' THEN v_numar := 13; + WHEN 'E' THEN v_numar := 14; + WHEN 'F' THEN v_numar := 15; + ELSE v_numar := TO_NUMBER(V_HEXA); + END CASE; + ELSE + RAISE_APPLICATION_ERROR(-20000, 'Caracterul nu este valid!'); + END IF; + RETURN v_numar; + END hextodec; + + --------------------------------------------------------------------------- + -- DECTOHEX + -- Converts a decimal to hex character + --------------------------------------------------------------------------- + FUNCTION dectohex(V_NUMAR IN NUMBER) RETURN VARCHAR2 IS + v_hexa VARCHAR2(1); + BEGIN + CASE v_numar + WHEN 10 THEN v_hexa := 'A'; + WHEN 11 THEN v_hexa := 'B'; + WHEN 12 THEN v_hexa := 'C'; + WHEN 13 THEN v_hexa := 'D'; + WHEN 14 THEN v_hexa := 'E'; + WHEN 15 THEN v_hexa := 'F'; + ELSE v_hexa := TO_CHAR(V_NUMAR); + END CASE; + RETURN v_hexa; + END dectohex; + +END AUTH_PACK; +/ + +-- ============================================================================ +-- SECTION 5: VIEW +-- ============================================================================ + +PROMPT [8/11] Creating SYS.VAUTH_SERII view... +CREATE OR REPLACE VIEW SYS.VAUTH_SERII ( + ID_PROGRAM, + NUME, + SERIE, + NR_UTIL, + DATA_VAL +) AS +SELECT a.id_program, + a.denumire AS nume, + auth_pack.selecteaza_serie(a.id_program) AS serie, + auth_pack.selecteaza_nr_util(a.id_program) AS nr_util, + auth_pack.selecteaza_data_val(a.id_program) AS data_val +FROM syn_nom_programe a +LEFT JOIN syn_def_programe b ON a.id_program = b.ide_program +WHERE b.sters = 0 + AND b.instalat = 1; + +-- ============================================================================ +-- SECTION 6: ADDITIONAL PROCEDURES +-- ============================================================================ + +PROMPT [9/11] Creating SYS.EXECUTESCRIPTOS procedure... +CREATE OR REPLACE PROCEDURE SYS.EXECUTESCRIPTOS( + p_nume_script IN VARCHAR2, + p_param IN VARCHAR2, + p_wait IN VARCHAR2, + p_result OUT NUMBER +) IS + v_job_name VARCHAR2(100); + v_state VARCHAR2(30); +BEGIN + v_job_name := 'EXECUTESCRIPTOS_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS'); + + DBMS_SCHEDULER.CREATE_JOB( + job_name => v_job_name, + job_type => 'EXECUTABLE', + job_action => p_nume_script, + number_of_arguments => 1, + start_date => SYSTIMESTAMP, + enabled => FALSE, + auto_drop => TRUE + ); + + DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( + job_name => v_job_name, + argument_position => 1, + argument_value => p_param + ); + + DBMS_SCHEDULER.ENABLE(v_job_name); + + IF p_wait = 'Y' THEN + LOOP + BEGIN + SELECT state INTO v_state + FROM dba_scheduler_jobs + WHERE job_name = v_job_name; + + EXIT WHEN v_state NOT IN ('SCHEDULED', 'RUNNING'); + EXCEPTION + WHEN NO_DATA_FOUND THEN + EXIT; -- Job completed and was auto-dropped + END; + DBMS_LOCK.SLEEP(1); + END LOOP; + END IF; + + p_result := 0; +EXCEPTION + WHEN OTHERS THEN + p_result := -1; +END EXECUTESCRIPTOS; +/ + +PROMPT [10/11] Creating SYS.NEWSCHEMA procedure... +CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMA( + p_schema_name IN VARCHAR2, + p_password IN VARCHAR2, + p_result OUT NUMBER +) IS +BEGIN + EXECUTE IMMEDIATE 'CREATE USER ' || p_schema_name || + ' IDENTIFIED BY ' || p_password || + ' DEFAULT TABLESPACE ROA' || + ' TEMPORARY TABLESPACE TEMP' || + ' QUOTA UNLIMITED ON ROA'; + + EXECUTE IMMEDIATE 'GRANT CONNECT, RESOURCE TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE SESSION TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE TABLE TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE VIEW TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE SEQUENCE TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE PROCEDURE TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE TRIGGER TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE TYPE TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE SYNONYM TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE DATABASE LINK TO ' || p_schema_name; + EXECUTE IMMEDIATE 'GRANT CREATE JOB TO ' || p_schema_name; + + DBMS_OUTPUT.PUT_LINE('Schema ' || p_schema_name || ' created successfully!'); + + p_result := 0; +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE('Error creating schema: ' || SQLERRM); + p_result := -1; +END NEWSCHEMA; +/ + +PROMPT [11/11] Creating SYS.NEWSCHEMAJOB and SYS.UPDATESQLPLUS procedures... +CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMAJOB( + p_schema_name IN VARCHAR2, + p_password IN VARCHAR2 +) IS + v_job_name VARCHAR2(100); +BEGIN + v_job_name := 'NEWSCHEMA_' || p_schema_name; + + DBMS_SCHEDULER.CREATE_JOB( + job_name => v_job_name, + job_type => 'STORED_PROCEDURE', + job_action => 'SYS.NEWSCHEMA', + number_of_arguments => 3, + start_date => SYSTIMESTAMP, + enabled => FALSE, + auto_drop => TRUE + ); + + DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( + job_name => v_job_name, + argument_position => 1, + argument_value => p_schema_name + ); + + DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( + job_name => v_job_name, + argument_position => 2, + argument_value => p_password + ); + + DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( + job_name => v_job_name, + argument_position => 3, + argument_value => '0' + ); + + DBMS_SCHEDULER.ENABLE(v_job_name); +END NEWSCHEMAJOB; +/ + +CREATE OR REPLACE PROCEDURE SYS.UPDATESQLPLUS IS + v_result NUMBER; +BEGIN + -- Path may need to be adjusted for your Windows installation + EXECUTESCRIPTOS('D:\ROMFAST\UPDATE\UPDATE_SQLPLUS.BAT', '', 'N', v_result); +END UPDATESQLPLUS; +/ + +-- ============================================================================ +-- VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT Verifying SYS Custom Objects +PROMPT ======================================== +PROMPT + +PROMPT SYS custom objects status: +SELECT object_name, object_type, status +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ( + 'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', 'UPDATESQLPLUS', + 'PINFO', 'INFO', 'SEQ_AUTH_SERII' + ) +ORDER BY object_type, object_name; + +PROMPT +PROMPT Invalid objects (should be empty): +SELECT object_name, object_type, status +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ( + 'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', 'UPDATESQLPLUS', + 'PINFO', 'INFO', 'SEQ_AUTH_SERII' + ) + AND status != 'VALID'; + +PROMPT +PROMPT ======================================== +PROMPT SYS Custom Objects Installation Complete +PROMPT ======================================== +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/verify-objects.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/verify-objects.sql new file mode 100644 index 0000000..05e079a --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/verify-objects.sql @@ -0,0 +1,514 @@ +-- ============================================================================ +-- ROA DATABASE VERIFICATION SCRIPT +-- ============================================================================ +-- Comprehensive verification of all ROA database objects and configuration +-- +-- Usage: +-- @verify-objects.sql +-- +-- Connect as: SYSDBA or SYSTEM +-- +-- This script verifies: +-- 1. Tablespace ROA exists +-- 2. Users CONTAFIN_ORACLE and company schemas exist +-- 3. SYS custom objects (AUTH_PACK, NEWSCHEMA, etc.) +-- 4. Public synonyms count and status +-- 5. Invalid objects +-- 6. Profile settings +-- 7. Network ACL configuration +-- ============================================================================ + +SET ECHO OFF +SET FEEDBACK ON +SET SERVEROUTPUT ON +SET LINESIZE 200 +SET PAGESIZE 100 +WHENEVER SQLERROR CONTINUE + +PROMPT +PROMPT ============================================================ +PROMPT ROA DATABASE VERIFICATION REPORT +PROMPT Generated: +SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS "Report Time" FROM DUAL; +PROMPT ============================================================ +PROMPT + +-- ============================================================================ +-- SECTION 1: DATABASE INFORMATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [1/10] DATABASE INFORMATION +PROMPT ======================================== +PROMPT + +COLUMN name FORMAT A20 +COLUMN value FORMAT A50 + +SELECT name, cdb, open_mode, log_mode +FROM v$database; + +PROMPT +PROMPT Instance Information: +SELECT instance_name, host_name, version_full, status +FROM v$instance; + +PROMPT +PROMPT Current Container (for Oracle 12c+): +SHOW CON_NAME + +-- ============================================================================ +-- SECTION 2: TABLESPACE VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [2/10] TABLESPACE ROA VERIFICATION +PROMPT ======================================== +PROMPT + +COLUMN tablespace_name FORMAT A15 +COLUMN status FORMAT A10 +COLUMN contents FORMAT A10 +COLUMN extent_management FORMAT A10 + +SELECT tablespace_name, status, contents, extent_management +FROM dba_tablespaces +WHERE tablespace_name = 'ROA'; + +PROMPT +PROMPT ROA Datafile(s): +COLUMN file_name FORMAT A60 +COLUMN size_mb FORMAT 999,999.99 +COLUMN max_mb FORMAT 999,999.99 + +SELECT file_name, + bytes/1024/1024 AS size_mb, + autoextensible, + CASE WHEN maxbytes = 0 THEN bytes/1024/1024 + ELSE maxbytes/1024/1024 + END AS max_mb +FROM dba_data_files +WHERE tablespace_name = 'ROA'; + +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count FROM dba_tablespaces WHERE tablespace_name = 'ROA'; + IF v_count = 0 THEN + DBMS_OUTPUT.PUT_LINE('*** ERROR: Tablespace ROA does not exist! ***'); + ELSE + DBMS_OUTPUT.PUT_LINE('OK: Tablespace ROA exists.'); + END IF; +END; +/ + +-- ============================================================================ +-- SECTION 3: USER VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [3/10] USER VERIFICATION +PROMPT ======================================== +PROMPT + +COLUMN username FORMAT A25 +COLUMN default_tablespace FORMAT A15 +COLUMN account_status FORMAT A20 + +PROMPT CONTAFIN_ORACLE user: +SELECT username, default_tablespace, temporary_tablespace, account_status, profile +FROM dba_users +WHERE username = 'CONTAFIN_ORACLE'; + +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count FROM dba_users WHERE username = 'CONTAFIN_ORACLE'; + IF v_count = 0 THEN + DBMS_OUTPUT.PUT_LINE('*** ERROR: User CONTAFIN_ORACLE does not exist! ***'); + ELSE + DBMS_OUTPUT.PUT_LINE('OK: User CONTAFIN_ORACLE exists.'); + END IF; +END; +/ + +PROMPT +PROMPT Company schemas (users with ROA default tablespace): +SELECT username, account_status, created +FROM dba_users +WHERE default_tablespace = 'ROA' + AND username NOT IN ('CONTAFIN_ORACLE') +ORDER BY username; + +PROMPT +PROMPT CONTAFIN_ORACLE system privileges: +SELECT privilege +FROM dba_sys_privs +WHERE grantee = 'CONTAFIN_ORACLE' +ORDER BY privilege; + +PROMPT +PROMPT CONTAFIN_ORACLE roles: +SELECT granted_role, default_role +FROM dba_role_privs +WHERE grantee = 'CONTAFIN_ORACLE'; + +-- ============================================================================ +-- SECTION 4: SYS CUSTOM OBJECTS VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [4/10] SYS CUSTOM OBJECTS +PROMPT ======================================== +PROMPT + +COLUMN object_name FORMAT A25 +COLUMN object_type FORMAT A15 +COLUMN status FORMAT A10 + +PROMPT Expected SYS custom objects: +SELECT object_name, object_type, status, created +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ( + 'AUTH_PACK', + 'AUTH_DETALII', + 'AUTH_SERII', + 'VAUTH_SERII', + 'SEQ_AUTH_SERII', + 'EXECUTESCRIPTOS', + 'NEWSCHEMA', + 'NEWSCHEMAJOB', + 'UPDATESQLPLUS', + 'PINFO', + 'INFO' + ) +ORDER BY object_type, object_name; + +DECLARE + v_count NUMBER; + v_expected NUMBER := 12; -- Tables: 3, View: 1, Sequence: 1, Package: 2, Procedures: 5 +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_objects + WHERE owner = 'SYS' + AND object_name IN ( + 'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'SEQ_AUTH_SERII', 'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', + 'UPDATESQLPLUS', 'PINFO', 'INFO' + ) + AND status = 'VALID'; + + DBMS_OUTPUT.PUT_LINE('Found ' || v_count || ' valid SYS custom objects.'); + IF v_count < 10 THEN + DBMS_OUTPUT.PUT_LINE('*** WARNING: Some SYS objects may be missing or invalid! ***'); + ELSE + DBMS_OUTPUT.PUT_LINE('OK: All expected SYS custom objects are present.'); + END IF; +END; +/ + +-- ============================================================================ +-- SECTION 5: PUBLIC SYNONYMS VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [5/10] PUBLIC SYNONYMS +PROMPT ======================================== +PROMPT + +PROMPT Public synonyms pointing to CONTAFIN_ORACLE: +SELECT COUNT(*) AS total_synonyms +FROM dba_synonyms +WHERE owner = 'PUBLIC' + AND table_owner = 'CONTAFIN_ORACLE'; + +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_synonyms + WHERE owner = 'PUBLIC' + AND table_owner = 'CONTAFIN_ORACLE'; + + IF v_count < 50 THEN + DBMS_OUTPUT.PUT_LINE('*** WARNING: Expected 50+ public synonyms, found ' || v_count || ' ***'); + ELSE + DBMS_OUTPUT.PUT_LINE('OK: Found ' || v_count || ' public synonyms for CONTAFIN_ORACLE.'); + END IF; +END; +/ + +PROMPT +PROMPT Key public synonyms check: +SELECT + CASE WHEN EXISTS (SELECT 1 FROM dba_synonyms WHERE owner='PUBLIC' AND synonym_name='SYN_NOM_FIRME') + THEN 'OK' ELSE 'MISSING' END AS SYN_NOM_FIRME, + CASE WHEN EXISTS (SELECT 1 FROM dba_synonyms WHERE owner='PUBLIC' AND synonym_name='SYN_NOM_PROGRAME') + THEN 'OK' ELSE 'MISSING' END AS SYN_NOM_PROGRAME, + CASE WHEN EXISTS (SELECT 1 FROM dba_synonyms WHERE owner='PUBLIC' AND synonym_name='SYN_UTILIZATORI') + THEN 'OK' ELSE 'MISSING' END AS SYN_UTILIZATORI, + CASE WHEN EXISTS (SELECT 1 FROM dba_synonyms WHERE owner='PUBLIC' AND synonym_name='PACK_UPDATE') + THEN 'OK' ELSE 'MISSING' END AS PACK_UPDATE, + CASE WHEN EXISTS (SELECT 1 FROM dba_synonyms WHERE owner='PUBLIC' AND synonym_name='PACK_UTILS') + THEN 'OK' ELSE 'MISSING' END AS PACK_UTILS +FROM DUAL; + +-- ============================================================================ +-- SECTION 6: CONTAFIN_ORACLE OBJECTS +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [6/10] CONTAFIN_ORACLE SCHEMA OBJECTS +PROMPT ======================================== +PROMPT + +PROMPT Object count by type: +SELECT object_type, COUNT(*) AS count +FROM dba_objects +WHERE owner = 'CONTAFIN_ORACLE' +GROUP BY object_type +ORDER BY object_type; + +PROMPT +PROMPT Total objects in CONTAFIN_ORACLE: +SELECT COUNT(*) AS total_objects +FROM dba_objects +WHERE owner = 'CONTAFIN_ORACLE'; + +-- ============================================================================ +-- SECTION 7: INVALID OBJECTS +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [7/10] INVALID OBJECTS CHECK +PROMPT ======================================== +PROMPT + +PROMPT Invalid SYS custom objects: +SELECT object_name, object_type, status +FROM dba_objects +WHERE owner = 'SYS' + AND object_name IN ( + 'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII', + 'SEQ_AUTH_SERII', 'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', + 'UPDATESQLPLUS', 'PINFO', 'INFO' + ) + AND status != 'VALID'; + +PROMPT +PROMPT Invalid CONTAFIN_ORACLE objects: +SELECT object_name, object_type +FROM dba_objects +WHERE owner = 'CONTAFIN_ORACLE' + AND status = 'INVALID' +ORDER BY object_type, object_name; + +DECLARE + v_count NUMBER; +BEGIN + SELECT COUNT(*) INTO v_count + FROM dba_objects + WHERE owner = 'CONTAFIN_ORACLE' + AND status = 'INVALID'; + + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE('*** WARNING: ' || v_count || ' invalid objects in CONTAFIN_ORACLE ***'); + DBMS_OUTPUT.PUT_LINE('Run: ALTER PACKAGE/PROCEDURE/VIEW ... COMPILE; to fix'); + ELSE + DBMS_OUTPUT.PUT_LINE('OK: No invalid objects in CONTAFIN_ORACLE.'); + END IF; +END; +/ + +-- ============================================================================ +-- SECTION 8: PROFILE SETTINGS +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [8/10] PROFILE PASSWORD SETTINGS +PROMPT ======================================== +PROMPT + +COLUMN resource_name FORMAT A30 +COLUMN limit FORMAT A20 + +SELECT resource_name, limit +FROM dba_profiles +WHERE profile = 'DEFAULT' + AND resource_type = 'PASSWORD' +ORDER BY resource_name; + +DECLARE + v_limit VARCHAR2(40); +BEGIN + SELECT limit INTO v_limit + FROM dba_profiles + WHERE profile = 'DEFAULT' + AND resource_name = 'PASSWORD_LIFE_TIME'; + + IF v_limit != 'UNLIMITED' THEN + DBMS_OUTPUT.PUT_LINE('*** WARNING: PASSWORD_LIFE_TIME is not UNLIMITED (' || v_limit || ')'); + DBMS_OUTPUT.PUT_LINE('Run configure-profile.sql to fix.'); + ELSE + DBMS_OUTPUT.PUT_LINE('OK: PASSWORD_LIFE_TIME is UNLIMITED.'); + END IF; +END; +/ + +-- ============================================================================ +-- SECTION 9: DIRECTORY AND ACL VERIFICATION +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [9/10] DIRECTORY AND ACL CONFIGURATION +PROMPT ======================================== +PROMPT + +PROMPT DMPDIR Directory: +COLUMN directory_name FORMAT A15 +COLUMN directory_path FORMAT A60 + +SELECT directory_name, directory_path +FROM dba_directories +WHERE directory_name = 'DMPDIR'; + +PROMPT +PROMPT Network ACL for CONTAFIN_ORACLE: +SELECT host, acl +FROM dba_network_acls +WHERE acl LIKE '%roaupdate%'; + +PROMPT +PROMPT ACL Privileges: +SELECT principal, privilege, is_grant +FROM dba_network_acl_privileges +WHERE acl LIKE '%roaupdate%'; + +-- ============================================================================ +-- SECTION 10: AUTH_DETALII DATA CHECK +-- ============================================================================ + +PROMPT +PROMPT ======================================== +PROMPT [10/10] LICENSE DATA CHECK +PROMPT ======================================== +PROMPT + +PROMPT AUTH_DETALII (Client ID): +SELECT * FROM SYS.AUTH_DETALII; + +PROMPT +PROMPT AUTH_SERII (License serials - without decryption): +SELECT id_serie, id_program, sters, dataora, id_util +FROM SYS.AUTH_SERII +WHERE sters = 0 +ORDER BY id_program; + +PROMPT +PROMPT License View (via VAUTH_SERII): +BEGIN + FOR rec IN (SELECT * FROM SYS.VAUTH_SERII) LOOP + DBMS_OUTPUT.PUT_LINE('Program: ' || rec.nume || + ', Users: ' || rec.nr_util || + ', Valid until: ' || TO_CHAR(rec.data_val, 'YYYY-MM-DD')); + END LOOP; +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE('Note: Cannot query VAUTH_SERII - ' || SQLERRM); + DBMS_OUTPUT.PUT_LINE('This is normal if synonyms are not yet created.'); +END; +/ + +-- ============================================================================ +-- SUMMARY +-- ============================================================================ + +PROMPT +PROMPT ============================================================ +PROMPT VERIFICATION SUMMARY +PROMPT ============================================================ +PROMPT + +DECLARE + v_errors NUMBER := 0; + v_warnings NUMBER := 0; + v_count NUMBER; + v_limit VARCHAR2(40); +BEGIN + -- Check tablespace + SELECT COUNT(*) INTO v_count FROM dba_tablespaces WHERE tablespace_name = 'ROA'; + IF v_count = 0 THEN + DBMS_OUTPUT.PUT_LINE('ERROR: Tablespace ROA missing'); + v_errors := v_errors + 1; + END IF; + + -- Check CONTAFIN_ORACLE user + SELECT COUNT(*) INTO v_count FROM dba_users WHERE username = 'CONTAFIN_ORACLE'; + IF v_count = 0 THEN + DBMS_OUTPUT.PUT_LINE('ERROR: User CONTAFIN_ORACLE missing'); + v_errors := v_errors + 1; + END IF; + + -- Check AUTH_PACK + SELECT COUNT(*) INTO v_count FROM dba_objects + WHERE owner = 'SYS' AND object_name = 'AUTH_PACK' AND object_type = 'PACKAGE BODY' AND status = 'VALID'; + IF v_count = 0 THEN + DBMS_OUTPUT.PUT_LINE('ERROR: AUTH_PACK package missing or invalid'); + v_errors := v_errors + 1; + END IF; + + -- Check public synonyms + SELECT COUNT(*) INTO v_count FROM dba_synonyms + WHERE owner = 'PUBLIC' AND table_owner = 'CONTAFIN_ORACLE'; + IF v_count < 50 THEN + DBMS_OUTPUT.PUT_LINE('WARNING: Only ' || v_count || ' public synonyms (expected 50+)'); + v_warnings := v_warnings + 1; + END IF; + + -- Check invalid objects + SELECT COUNT(*) INTO v_count FROM dba_objects + WHERE owner = 'CONTAFIN_ORACLE' AND status = 'INVALID'; + IF v_count > 0 THEN + DBMS_OUTPUT.PUT_LINE('WARNING: ' || v_count || ' invalid objects in CONTAFIN_ORACLE'); + v_warnings := v_warnings + 1; + END IF; + + -- Check profile + SELECT limit INTO v_limit FROM dba_profiles + WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_LIFE_TIME'; + IF v_limit != 'UNLIMITED' THEN + DBMS_OUTPUT.PUT_LINE('WARNING: Password expiration is enabled'); + v_warnings := v_warnings + 1; + END IF; + + DBMS_OUTPUT.PUT_LINE(''); + DBMS_OUTPUT.PUT_LINE('----------------------------------------'); + DBMS_OUTPUT.PUT_LINE('Total Errors: ' || v_errors); + DBMS_OUTPUT.PUT_LINE('Total Warnings: ' || v_warnings); + DBMS_OUTPUT.PUT_LINE('----------------------------------------'); + + IF v_errors = 0 AND v_warnings = 0 THEN + DBMS_OUTPUT.PUT_LINE('STATUS: ALL CHECKS PASSED'); + ELSIF v_errors = 0 THEN + DBMS_OUTPUT.PUT_LINE('STATUS: PASSED WITH WARNINGS'); + ELSE + DBMS_OUTPUT.PUT_LINE('STATUS: FAILED - Please fix errors'); + END IF; +END; +/ + +PROMPT +PROMPT ============================================================ +PROMPT END OF VERIFICATION REPORT +PROMPT ============================================================ +PROMPT diff --git a/proxmox/lxc108-oracle/roa-windows-setup/test/clone-vm300.sh b/proxmox/lxc108-oracle/roa-windows-setup/test/clone-vm300.sh new file mode 100644 index 0000000..a6a0e5d --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/test/clone-vm300.sh @@ -0,0 +1,212 @@ +#!/bin/bash +# ============================================================================= +# Clone VM 300 (Windows 11 Template) for Oracle Testing +# ============================================================================= +# +# Purpose: Create a test VM for Oracle installation testing +# +# Usage: +# ./clone-vm300.sh [TARGET_VMID] [TARGET_NAME] +# +# Examples: +# ./clone-vm300.sh # Creates VM 301 named oracle-test-301 +# ./clone-vm300.sh 305 # Creates VM 305 named oracle-test-305 +# ./clone-vm300.sh 310 roa-prod # Creates VM 310 named roa-prod +# +# Prerequisites: +# - Run on Proxmox host (pvemini, pve1, or pveelite) +# - VM 300 exists as Windows 11 template +# - Sufficient storage space (~50GB per clone) +# +# ============================================================================= + +set -e + +# ----------------------------------------------------------------------------- +# Configuration +# ----------------------------------------------------------------------------- + +SOURCE_VMID=300 +TARGET_VMID=${1:-301} +TARGET_NAME=${2:-"oracle-test-${TARGET_VMID}"} + +# Storage for new VM (change if needed) +TARGET_STORAGE="local-zfs" + +# Node where to create the VM (empty = same as source) +TARGET_NODE="" + +# Full clone (true) or linked clone (false) +FULL_CLONE=true + +# Start VM after creation +AUTO_START=true + +# Description for the new VM +DESCRIPTION="Oracle 21c Test VM - Created $(date '+%Y-%m-%d %H:%M')" + +# ----------------------------------------------------------------------------- +# Validation +# ----------------------------------------------------------------------------- + +echo "==============================================" +echo "Proxmox VM Clone Script" +echo "==============================================" +echo "" +echo "Source VM: $SOURCE_VMID" +echo "Target VM: $TARGET_VMID" +echo "Target Name: $TARGET_NAME" +echo "Full Clone: $FULL_CLONE" +echo "Auto Start: $AUTO_START" +echo "" + +# Check if running on Proxmox +if ! command -v qm &> /dev/null; then + echo "ERROR: This script must be run on a Proxmox host" + echo " (qm command not found)" + exit 1 +fi + +# Check if source VM exists +if ! qm status $SOURCE_VMID &> /dev/null; then + echo "ERROR: Source VM $SOURCE_VMID does not exist" + exit 1 +fi + +# Check if target VMID is already in use +if qm status $TARGET_VMID &> /dev/null 2>&1; then + echo "ERROR: Target VMID $TARGET_VMID already exists" + echo " Choose a different VMID or remove existing VM:" + echo " qm destroy $TARGET_VMID" + exit 1 +fi + +# Confirm before proceeding +read -p "Proceed with cloning? [y/N] " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 0 +fi + +# ----------------------------------------------------------------------------- +# Clone VM +# ----------------------------------------------------------------------------- + +echo "" +echo "Creating clone..." + +CLONE_CMD="qm clone $SOURCE_VMID $TARGET_VMID --name $TARGET_NAME" + +if [ "$FULL_CLONE" = true ]; then + CLONE_CMD="$CLONE_CMD --full" +fi + +if [ -n "$TARGET_STORAGE" ]; then + CLONE_CMD="$CLONE_CMD --storage $TARGET_STORAGE" +fi + +if [ -n "$TARGET_NODE" ]; then + CLONE_CMD="$CLONE_CMD --target $TARGET_NODE" +fi + +echo "Running: $CLONE_CMD" +eval $CLONE_CMD + +echo "Clone created successfully" + +# ----------------------------------------------------------------------------- +# Configure VM +# ----------------------------------------------------------------------------- + +echo "" +echo "Configuring VM..." + +# Set description +qm set $TARGET_VMID --description "$DESCRIPTION" + +# Optionally increase resources for Oracle +# qm set $TARGET_VMID --memory 8192 --cores 4 + +echo "VM configured" + +# ----------------------------------------------------------------------------- +# Start VM +# ----------------------------------------------------------------------------- + +if [ "$AUTO_START" = true ]; then + echo "" + echo "Starting VM..." + qm start $TARGET_VMID + + # Wait for VM to start + sleep 5 + + # Check status + STATUS=$(qm status $TARGET_VMID | awk '{print $2}') + echo "VM Status: $STATUS" +fi + +# ----------------------------------------------------------------------------- +# Output Summary +# ----------------------------------------------------------------------------- + +echo "" +echo "==============================================" +echo "VM Clone Complete" +echo "==============================================" +echo "" +echo "VMID: $TARGET_VMID" +echo "Name: $TARGET_NAME" +echo "Status: $(qm status $TARGET_VMID | awk '{print $2}')" +echo "" +echo "Console URL: https://$(hostname -I | awk '{print $1}'):8006/#v1:0:=qemu%2F${TARGET_VMID}:4::::::" +echo "" +echo "Next steps:" +echo " 1. Connect to VM console" +echo " 2. Complete Windows OOBE if needed" +echo " 3. Install Oracle 21c XE or SE" +echo " 4. Run ROA setup scripts" +echo "" +echo "To delete this VM when done:" +echo " qm stop $TARGET_VMID" +echo " qm destroy $TARGET_VMID" +echo "" + +# ----------------------------------------------------------------------------- +# Helper Commands +# ----------------------------------------------------------------------------- + +# Print helpful commands +cat << 'COMMANDS' +# Useful Proxmox commands: + +# List all VMs +qm list + +# VM status +qm status TARGET_VMID + +# Start/Stop/Restart VM +qm start TARGET_VMID +qm stop TARGET_VMID +qm restart TARGET_VMID + +# Access VM console +qm terminal TARGET_VMID + +# Clone with different storage +qm clone 300 TARGET_VMID --name NAME --full --storage local-lvm + +# Snapshot before testing +qm snapshot TARGET_VMID snap-before-oracle --description "Before Oracle install" + +# Rollback to snapshot +qm rollback TARGET_VMID snap-before-oracle + +# Delete VM +qm stop TARGET_VMID && qm destroy TARGET_VMID + +COMMANDS + +exit 0