CMM/DODA: fix DODA paths + CyberArk EPM policy doc
- 09-Setup-CMM.ps1: Step 2.5 ACL list targeted C:\Program Files\DODA (a path that never exists), so the BUILTIN\Users write grant on DODA was silently skipped. Corrected to C:\Apps\DODA, where Install-DODA.ps1 actually extracts. - Install-DODA.ps1: create C:\Apps\DODA\PreProcess after extract. The DODA zip unpacks flat without it; MergeFiles.exe expects it and crashed with DirectoryNotFoundException (MergeFiles.GetDoDAFolder) when absent. - docs/cyberark-cmm-doda-policy.md: EPM admin reference for elevating the CMM report toolchain. CyberArk EPM elevation is per-process and not inherited, so the external tools PC-DMIS spawns (MergeFiles/PCDToIGES/RotateProbeVector/ DovetailAnalysis) run un-elevated and fail. Doc gives the Application Group (by SHA-256), the Elevate policy, scope, verify steps, and the CREATE_PDF_FROM_RTF.BAS rework that drops Word/Reader from the elevation set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
144
docs/cyberark-cmm-doda-policy.md
Normal file
144
docs/cyberark-cmm-doda-policy.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# CyberArk EPM - CMM / DODA elevation policy
|
||||
|
||||
Reference for the CyberArk EPM admin. Fixes the "PC-DMIS is elevated but the
|
||||
tools it calls error that they are not running elevated" problem on CMM bays.
|
||||
|
||||
## Problem (root cause)
|
||||
|
||||
CyberArk EPM elevation is per-process and is NOT inherited by child processes.
|
||||
The existing policy elevates PC-DMIS (`PCDLRN.exe`), but the external `.exe`
|
||||
files the PC-DMIS routine spawns (report, geometry, and DODA tools) launch with
|
||||
the standard user token (Medium integrity) and fail their own "must run
|
||||
elevated" check, even though the parent PC-DMIS is elevated. The elevation dies
|
||||
at the process boundary.
|
||||
|
||||
## Flow that breaks
|
||||
|
||||
The PC-DMIS routine drives in-process `.BAS` scripts that shell out to separate
|
||||
executables:
|
||||
|
||||
| Step | Process | Separate process? |
|
||||
|------|---------|-------------------|
|
||||
| Merge / sort report results | `MergeFiles.exe` (.NET), reads `C:\Apps\DODA\PreProcess\` | yes |
|
||||
| Geometry export | `PCDToIGES.exe`, `RotateProbeVector.exe` | yes |
|
||||
| DODA calculation | `DovetailAnalysis.exe` (+ embedded JVM and python) | yes |
|
||||
| RTF -> PDF, display | `winword.exe`, `AcroRd32.exe` | yes (removed by the BAS rework below) |
|
||||
| Folder create / save | `MAKEDIR.BAS`, `MAKEFOLDER.bas`, `SaveAsFolder.bas` | no (in-process, uses PC-DMIS token) |
|
||||
|
||||
The in-process file operations inherit PC-DMIS's elevated token. The separate
|
||||
`.exe` files do not. Those are what get blocked.
|
||||
|
||||
## Fix: one Application Group + one Elevate policy
|
||||
|
||||
Do NOT use "elevate all child processes of PC-DMIS". That would elevate
|
||||
`cmd.exe` and anything PC-DMIS launches, which is a large hole on a locked-down
|
||||
shopfloor PC. Elevate only the named toolchain.
|
||||
|
||||
### Application Group: CMM-DODA-Tools
|
||||
|
||||
These are in-house, unsigned tools, so match by SHA-256 (or by path + filename
|
||||
if the install directory is admin-write-only and the confirmed path is known).
|
||||
|
||||
| App | SHA-256 | Spawns children? |
|
||||
|-----|---------|------------------|
|
||||
| `MergeFiles.exe` | `e58ce7599d3bdba816c7ecb183d4f52b32ad8be0b8e4f41813824d8eb472d723` | no |
|
||||
| `PCDToIGES.exe` | `7bdc961c406f7a0f6f8a10752988a17504bdfd691469c08d20f0d5b6673974cf` | no |
|
||||
| `RotateProbeVector.exe` | `f8a1b5b0025769fe0d28dc12826ef5d1fbcdba3b29383799c1eb04b955abebdc` | no |
|
||||
| `DovetailAnalysis.exe` | `86dcb0898bdef4687427ce339520a9c9f5a582890c2241d784fa985019eaaec1` | yes (JVM + python) |
|
||||
|
||||
### Elevate policy
|
||||
|
||||
- Target: the `CMM-DODA-Tools` Application Group
|
||||
- Action: Elevate (run with administrator rights)
|
||||
- Applies to: the CMM computer set + the `ShopFloor` user
|
||||
- Child processes: elevate ONLY for `DovetailAnalysis.exe` (it launches the
|
||||
embedded JVM and python scripts that do the actual file work). The other
|
||||
three have no children.
|
||||
- Match basis: SHA-256 hash
|
||||
|
||||
## Explicitly NOT in the policy
|
||||
|
||||
`winword.exe`, `AcroRd32.exe`, `cmd.exe`. The `CREATE_PDF_FROM_RTF.BAS` rework
|
||||
(Word writes the PDF to user `%TEMP%`, PC-DMIS moves it to the final path with
|
||||
its own elevated in-process token, display via the default PDF handler) removes
|
||||
their need for elevation. Keep Office and Reader out of the elevation set.
|
||||
|
||||
## What the EPM admin needs from GE
|
||||
|
||||
- The computer group = the CMM bays (hostname list, OU, or AD group)
|
||||
- The user = `ShopFloor` (local account)
|
||||
- If using path matching instead of hash: the confirmed install directory of the
|
||||
four exes on a bay (`where MergeFiles.exe`)
|
||||
|
||||
## Verify
|
||||
|
||||
- Before: from elevated PC-DMIS, spawn a child `cmd.exe`, then run
|
||||
`whoami /groups | findstr Label`. Medium Mandatory Level confirms children are
|
||||
not elevated (the bug).
|
||||
- After: the four tools run at High Mandatory Level; report generation plus
|
||||
copy/move/delete to C: and S: succeed; no "not elevated" error.
|
||||
|
||||
## Caveats
|
||||
|
||||
- Hash churn: rebuilding a tool changes its hash, so the Application Group hash
|
||||
must be re-stamped. Path + filename matching avoids this IF the install
|
||||
directory is admin-write-only (so a same-named spoof cannot be dropped there).
|
||||
- Not an ACL fix: the tools hard-check elevation and bail before touching the
|
||||
filesystem, so pre-granting NTFS ACLs alone will not unblock them. The EPM
|
||||
elevation is the actual lever.
|
||||
- Scope tight: match by hash and scope to the CMM computer group + ShopFloor so
|
||||
this elevation never applies fleet-wide.
|
||||
|
||||
## Related code fixes (PXE imaging side)
|
||||
|
||||
- `09-Setup-CMM.ps1` Step 2.5 ACL list corrected from `C:\Program Files\DODA`
|
||||
(nonexistent) to `C:\Apps\DODA` (where `Install-DODA.ps1` actually extracts).
|
||||
- `MergeFiles.exe` expects `C:\Apps\DODA\PreProcess\`, which the DODA zip does
|
||||
not create (it extracts flat). A missing `PreProcess` directory is the likely
|
||||
cause of the historical `MergeFiles.GetDoDAFolder` `DirectoryNotFoundException`
|
||||
crash (see `cmm-utilities` repo `dotNET event.txt`). Have `Install-DODA.ps1`
|
||||
create the `PreProcess` subdir, or have whoever deploys the toolchain own it.
|
||||
- The CMM tool chain (`MergeFiles.exe`, `PCDToIGES.exe`, `RotateProbeVector.exe`,
|
||||
the `.BAS` scripts) lives in the separate `cmm-utilities` repo and is NOT
|
||||
deployed by PXE imaging today. Decide whether imaging should own it so the
|
||||
install path, ACLs, and `PreProcess` directory are consistent.
|
||||
|
||||
## CREATE_PDF_FROM_RTF.BAS rework (removes Word/Reader from the elevation set)
|
||||
|
||||
```vb
|
||||
' CREATE_PDF_FROM_RTF.BAS - rev 1.0: convert in user temp, then move with
|
||||
' PC-DMIS's own token; display via default handler (no elevation needed).
|
||||
Sub Main(filename As String, displayReport As String)
|
||||
Dim rtfFile As String, finalPdf As String, tempPdf As String
|
||||
rtfFile = filename & ".RTF"
|
||||
finalPdf = filename & ".PDF"
|
||||
Dim base As String
|
||||
base = Mid(filename, InStrRev(filename, "\") + 1)
|
||||
tempPdf = Environ$("TEMP") & "\" & base & ".PDF"
|
||||
|
||||
' Word (un-elevated COM) can write to %TEMP% - a user-writable path.
|
||||
Dim word As Object
|
||||
Set word = CreateObject("word.application")
|
||||
word.Visible = False
|
||||
word.Documents.Open rtfFile
|
||||
word.ActiveDocument.SaveAs2 tempPdf, 17 ' 17 = wdFormatPDF
|
||||
word.Quit
|
||||
Set word = Nothing
|
||||
|
||||
' Move temp -> final using PC-DMIS's in-process token (elevated via
|
||||
' CyberArk), so the protected/S: destination is written without needing
|
||||
' Word itself elevated. FileCopy works across volumes; Name does not.
|
||||
If Dir(finalPdf) <> "" Then Kill finalPdf
|
||||
FileCopy tempPdf, finalPdf
|
||||
Kill tempPdf
|
||||
|
||||
' Display via the default PDF handler in the user's own context.
|
||||
If UCase(displayReport) = "TRUE" Then
|
||||
Dim sh As Object
|
||||
Set sh = CreateObject("Shell.Application")
|
||||
sh.ShellExecute finalPdf, "", "", "open", 1
|
||||
End If
|
||||
|
||||
Kill rtfFile
|
||||
End Sub
|
||||
```
|
||||
@@ -180,7 +180,7 @@ $pcdmisDirs = @(
|
||||
'C:\Program Files\Hexagon\PC-DMIS 2026.1 64-bit',
|
||||
'C:\ProgramData\Hexagon',
|
||||
'C:\Program Files (x86)\General Electric\goCMM',
|
||||
'C:\Program Files\DODA'
|
||||
'C:\Apps\DODA'
|
||||
)
|
||||
foreach ($dir in $pcdmisDirs) {
|
||||
if (-not (Test-Path -LiteralPath $dir)) {
|
||||
|
||||
@@ -29,6 +29,16 @@ try {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# MergeFiles.exe (cmm-utilities toolchain) reads C:\Apps\DODA\PreProcess\ as
|
||||
# its working dir. The DODA zip extracts flat without it, so create it here -
|
||||
# a missing PreProcess dir is the known cause of MergeFiles.GetDoDAFolder
|
||||
# throwing DirectoryNotFoundException (see cmm-utilities dotNET event.txt).
|
||||
$preProcess = Join-Path $installDir 'PreProcess'
|
||||
if (-not (Test-Path $preProcess)) {
|
||||
New-Item -Path $preProcess -ItemType Directory -Force | Out-Null
|
||||
Write-Host "Created $preProcess"
|
||||
}
|
||||
|
||||
if (Test-Path (Join-Path $installDir 'DovetailAnalysis.exe')) {
|
||||
Write-Host "DovetailAnalysis.exe verified present"
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user