From bcb558f1dc8477a920211232c7492eeb5e406946 Mon Sep 17 00:00:00 2001 From: Marius Date: Wed, 28 Jan 2026 20:56:58 +0200 Subject: [PATCH] Fix ROA Windows setup scripts for Oracle XE deployment Key fixes: - Add Run.cmd/RunAll.cmd wrappers with ExecutionPolicy Bypass - Add Get-ListenerHost() to auto-detect listener IP address - Fix impdp connection using EZConnect format (host:port/service) - Add parallel=1 for Oracle XE compatibility - Fix Write-Log to accept empty strings with [AllowEmptyString()] - Fix Get-SchemaObjectCount regex for Windows line endings (\r\n) - Fix path comparison for DMP file copy operation - Add GRANT EXECUTE ON SYS.AUTH_PACK TO PUBLIC for PACK_DREPTURI - Fix VAUTH_SERII view to use SYN_NOM_PROGRAME (has DENUMIRE column) - Add sections 10-11 to grants-public.sql for SYS object grants Tested on VM 302 (10.0.20.130) with Oracle XE 21c. Co-Authored-By: Claude Opus 4.5 --- .../lxc108-oracle/roa-windows-setup/README.md | 43 +++++- .../lxc108-oracle/roa-windows-setup/Run.cmd | 83 ++++++++++++ .../roa-windows-setup/RunAll.cmd | 124 ++++++++++++++++++ .../scripts/03-import-contafin.ps1 | 23 ++-- .../scripts/05-import-companies.ps1 | 7 +- .../scripts/99-uninstall-roa.ps1 | 99 ++++++++------ .../scripts/lib/logging-functions.ps1 | 16 ++- .../scripts/lib/oracle-functions.ps1 | 104 +++++++++++++-- .../roa-windows-setup/sql/grants-public.sql | 72 ++++++++++ 9 files changed, 503 insertions(+), 68 deletions(-) create mode 100644 proxmox/lxc108-oracle/roa-windows-setup/Run.cmd create mode 100644 proxmox/lxc108-oracle/roa-windows-setup/RunAll.cmd diff --git a/proxmox/lxc108-oracle/roa-windows-setup/README.md b/proxmox/lxc108-oracle/roa-windows-setup/README.md index b5e7a6d..08cd3b0 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/README.md +++ b/proxmox/lxc108-oracle/roa-windows-setup/README.md @@ -31,14 +31,41 @@ Scripts and documentation for setting up ROA Oracle Database on Windows servers: 4. Copy `config.example.ps1` to `config.ps1` and edit values 5. Run scripts in order: `01` -> `07` +### Option A: Use Batch Wrappers (Recommended) + +The batch wrappers handle PowerShell execution policy automatically: + +```cmd +# Complete installation (all scripts in order) +RunAll.cmd + +# Or run individual scripts +Run.cmd 01-setup-database.ps1 +Run.cmd 02-create-sys-objects.ps1 +Run.cmd 03-import-contafin.ps1 +Run.cmd 04-create-synonyms-grants.ps1 +Run.cmd 05-import-companies.ps1 +Run.cmd 07-verify-installation.ps1 +``` + +### Option B: PowerShell Direct (requires Bypass) + +If running PowerShell directly, use `-ExecutionPolicy Bypass`: + ```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 +# From PowerShell +powershell -ExecutionPolicy Bypass -File .\scripts\01-setup-database.ps1 +powershell -ExecutionPolicy Bypass -File .\scripts\07-verify-installation.ps1 -Detailed +``` + +### Option C: Set Execution Policy (Admin required) + +```powershell +# Run as Administrator (one-time setup) +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine + +# Then run scripts normally +.\scripts\01-setup-database.ps1 ``` --- @@ -61,6 +88,8 @@ Copy `config.example.ps1` to `config.ps1` and edit: roa-windows-setup/ ├── README.md # This file ├── config.example.ps1 # Configuration template +├── Run.cmd # Script runner (handles ExecutionPolicy) +├── RunAll.cmd # Complete installation runner │ ├── docs/ # Installation guides │ ├── 00-INSTALL-ORACLE-XE.md # Oracle 21c XE installation diff --git a/proxmox/lxc108-oracle/roa-windows-setup/Run.cmd b/proxmox/lxc108-oracle/roa-windows-setup/Run.cmd new file mode 100644 index 0000000..0b47fb9 --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/Run.cmd @@ -0,0 +1,83 @@ +@echo off +REM ============================================================================= +REM ROA Oracle Setup Script Runner +REM ============================================================================= +REM This wrapper runs PowerShell scripts with ExecutionPolicy Bypass +REM Usage: Run.cmd [arguments] +REM Example: Run.cmd 01-setup-database.ps1 +REM Run.cmd 07-verify-installation.ps1 -Detailed +REM ============================================================================= + +setlocal enabledelayedexpansion + +if "%~1"=="" ( + echo. + echo ROA Oracle Setup Script Runner + echo ============================== + echo. + echo Usage: Run.cmd ^ [arguments] + echo. + echo Available scripts: + echo 01-setup-database.ps1 - Initial database setup + echo 02-create-sys-objects.ps1 - Create SYS objects + echo 03-import-contafin.ps1 - Import CONTAFIN_ORACLE schema + echo 04-create-synonyms-grants.ps1 - Create public synonyms and grants + echo 05-import-companies.ps1 - Batch import company schemas + echo 06-add-company.ps1 - Add new company + echo 07-verify-installation.ps1 - Verify installation + echo 99-uninstall-roa.ps1 - Uninstall ROA ^(cleanup^) + echo. + echo Examples: + echo Run.cmd 01-setup-database.ps1 + echo Run.cmd 07-verify-installation.ps1 -Detailed + echo Run.cmd 99-uninstall-roa.ps1 -Force + echo. + exit /b 1 +) + +set SCRIPT=%~1 +shift + +REM Build arguments string +set ARGS= +:argloop +if "%~1"=="" goto endargs +set ARGS=%ARGS% %1 +shift +goto argloop +:endargs + +REM Check if script exists in scripts folder +set SCRIPT_PATH=%~dp0scripts\%SCRIPT% +if not exist "%SCRIPT_PATH%" ( + REM Try in current directory + set SCRIPT_PATH=%~dp0%SCRIPT% +) + +if not exist "%SCRIPT_PATH%" ( + echo ERROR: Script not found: %SCRIPT% + echo Looked in: + echo - %~dp0scripts\%SCRIPT% + echo - %~dp0%SCRIPT% + exit /b 1 +) + +echo. +echo Running: %SCRIPT% %ARGS% +echo ============================================================ +echo. + +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPT_PATH%" %ARGS% + +set EXITCODE=%ERRORLEVEL% + +echo. +echo ============================================================ +if %EXITCODE% EQU 0 ( + echo Script completed successfully. +) else ( + echo Script failed with exit code: %EXITCODE% +) +echo. + +exit /b %EXITCODE% diff --git a/proxmox/lxc108-oracle/roa-windows-setup/RunAll.cmd b/proxmox/lxc108-oracle/roa-windows-setup/RunAll.cmd new file mode 100644 index 0000000..a3ef7de --- /dev/null +++ b/proxmox/lxc108-oracle/roa-windows-setup/RunAll.cmd @@ -0,0 +1,124 @@ +@echo off +REM ============================================================================= +REM ROA Oracle Complete Installation +REM ============================================================================= +REM Runs all setup scripts in order with ExecutionPolicy Bypass +REM ============================================================================= + +setlocal enabledelayedexpansion + +echo. +echo ============================================================ +echo ROA Oracle Complete Installation +echo ============================================================ +echo. +echo This will run all setup scripts in order: +echo 1. 01-setup-database.ps1 +echo 2. 02-create-sys-objects.ps1 +echo 3. 03-import-contafin.ps1 +echo 4. 04-create-synonyms-grants.ps1 +echo 5. 05-import-companies.ps1 +echo 6. 07-verify-installation.ps1 +echo. +echo Prerequisites: +echo - Oracle 21c XE or SE installed and running +echo - DMP files in C:\DMPDIR +echo. + +set /p CONFIRM="Continue with installation? [Y/N]: " +if /i not "%CONFIRM%"=="Y" ( + echo Installation cancelled. + exit /b 0 +) + +echo. +set SCRIPTS_DIR=%~dp0scripts +set ERRORS=0 + +REM Script 1: Setup Database +echo. +echo [1/6] Running 01-setup-database.ps1... +echo ============================================================ +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPTS_DIR%\01-setup-database.ps1" +if %ERRORLEVEL% NEQ 0 ( + echo [FAILED] 01-setup-database.ps1 failed! + set /a ERRORS+=1 + set /p CONTINUE="Continue anyway? [Y/N]: " + if /i not "!CONTINUE!"=="Y" goto :summary +) + +REM Script 2: Create SYS Objects +echo. +echo [2/6] Running 02-create-sys-objects.ps1... +echo ============================================================ +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPTS_DIR%\02-create-sys-objects.ps1" +if %ERRORLEVEL% NEQ 0 ( + echo [FAILED] 02-create-sys-objects.ps1 failed! + set /a ERRORS+=1 + set /p CONTINUE="Continue anyway? [Y/N]: " + if /i not "!CONTINUE!"=="Y" goto :summary +) + +REM Script 3: Import CONTAFIN_ORACLE +echo. +echo [3/6] Running 03-import-contafin.ps1... +echo ============================================================ +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPTS_DIR%\03-import-contafin.ps1" +if %ERRORLEVEL% NEQ 0 ( + echo [FAILED] 03-import-contafin.ps1 failed! + set /a ERRORS+=1 + set /p CONTINUE="Continue anyway? [Y/N]: " + if /i not "!CONTINUE!"=="Y" goto :summary +) + +REM Script 4: Create Synonyms and Grants +echo. +echo [4/6] Running 04-create-synonyms-grants.ps1... +echo ============================================================ +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPTS_DIR%\04-create-synonyms-grants.ps1" +if %ERRORLEVEL% NEQ 0 ( + echo [FAILED] 04-create-synonyms-grants.ps1 failed! + set /a ERRORS+=1 + set /p CONTINUE="Continue anyway? [Y/N]: " + if /i not "!CONTINUE!"=="Y" goto :summary +) + +REM Script 5: Import Companies +echo. +echo [5/6] Running 05-import-companies.ps1... +echo ============================================================ +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPTS_DIR%\05-import-companies.ps1" +if %ERRORLEVEL% NEQ 0 ( + echo [FAILED] 05-import-companies.ps1 failed! + set /a ERRORS+=1 + set /p CONTINUE="Continue anyway? [Y/N]: " + if /i not "!CONTINUE!"=="Y" goto :summary +) + +REM Script 6: Verify Installation +echo. +echo [6/6] Running 07-verify-installation.ps1... +echo ============================================================ +powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPTS_DIR%\07-verify-installation.ps1" +if %ERRORLEVEL% NEQ 0 ( + echo [WARNING] Verification reported issues. + set /a ERRORS+=1 +) + +:summary +echo. +echo ============================================================ +echo Installation Summary +echo ============================================================ +echo. +if %ERRORS% EQU 0 ( + echo [SUCCESS] All scripts completed successfully! +) else ( + echo [WARNING] Installation completed with %ERRORS% error(s). + echo Review logs in the logs\ folder for details. +) +echo. +echo Logs are saved in: %~dp0logs\ +echo. + +exit /b %ERRORS% 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 index 4dbd81d..8d15e1c 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/scripts/03-import-contafin.ps1 +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/03-import-contafin.ps1 @@ -66,7 +66,7 @@ param( [string]$TableExistsAction = "REPLACE", [Parameter(Mandatory = $false)] - [int]$Parallel = 2 + [int]$Parallel = 1 ) $ErrorActionPreference = 'Stop' @@ -117,7 +117,11 @@ try { $dumpFileName = Split-Path -Path $DumpFile -Leaf $targetDumpPath = Join-Path $DmpDir $dumpFileName - if ($DumpFile -ne $targetDumpPath) { + # Resolve paths for accurate comparison (handles casing and path format differences) + $resolvedSource = (Resolve-Path -Path $DumpFile -ErrorAction SilentlyContinue).Path + $resolvedTarget = if (Test-Path $targetDumpPath) { (Resolve-Path -Path $targetDumpPath).Path } else { $null } + + if ($resolvedSource -ne $resolvedTarget) { Write-Log "Copying dump file to DMPDIR..." Copy-Item -Path $DumpFile -Destination $targetDumpPath -Force Write-LogSuccess "Dump file copied to: $targetDumpPath" @@ -149,8 +153,12 @@ try { $importLogFile = "CONTAFIN_ORACLE_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" - # Build impdp command - $connString = "SYSTEM/`"$SystemPassword`"@$ServiceName" + # Get listener host for connection (handles listener bound to specific IP) + $dbHost = Get-ListenerHost -OracleHome $oraHome + $dbPort = 1521 + + # Build impdp command with EZConnect format + $connString = "SYSTEM/`"$SystemPassword`"@${dbHost}:${dbPort}/${ServiceName}" $impdpParams = @( "`"$connString`"", @@ -158,13 +166,10 @@ try { "dumpfile=$dumpFileName", "logfile=$importLogFile", "schemas=CONTAFIN_ORACLE", - "table_exists_action=$TableExistsAction" + "table_exists_action=$TableExistsAction", + "parallel=$Parallel" # Always specify to override DMP metadata (XE requires parallel=1) ) - if ($Parallel -gt 1) { - $impdpParams += "parallel=$Parallel" - } - $arguments = $impdpParams -join " " Write-Log "Executing impdp..." 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 index 06c4248..88f4273 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/scripts/05-import-companies.ps1 +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/05-import-companies.ps1 @@ -308,7 +308,9 @@ EXIT; $impdpPath = Join-Path $oraHome "bin\impdp.exe" $importLogFile = "$($item.Schema)_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" - $connString = "SYSTEM/`"$SystemPassword`"@$ServiceName" + # Use EZConnect format for impdp (handles listener bound to specific IP) + $dbHost = Get-ListenerHost -OracleHome $oraHome + $connString = "SYSTEM/`"$SystemPassword`"@${dbHost}:1521/$ServiceName" # Check if dump has different schema name (remapping needed) $remapParam = "" @@ -324,7 +326,8 @@ EXIT; "dumpfile=$dumpFileName", "logfile=$importLogFile", "schemas=$($item.Schema)", - "table_exists_action=REPLACE" + "table_exists_action=REPLACE", + "parallel=1" # Required for Oracle XE ) if ($remapParam) { diff --git a/proxmox/lxc108-oracle/roa-windows-setup/scripts/99-uninstall-roa.ps1 b/proxmox/lxc108-oracle/roa-windows-setup/scripts/99-uninstall-roa.ps1 index c7864c4..26ed140 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/scripts/99-uninstall-roa.ps1 +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/99-uninstall-roa.ps1 @@ -6,16 +6,24 @@ # Usage: # .\99-uninstall-roa.ps1 -SystemPassword "yourpassword" # .\99-uninstall-roa.ps1 -SystemPassword "yourpassword" -Force +# .\99-uninstall-roa.ps1 -ServiceName "XEPDB1" -SystemPassword "yourpassword" -Force # # Parameters: -# -SystemPassword : SYS password for database connection +# -SystemPassword : SYS password for database connection (default: romfastsoft) +# -ServiceName : Oracle service name (auto-detected if not specified) # -Force : Skip confirmation prompt # # ============================================================================ param( [Parameter(Mandatory=$false)] - [string]$SystemPassword, + [string]$OracleHome, + + [Parameter(Mandatory=$false)] + [string]$ServiceName, + + [Parameter(Mandatory=$false)] + [string]$SystemPassword = "romfastsoft", [Parameter(Mandatory=$false)] [switch]$Force @@ -30,13 +38,14 @@ $ErrorActionPreference = "Stop" $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $RootDir = Split-Path -Parent $ScriptDir -# Load config +# Load config (optional - script can work with auto-detection) $ConfigFile = Join-Path $RootDir "config.ps1" if (Test-Path $ConfigFile) { . $ConfigFile -} else { - Write-Host "ERROR: config.ps1 not found. Copy config.example.ps1 to config.ps1" -ForegroundColor Red - exit 1 + # Use config values if parameters not provided + if (-not $OracleHome -and $ORACLE_HOME) { $OracleHome = $ORACLE_HOME } + if (-not $ServiceName -and $SERVICE_NAME) { $ServiceName = $SERVICE_NAME } + if ($SystemPassword -eq "romfastsoft" -and $SYSTEM_PASSWORD) { $SystemPassword = $SYSTEM_PASSWORD } } # Load libraries @@ -53,20 +62,25 @@ Write-Host " ROA UNINSTALL - REMOVING ALL ROA OBJECTS" -ForegroundColor Cy Write-Host "============================================================" -ForegroundColor Cyan Write-Host "" -# Get password if not provided -if (-not $SystemPassword) { - $SecurePassword = Read-Host "Enter SYS password" -AsSecureString - $SystemPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto( - [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword) - ) +# Get Oracle Home +$oraHome = Get-OracleHome -OracleHome $OracleHome +Write-Host "[INFO] Oracle Home: $oraHome" -ForegroundColor Green + +# Get listener host +$OracleHost = Get-ListenerHost -OracleHome $oraHome +Write-Host "[INFO] Database Host: $OracleHost" -ForegroundColor Green + +# Auto-detect service name if not specified +if (-not $ServiceName) { + $ServiceName = "XEPDB1" # Default for Oracle XE } +Write-Host "[INFO] Service Name: $ServiceName" -ForegroundColor Green # Build connection string -$OracleService = if ($Config.OracleService) { $Config.OracleService } else { "XEPDB1" } -$OracleHost = if ($Config.OracleHost) { $Config.OracleHost } else { "localhost" } -$OraclePort = if ($Config.OraclePort) { $Config.OraclePort } else { 1521 } -$ConnString = "${OracleHost}:${OraclePort}/${OracleService}" +$OraclePort = 1521 +$ConnString = "${OracleHost}:${OraclePort}/${ServiceName}" +Write-Host "" Write-Host "Target database: $ConnString" -ForegroundColor Yellow Write-Host "" @@ -95,9 +109,9 @@ Write-Host "Starting uninstall..." -ForegroundColor Cyan Write-Host "" # Find sqlplus -$SqlPlus = Get-SqlPlusPath -if (-not $SqlPlus) { - Write-Host "ERROR: sqlplus.exe not found" -ForegroundColor Red +$SqlPlus = Join-Path $oraHome "bin\sqlplus.exe" +if (-not (Test-Path $SqlPlus)) { + Write-Host "ERROR: sqlplus.exe not found at $SqlPlus" -ForegroundColor Red exit 1 } @@ -110,27 +124,36 @@ if (-not (Test-Path $SqlScript)) { } Write-Host "Running uninstall script..." -ForegroundColor Cyan +Write-Host "" -$SqlInput = @" -@"$SqlScript" -EXIT -"@ +# Set Oracle environment +$env:ORACLE_HOME = $oraHome +$env:PATH = "$oraHome\bin;$env:PATH" +$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" -$process = Start-Process -FilePath $SqlPlus ` - -ArgumentList "sys/${SystemPassword}@${ConnString} as sysdba" ` - -NoNewWindow -Wait -PassThru ` - -RedirectStandardInput (New-TemporaryFile | ForEach-Object { - $SqlInput | Set-Content $_.FullName - $_.FullName - }) - -# Alternative: run directly -& $SqlPlus "sys/${SystemPassword}@${ConnString} as sysdba" "@$SqlScript" +# Execute uninstall SQL script +try { + & $SqlPlus "sys/${SystemPassword}@${ConnString} as sysdba" "@$SqlScript" + $exitCode = $LASTEXITCODE +} +catch { + Write-Host "ERROR: Failed to execute uninstall script: $_" -ForegroundColor Red + exit 1 +} Write-Host "" -Write-Host "============================================================" -ForegroundColor Green -Write-Host " ROA UNINSTALL COMPLETE" -ForegroundColor Green -Write-Host "============================================================" -ForegroundColor Green -Write-Host "" -Write-Host "Database is now clean. You can re-run the setup scripts." -ForegroundColor Cyan +if ($exitCode -eq 0) { + Write-Host "============================================================" -ForegroundColor Green + Write-Host " ROA UNINSTALL COMPLETE" -ForegroundColor Green + Write-Host "============================================================" -ForegroundColor Green + Write-Host "" + Write-Host "Database is now clean. You can re-run the setup scripts." -ForegroundColor Cyan +} +else { + Write-Host "============================================================" -ForegroundColor Yellow + Write-Host " ROA UNINSTALL COMPLETED WITH WARNINGS" -ForegroundColor Yellow + Write-Host "============================================================" -ForegroundColor Yellow + Write-Host "" + Write-Host "Some objects may not have been removed. Review output above." -ForegroundColor Yellow +} Write-Host "" 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 index 34da2f5..3168f27 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/logging-functions.ps1 +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/logging-functions.ps1 @@ -90,8 +90,9 @@ function Initialize-LogFile { function Write-Log { [CmdletBinding()] param( - [Parameter(Mandatory = $true, Position = 0)] - [string]$Message, + [Parameter(Mandatory = $false, Position = 0)] + [AllowEmptyString()] + [string]$Message = "", [Parameter(Mandatory = $false)] [ValidateSet('Info', 'Warning', 'Error', 'Success', 'Debug')] @@ -101,6 +102,17 @@ function Write-Log { [switch]$NoConsole ) + # Handle empty messages (blank lines) + if ([string]::IsNullOrEmpty($Message)) { + if ($script:LogFile) { + Add-Content -Path $script:LogFile -Value "" -Encoding UTF8 + } + if (-not $NoConsole) { + Write-Host "" + } + return + } + $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' $logMessage = "[$timestamp] [$Level] $Message" 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 index de1e25b..a6cc1f8 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/oracle-functions.ps1 +++ b/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/oracle-functions.ps1 @@ -17,6 +17,82 @@ # Source logging functions . "$PSScriptRoot\logging-functions.ps1" +<# +.SYNOPSIS + Get the listener host address. + +.DESCRIPTION + Auto-detects the host address from listener configuration. + Returns the IP address the listener is bound to. + +.PARAMETER OracleHome + Oracle Home directory. + +.OUTPUTS + String. The host address (IP or hostname). + +.EXAMPLE + $host = Get-ListenerHost -OracleHome "C:\app\oracle\product\21c\dbhomeXE" +#> +function Get-ListenerHost { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string]$OracleHome + ) + + $oraHome = Get-OracleHome -OracleHome $OracleHome + $lsnrctl = Join-Path $oraHome "bin\lsnrctl.exe" + + if (-not (Test-Path $lsnrctl)) { + return "localhost" + } + + try { + # Set Oracle environment + $env:ORACLE_HOME = $oraHome + $env:PATH = "$oraHome\bin;$env:PATH" + + $output = & $lsnrctl status 2>&1 | Out-String + + # Parse HOST from listener output - look for TCP endpoint (not TCPS) + # Format: (PROTOCOL=tcp)(HOST=10.0.20.130)(PORT=1521) + # Use simple IP pattern to avoid regex escaping issues + $tcpMatch = [regex]::Match($output, "PROTOCOL=tcp\).*?HOST=([0-9\.]+)") + if ($tcpMatch.Success) { + $listenerHost = $tcpMatch.Groups[1].Value + + # If listener is bound to 0.0.0.0, try to get actual IP + if ($listenerHost -eq "0.0.0.0") { + $ip = (Get-NetIPAddress -AddressFamily IPv4 | + Where-Object { $_.IPAddress -notmatch "^127\." -and $_.PrefixOrigin -ne "WellKnown" } | + Select-Object -First 1).IPAddress + if ($ip) { return $ip } + return "localhost" + } + + # If it's a specific IP (not localhost), return it + if ($listenerHost -notmatch "^127\." -and $listenerHost -ne "localhost") { + return $listenerHost + } + } + + # Fallback: try any HOST= pattern + $anyHostMatch = [regex]::Match($output, "HOST=([0-9\.]+)") + if ($anyHostMatch.Success) { + $listenerHost = $anyHostMatch.Groups[1].Value + if ($listenerHost -notmatch "^127\." -and $listenerHost -ne "0.0.0.0") { + return $listenerHost + } + } + + return "localhost" + } + catch { + return "localhost" + } +} + <# .SYNOPSIS Find Oracle Home directory. @@ -489,14 +565,15 @@ function Invoke-SqlPlus { throw "SQL*Plus not found at: $sqlplus" } - # Build connection string (EZConnect format if DbHost is provided) - $sysdba = if ($AsSysdba) { " as sysdba" } else { "" } - if ($DbHost) { - $connString = "$Username/`"$Password`"@${DbHost}:${Port}/${ServiceName}$sysdba" - } else { - $connString = "$Username/`"$Password`"@$ServiceName$sysdba" + # Auto-detect host from listener if not provided + if (-not $DbHost) { + $DbHost = Get-ListenerHost -OracleHome $oraHome } + # Build connection string (always use EZConnect format for reliability) + $sysdba = if ($AsSysdba) { " as sysdba" } else { "" } + $connString = "$Username/`"$Password`"@${DbHost}:${Port}/${ServiceName}$sysdba" + $tempFile = $null try { @@ -973,14 +1050,21 @@ SELECT 'INVALID:' || COUNT(*) FROM dba_objects WHERE owner = UPPER('$SchemaName' EXIT; "@ - $result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName ` + $oraHome = Get-OracleHome -OracleHome $OracleHome + + $result = Invoke-SqlPlus -OracleHome $oraHome -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] + # Parse result lines for object type counts + $lines = $result -split "`r?`n" + foreach ($line in $lines) { + $trimmed = $line.Trim() + if ($trimmed.Length -gt 0 -and $trimmed -match "^([A-Z][A-Z_ ]*):(\d+)$") { + $key = $Matches[1].Trim() + $value = [int]$Matches[2] + $counts[$key] = $value } } diff --git a/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql b/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql index a07633b..8578714 100644 --- a/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql +++ b/proxmox/lxc108-oracle/roa-windows-setup/sql/grants-public.sql @@ -386,6 +386,78 @@ SELECT grantee, table_name, privilege FROM dba_tab_privs WHERE table_name = 'DMPDIR'; +-- ============================================================================ +-- SECTION 10: GRANTS ON UNDERLYING TABLES FOR SYS OBJECTS +-- ============================================================================ +-- SYS.AUTH_PACK needs direct access to CONTAFIN_ORACLE tables through synonyms +-- These grants ensure SYS-owned objects can resolve synonym references + +PROMPT [10/11] Granting table access for SYS objects... + +-- Tables accessed by SYS.AUTH_PACK +GRANT SELECT ON CONTAFIN_ORACLE.NOM_PROGRAME TO PUBLIC; +GRANT SELECT ON CONTAFIN_ORACLE.DEF_PROGRAME TO PUBLIC; +GRANT SELECT ON CONTAFIN_ORACLE.AUTH_SERII TO PUBLIC; +GRANT SELECT ON CONTAFIN_ORACLE.AUTH_DETALII TO PUBLIC; + +-- Tables accessed by VAUTH_SERII view +GRANT SELECT ON CONTAFIN_ORACLE.VDEF_PROGRAME TO PUBLIC; + +-- ============================================================================ +-- SECTION 11: RECOMPILE SYS AND CONTAFIN_ORACLE OBJECTS +-- ============================================================================ + +PROMPT [11/11] Recompiling SYS and CONTAFIN_ORACLE objects... + +-- Recompile SYS.AUTH_PACK (depends on synonyms now available) +ALTER PACKAGE SYS.AUTH_PACK COMPILE; +ALTER PACKAGE SYS.AUTH_PACK COMPILE BODY; + +-- Grant EXECUTE on SYS.AUTH_PACK so CONTAFIN_ORACLE.PACK_DREPTURI can call it +-- through the PACK_AUTENTIFICARE synonym +GRANT EXECUTE ON SYS.AUTH_PACK TO PUBLIC; + +-- Recreate VAUTH_SERII view (may have been invalid due to missing synonym) +-- This view uses SYN_NOM_PROGRAME for program names and AUTH_PACK functions for license info +BEGIN + EXECUTE IMMEDIATE ' + 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'; + DBMS_OUTPUT.PUT_LINE(' View VAUTH_SERII created/replaced.'); +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE(' Warning: Could not create VAUTH_SERII: ' || SQLERRM); +END; +/ + +GRANT SELECT ON SYS.VAUTH_SERII TO PUBLIC; + +-- Recompile CONTAFIN_ORACLE invalid objects +PROMPT Recompiling CONTAFIN_ORACLE schema... +BEGIN + DBMS_UTILITY.COMPILE_SCHEMA(schema => 'CONTAFIN_ORACLE', compile_all => FALSE); +END; +/ + +-- Show remaining invalid objects +PROMPT +PROMPT Remaining invalid objects (excluding email procedures): +SELECT owner, object_name, object_type +FROM dba_objects +WHERE owner IN ('SYS', 'CONTAFIN_ORACLE') + AND status = 'INVALID' + AND object_type NOT IN ('SYNONYM') + AND object_name NOT IN ('SENDEMAIL', 'EMAILINCASARI', 'EMAILNOTIFICAREFACTURI', 'EMAILSTOCCRITIC') +ORDER BY owner, object_type, object_name; + PROMPT PROMPT ======================================== PROMPT Grant Configuration Complete