Tempo fa il supporto di primo livello ha ricevuto diverse chiamate d’assistenza per un problema dovuto a delle stampanti HP portatili (che usiamo per personale sul campo) che a causa di un aggiornamento driver di HP avevano problemi che si risolvevano solo a colpi di riavvio spooler di stampa di Windows, con tanto di lamentele trovate in giro per la rete e promesse di aggiornamento da parte del vendor. Dovendo però trovare un rimedio “casalingo” (si fa per dire) nel frattempo, si è optato per la modifica dei permessi utente (non amministratori di macchina) per consentire il riavvio del servizio di spooler anche senza interpellare il supporto di primo livello, è così che è nata UserSpoolerRestart.
Userche?
Un’utilità che svolge un lavoro banale: modificare i permessi utente affinché questi possano riavviare lo spooler di stampa. Per lanciarla necessiterà certamente di un amministratore ma si può facilmente distribuirla tramite GPO o sistema di software inventory / management (io ho usato Quest Kace). Doppio clic, l’applicazione modifica il comportamento del sistema e inserisce sul Desktop degli utenti (quello Pubblico, visibile quindi da tutti gli utenti configurati sul sistema) un link a un banale batch che consentirà di riavviare il servizio spooler ogni volta sarà necessario. Lo stesso collegamento sarà disponibile nel menu Start di Windows.
Testata con successo su Windows 10 e 11, ho voluto rilasciare il suo codice sorgente e l’eseguibile compilato su GitHub, all’indirizzo github.com/Run-NSIS/UserSpoolerRestart.
Sotto al cofano
Nulla da nascondere, il codice parla chiaro ed è leggibile anche da chi non mastica abitualmente NSIS (con un pizzico di batch e PowerShell). Mi sono basato molto su quanto riportato su superuser.com/a/1689265 e winhelponline.com/blog/view-edit-service-permissions-windows (oltre alla documentazione ufficiale di Microsoft, learn.microsoft.com/en-us/windows/win32/services/service-security-and-access-right e learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings), queste fonti mi hanno permesso di comprendere al meglio tutto il giro del fumo che devo aspettarmi dal sistema di casa Microsoft riguardo le autorizzazioni dell’utente, del sistema, dell’amministratore, ecc. per ciò che concerne la possibilità di lasciare a una o più di queste parti libero arbitrio per il riavvio di uno o più servizi della macchina in uso.
Le sigle che andrò a riportare e utilizzare qui di seguito nell’articolo faranno perciò riferimento alle tabelle che ho caricato nel file readme del progetto, parti da qui: github.com/Run-NSIS/UserSpoolerRestart/#security-principal.
I permessi di ciascun servizio (in blocco unico e apparentemente illeggibile) si ottengono semplicemente lanciando da prompt dei comandi un sc sdshow spooler
(dove spooler
può essere genericamente modificato con qualsiasi altro servizio attivo sulla macchina, ma non è questo il caso che descrivo oggi):
D:(A;;CCLCSWLOCRRC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWRPWPDTLOCRRC;;;SY)
Questa stringa costituisce a oggi il set di permessi relativi al servizio spooler della mia macchina di lavoro. Isolando la parentesi che include al suo interno “AU” (quindi Authenticated Users) in coda si scopre che l’accesso è consentito (A, vedi github.com/Run-NSIS/UserSpoolerRestart/#security-descriptors-meaning) per effettuare SERVICE_QUERY_CONFIG (CC), SERVICE_QUERY_STATUS (LC), SERVICE_ENUMERATE_DEPENDENTS (SW), SERVICE_INTERROGATE (LO), SERVICE_USER_DEFINED_CONTROL (CR) e READ_CONTROL (RC). Unendo le varie sigle si ottiene per l’appunto CCLCSWLOCRRC
. Cosa manca all’appello? Semplice: RPWPDT
, ovvero SERVICE_START (RP), SERVICE_STOP (WP) e SERVICE_PAUSE_CONTINUE (DT), anche se quest’ultimo volendo è “di più” rispetto al permettere stop e start del servizio di stampa.
Per intervenire quindi c’è bisogno di prendere il set di permessi dell’utente autenticato e renderlo più completo.
Per questo motivo NSIS rileverà l’attuale set e lo darà in pasto a uno script PowerShell che si occuperà di spezzarlo in più parti ogni volta che incontrerà una parentesi tonda chiusa, per poi effettuare un nuovo spezzettamento ogni volta che troverà un punto e virgola nel blocco, isolando infine solo il blocco che termina con AU, permettendo di mettere mano sui singoli pezzetti e accodare solo se necessario il set aggiuntivo di permessi:github.com/Run-NSIS/UserSpoolerRestart/blob/main/Include/Split.ps1
Param( [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)][string] $ACL ) $Split = $($ACL) -Split '(?=\))' for($i = 0; $i -lt ($Split.Count -1); $i++) { if ($Split[$i].EndsWith('AU')) { $SplitACL = $Split[$i] -Split '(?=\;)' if ($SplitACL[2].EndsWith('RPWPDT')) { $AU_ACLMod = $SplitACL[2] } else { $AU_ACLMod = $SplitACL[2] + "RPWPDT" } $AUMod = $SplitACL[0] + $SplitACL[1] + $AU_ACLMod + $SplitACL[3] + $SplitACL[4] + $SplitACL[5] #Write-Host $AUMod -NoNewLine $Output = $Output + $AUMod } else { #Write-Host $Split[$i] -NoNewLine $Output = $Output + $Split[$i] } } #Write-Host ")" $Output = $Output + ")" echo $Output
Al termine dell’esecuzione, lo script PowerShell ricomporrà tutto come inizialmente ricevuto e restituirà come risultato il nuovo blocco permessi completo delle modifiche passandolo al codice NSIS. Sarà lui a occuparsi di lanciare il comando che andrà a sovrascrivere i permessi vecchi con i nuovi, il tutto grazie a un semplice sc sdset spooler
seguito dalla stringa permessi completa.
Ora che l’utente ha poteri nuovi sul servizio di stampa non resta che completare l’opera con gli accessori.
A corredo
A corredo c’è tutto quello che non ho voluto dare in pasto semplicemente allo script di PowerShell (perché avrei potuto gestire tutto con quello e fregarmene del resto) ma che reputo possa essere interessante e utile per l’utilizzatore.
NSIS mi ha permesso di creare un pacchetto eseguibile che in un percorso unico si occupa di:
- verificare che il servizio di stampa esista e sia avviato prima di effettuare ogni modifica.
- Effettuare un backup su file dei permessi attualmente trovati sul servizio.
- Depositare sul Desktop di tutti gli utenti (e anche nel menu di Start) un’icona che richiamerà uno stupidissimo ma efficace script batch che riavvia lo spooler in caso di necessità.
- Prevedere che in fase di disinstallazione dell’utilità (che installandosi e creando una chiave di registro dedicata potrà facilmente essere rilevata dai sistemi di inventario / distribuzione software, altra aspetto da non sottovalutare soprattutto in ambiente gestito) questa vada a ripristinare tutto alla situazione precedente la modifica, rimuovendo di fatto i permessi dati in più all’utente.
Punto extra va dedicato anche al servizio LPDSVC che se presente e avviato sulla macchina, si allaccerà a quello di spooler come dipendenza, per questo motivo il codice NSIS effettuerà le medesime modifiche anche su questo servizio nel caso in cui dovesse incontrarlo sul percorso.
Su GitHub ho caricato il pacchetto eseguibile già compilato per chi vuole avere vita facile o semplicemente non vuole installare NSIS sul sistema per compilarsi da solo il tutto. Troverai la versione sempre più aggiornata all’indirizzo github.com/Run-NSIS/UserSpoolerRestart/releases/latest. Ho testato con successo l’eseguibile su Windows 10 e 11 Pro. Non ho riscontro per altre configurazioni ma sarei felice se volessi darmene tu commentando l’articolo poco più sotto.
In caso di problemi non esitare ad aprire una segnalazione su GitHub.
#StaySafe
Immagine di copertina Lucas Kapla on Unsplash
L'articolo potrebbe non essere aggiornato
Questo post è stato scritto più di 5 mesi fa, potrebbe non essere aggiornato. Per qualsiasi dubbio ti invito a lasciare un commento per chiedere ulteriori informazioni! :-)