[NEW] GPO - Add Group Policy Objects module - #124
Conversation
Add a Group Policy module to list, view, create, duplicate, rename and delete the Group Policy Objects of a domain, and to edit their content. - LDAP core (GPC): TGPO and TGPOLogic (list, create, duplicate, rename, delete, staged modifications applied in a single LDAP operation). - SYSVOL access (GPT): TGPTCore using smbclient on Linux/macOS and the native UNC API on Windows; list files, read and write GPT.INI and Registry.pol files. - Registry.pol (REGF): TGPRegPol parser and serializer (keys, values, REG_SZ/REG_DWORD/REG_BINARY/...). - UI: toolbar actions, GPO list, Summary/Configuration/Catalog/Technical tabs, GPC parameter editor and Registry.pol visual editor, with a local staging model: nothing is written to the domain until the save action. - Save flow: write the modified Registry.pol files, update the GPT.INI, calculate the new User/Machine versions and update the versionNumber. - Register the module in the main window and in the packages.
synopse
left a comment
There was a problem hiding this comment.
Very nice PR!
I really like that there are so many unit tests.
I made some minor proposals of refactoring, adding some new wrapper functions to mORMot.
I guess the core GPO logic could be part of mormot.net.ldap, to be reusable.
What do you think?
| { TGPO } | ||
|
|
||
| function TGPO.GetDisplayName: RawUtf8; | ||
| var |
| i: Integer; | ||
| begin | ||
| result := ''; | ||
| if not ParseDN(ADomainDN, Pairs) then |
There was a problem hiding this comment.
missing noraise=true.
simply use the new DNToCN((ADomainDN, true, [dnDC])
| constructor TGPOLogic.Create(ALdapClient: TLdapClient); | ||
| begin | ||
| fLog := TOpenRSATLog; | ||
| if Assigned(fLog) then |
There was a problem hiding this comment.
anti pattern for sure - no way to disable this logging, which has little interrest
| Attributes.Add(GPO_ATTR_DISPLAYNAME, ADisplayName); | ||
|
|
||
| DomainName := GetDomainName; | ||
| Attributes.Add(GPO_ATTR_FILESYSPATH, |
There was a problem hiding this comment.
I just created TLdapAttributeList.AddFmt for this kind of code
| function TGPOLogic.ApplyModifications(AGPO: TGPO; | ||
| const AModifications: array of TGPOModification): Boolean; | ||
| var | ||
| Modifications: array of RawByteString; |
There was a problem hiding this comment.
use AsnAddItem() and Modifications: TAsnObjects
| GPO_MACHINE_VERSION_SHIFT = 16; | ||
|
|
||
| // Attributes of the GPC that OpenRSAT knows and can manage. | ||
| GPO_KNOWN_ATTRIBUTES: array of RawUtf8 = ( |
There was a problem hiding this comment.
using an enumerate would be much better here
| var | ||
| i: Integer; | ||
| begin | ||
| SetLength(result, Length(GPO_KNOWN_ATTRIBUTES)); |
There was a problem hiding this comment.
code would be simplified with an enumerate for GPO_KNOWN_ATTRIBUTES[] index
I agree with that. I'll do it as soon as possible. |
- Keep the GPO core logic in OpenRSAT (ugpocore.pas) and use the LDAP helpers added in mORMot 2.4 (GetByName, AddFmt, TAsnObjects/AsnAddItem, DNToCN with dnDC filter) instead of reimplementing them. - Fix the Registry.pol string handling: Windows stores REG_SZ/REG_MULTI_SZ values as UTF-16LE, now detected and converted on read/write. - Sanitize non UTF-8 text coming from smbclient and the SYSVOL files before it reaches the UI. - Fall back to English when a translation resource is missing, and stop logging an error when the Options TreeView has no previous selection. - Rename the GPO creation method to TGPOLogic.Add (avoid shadowing Create). - Reference the mORMot2 package of the submodule explicitly in the project files, and bump the mORMot2 submodule to the official 2.4 helpers. - Add a UTF-16LE Registry.pol unit test and keep the GPO catalog enum.
- Widen the Stage/Discard and Save/Discard changes buttons so the translated captions are not truncated, and enlarge the Configuration editor panel. - Make the GPT files list taller and add two splitters on the Technical tab: one between the GPC attributes and the GPT area, and one between the GPT files grid and the GPT.INI memo.
Remove the translation entries of the old GPO module strings that no longer exist in the code, and reorder the catalog around the new rsGPOCatalog* constants.
|
Nice work! |
Fixes #120
Group Policy Objects (GPO) module
Adds a Group Policy module to list, view, create, duplicate, rename and delete the Group Policy Objects of a domain, and to edit their content.
GPC (LDAP)
TGPO/TGPOLogic(packages/OpenRSATCore/ugpocore.pas): list, create, duplicate, rename and delete GPOs, with staged modifications applied in a single LDAP operation (Add/Replace/Delete per attribute).GPT (SYSVOL)
TGPTCore(packages/OpenRSATCore/ugptcore.pas): access to the GPT files through smbclient on Linux/macOS and through the native UNC API (with WNetAddConnection2) on Windows.LastErrorreports the real failure reason.Registry.pol (REGF)
TGPRegPol(packages/OpenRSATCore/ugpregpol.pas): binary REGF parser and serializer (PRegf header, nested keys, REG_SZ/REG_EXPAND_SZ/REG_DWORD/REG_QWORD/REG_BINARY/REG_MULTI_SZ values).UI (packages/OpenRSATGUI/ufrmmodulegpo.pas)
Save flow (GPO modification)
Tests
tests/unit/unittest.ugpocore.pas: 149 assertions covering the GPC helpers, the GPT.INI parser, the smbclient output parser and the Registry.pol parser (load, round-trip, edit and save, invalid inputs).tests/integration/integrationtest.ugpocore.pas: integration tests against a real Active Directory (list, create, duplicate, rename, delete, update configuration).