Windows 2000 introduces new security editors that are fully documented in the Platform SDK. However, NT 4.0’s security editors, which are used by Reged32 and Explorer, have never been documented by Microsoft. Back when I implemented WinObj v2.0 I derived the interfaces for the NT system ACL (Access Control List) editors, which are implemented by acledit.dll. I’ve decided to now finally publicly document the APIs, which are useful for applications that wish to support standard security editing features under NT 4.0.
This function pops up a discretionary ACL editor dialog box.
DWORD SedDiscretionaryAclEditor( HWND Owner, HINSTANCE Instance, PWCHAR MachineName, // optional PACLDLGCONTROL AclDlgControl, PACLEDITCONTROL AclEditControl, PWCHAR ObjectName, PACLCHANGE ChangeCallback, PVOID ChangeCallbackContext, PSECURITY_DESCRIPTOR ObjectSecurity, BOOLEAN NoReadPermission, BOOLEAN ReadOnly, PDWORD ChangeContextStatus, PVOID MustBeZero );
Handle to window of dialog owner.
This is the instance handle of the application that will be associated with the dialog box.
This is an optional parameter that specifies the name of the computer (e.g. \\mark) where local account lookups for security descriptors will be performed. Specify NULL for the local machine.
Points to a caller supplied ACL dialog control data structure.
Points to a caller-supplied ACL edit entry control data structure.
Specifies the text of the object name (e.g. “C:\temp\”) field printed in the dialog box.
Callback that is invoked if the user enters changes into the editor and then dismisses the dialog.
Context parameter that will be passed unchanged to the ChangeCallback procedure.
The security descriptor associated with the object. The descriptor is interpreted with respect to user accounts and permissions and the information is displayed in the dialog box.
Tell the user that they cannot view the security information, but they can attempt to overwrite it if they want. The object security descriptor information is not displayed in the dialog.
Tell the user that they can only view the object’s security information. The Add and Remove buttons on the dialog are disabled.
The dialog ignores this value which it passes as a parameter to the change callback function. The change callback function can return a status code to the code that invoked the dialog box if a pointer to a status variable is passed for this parameter.
Set to zero.
The function returns a non-zero value on failure. Failure is returned if the security context is invalid for example.
This function pops up an ownership editor dialog box.
DWORD SedTakeOwnership( HWND Owner, HINSTANCE Instance, PWCHAR MachineName, // optional PWCHAR ObjectType, PWCHAR ObjectName, DWORD ObjectCount, PACLCHANGE ChangeCallback, PVOID ChangeCallbackContext, PSECURITY_DESCRIPTOR ObjectSecurity, BOOLEAN NoReadPermission, BOOLEAN NoOwnerChange, PDWORD ChangeContextStatus, PACLHELPCONTROL HelpInfo, PVOID MustBeZero );
Handle to window of dialog owner.
This is the instance handle of the application that will be associated with the dialog box.
This is an optional parameter that specifies the name of the computer (e.g. \\mark) where local account lookups for security descriptors will be performed. Specify NULL for the local machine.
Specifies the text that will displayed for the object type (e.g. “Directory”).
Specifies the text of the object name (e.g. “C:\temp\”) field printed in the dialog box.
If more than one then ObjectName is ignored.
Callback that is invoked if the user enters changes into the editor and then dismisses the dialog.
Context parameter that will be passed unchanged to the ChangeCallback procedure.
The security descriptor associated with the object. The descriptor is interpreted with respect to user accounts and permissions and the information is displayed in the dialog box.
Tell the user that they cannot view the security information, but they can attempt to overwrite it if they want. The object security descriptor information is not displayed in the dialog.
Set to true to indicate that the user doesn't have permission to change ownership of the object.
The dialog ignores this value which it passes as a parameter to the change callback function. The change callback function can return a status code to the code that invoked the dialog box if a pointer to a status variable is passed for this parameter.
Pointer to a help information structure that is referenced when the user enters the Help button on the dialog box.
Set to zero.
The function returns a non-zero value on failure. Failure is returned if the security context is invalid for example.
This function pops up a system ACL editor dialog box.
DWORD SedSystemAclEditor( HWND Owner, HINSTANCE Instance, PWCHAR MachineName, // optional PACLDLGCONTROL AclDlgControl, PACLEDITCONTROL AclEditControl, PWCHAR ObjectName, PACLCHANGE ChangeCallback, PVOID ChangeCallbackContext, PSECURITY_DESCRIPTOR ObjectSecurity, BOOLEAN NoReadPermission, PDWORD ChangeContextStatus, PVOID MustBeZero );
Handle to window of dialog owner.
This is the instance handle of the application that will be associated with the dialog box.
This is an optional parameter that specifies the name of the computer (e.g. \\mark) where local account lookups for security descriptors will be performed. Specify NULL for the local machine.
Points to a caller supplied ACL dialog control data structure.
Points to a caller-supplied ACL edit entry control data structure.
Specifies the text of the object name (e.g. “C:\temp\”) field printed in the dialog box.
Callback that is invoked if the user enters changes into the editor and then dismisses the dialog.
Context parameter that will be passed unchanged to the ChangeCallback procedure.
The security descriptor associated with the object. The descriptor is interpreted with respect to user accounts and permissions and the information is displayed in the dialog box.
Tell the user that they do not have a privilege required for viewing the object’s auditing information.
The dialog ignores this value which it passes as a parameter to the change callback function. The change callback function can return a status code to the code that invoked the dialog box if a pointer to a status variable is passed for this parameter.
Set to zero.
The function returns a non-zero value on failure. Failure is returned if the security context is invalid for example.
The ACLDLGCONTROL structure specifies the attributes of the SedDiscritionaryAclEditor and SedSystemAclEditor dialog boxes.
typedef struct { UCHAR Version; BOOLEAN IsContainer; BOOLEAN AllowNewObject; BOOLEAN MapSpecificToGeneric; PDWORD GenericAccessMap; PDWORD GenericMappingNewObjects; PWCHAR DialogTitle; PACLHELPCONTROL HelpInfo; PWCHAR SubReplaceTitle; PWCHAR SubReplaceObjectsTitle; PWCHAR SubReplaceConfirmation; PWCHAR SpecialAccess; PWCHAR SpecialNewAccess; } ACLDLGCONTROL, *PACLDLGCONTROL;
Set to 1.
Indicates if object is a container.
Allow permissions to be applied to new (non-existent) objects.
Determines if generic mapping entry is used.
Points to a GENERIC_MAPPING (defined in the Win32 SDK) structure that specifies a mapping of generic to specific and standard access types. The access map array used by Explorer is:
DWORD AccessMasks[4] = { 0x120089, 0x120116, 0x1200A0, 0x1F01FF };
The access map array used by Regedt32 is:
DWORD RegistryAccessMasks[4] = { 0x120019, 0x20006, 0x20019, 0xF003F }
Interpreted as specific access types for new objects. Pass the same GENERIC_MAPPING structure as for the GenericAccessMap parameter.
Specifies the text that will be displayed in the title bar of the dialog box.
Points to PACLHELPCONTROL structure that defines the help actions taken when the user presses the dialog box’s Help button.
Specifies the text that is included next to the check box that allows a user to recursively replace security descriptors on children containers of the object that is being edited.
Specifies the text that is included next to the check box that allows a user to recursively replace security descriptors on children objects of the object that is being edited.
Species the text in the dialog box that is presented the user if they checked the check box that will result in a replacement of the security descriptors of all the children of the object being edited.
Specifies the text that is displayed for the entry in the pre-defined security settings drop down menu that the user can select to open a specific access editor dialog. Regedt32 and Explorer specify “Special Access...” for this string.
Specifies the text that is displayed for the entry in the pre-defined security settings drop down menu that the user can select to open a specific access editor dialog for new objects.
The ACLEDITCONTROL structure specifies security masks that the security editor dialog box uses when the user specifies that they want to edit specific security attributes for an object. They can do this by either selecting the “Special Access...” entry in the security settings drop-down list or by double clicking on an existing security entry in the dialog’s main window.
typedef struct { DWORD NumberOfEntries; PACLEDITENTRY Entries; PWCHAR DefaultPermissionName; } ACLEDITCONTROL, *PACLEDITCONTROL;
Specifies the number of entries being passed.
Points to an array of ACLEDITENTRY structures. Each entry in the list will result in an additional check box in the specific access security editor dialog box. When the user selects the entry the corresponding access mask bits will be added to the resulting security descriptor entry.
The permission that should be selected by default in the combo box in the Add permission dialog.
The ACLEDITENTRY structure specifies security masks that the security editor dialog box uses when the user specifies that they want to edit specific security attributes for an object.
typedef struct { DWORD Type; DWORD AccessMask; DWORD AccessMask1; // optional PWCHAR Name; } ACLEDITENTRY, *PACLEDITENTRY;
Specifies whether the entry is a generic access entry, a specific access entry or a combination.
If the user checks the box for this entry this access mask will be applied to the entry that the user is defining.
Used for special access or ignored.
Specifies the text label that will identify this access setting (e.g. “Read”).
See the following pages for the definitions for these data structures used by Explorer and Regedt32.
ACLEDITENTRY aclEditEntryRegistry[] = { { 2, KEY_QUERY_VALUE, 0, L"&Query Value" }, { 2, KEY_SET_VALUE, 0, L"&Set Value" }, { 2, KEY_CREATE_SUB_KEY, 0, L"&Create Subkeys"}, { 2, KEY_ENUMERATE_SUB_KEYS, 0, L"&Enumerate Subkeys" }, { 2, KEY_NOTIFY, 0, L"No&tify" }, { 2, KEY_CREATE_LINK, 0, L"Create &Link" }, { 2, DELETE, 0, L"&Delete" }, { 2, WRITE_DAC, 0, L"&Write DAC" }, { 2, WRITE_OWNER, 0, L"Write &Owner" }, { 2, READ_CONTROL, 0, L"&Read Control" }, { 1, 0x2019, 0, L"Read" }, { 1, GENERIC_ALL, 0, L"Full Control" }, };
ACLEDITENTRY aclEditEntryDirectory[] = { { 2, GENERIC_READ, 0, L"&Read (R)" }, { 2, GENERIC_WRITE, 0, L"&Write (W)" }, { 2, GENERIC_EXECUTE, 0, L"E&xecute (X)"}, { 2, ACCESS_SYSTEM_SECURITY, 0, L"&View/Change Audits (A)" }, { 2, DELETE, 0, L"&Delete (D)" }, { 2, WRITE_DAC, 0, L"Change &Permissions (P)" }, { 2, WRITE_OWNER, 0, L"Take &Ownership (O)" }, { 2, FILE_LIST_DIRECTORY, 0, L"&List (L)" }, { 2, FILE_ADD_FILE, 0, L"Add &Entry (N)" }, { 2, READ_CONTROL, 0, L"Read &Control (T)" }, { 3, 0, 0, L"No Access" }, { 3, FILE_LIST_DIRECTORY|READ_CONTROL, (DWORD) -1, L"List" }, { 3, GENERIC_READ|GENERIC_EXECUTE, GENERIC_READ|GENERIC_EXECUTE, L"Read" }, { 3, GENERIC_WRITE|GENERIC_EXECUTE, (DWORD) -1, L"Add" }, { 3, GENERIC_WRITE|GENERIC_READ|GENERIC_EXECUTE, GENERIC_READ|GENERIC_EXECUTE, L"Add Read" }, { 3, GENERIC_WRITE|GENERIC_READ|GENERIC_EXECUTE|DELETE, GENERIC_WRITE|GENERIC_READ| GENERIC_EXECUTE|DELETE, L"Change" }, { 3, GENERIC_ALL, GENERIC_ALL, L"Full Control" }, { 4, GENERIC_READ, 0, L"Read" }, { 4, GENERIC_WRITE, 0, L"Write" }, { 4, DELETE, 0, L"Delete (D)"}, { 4, WRITE_DAC, 0, L"Change Permissions (P)" }, { 4, WRITE_OWNER, 0, L"Take Ownership (O)" }, };
ACLEDITENTRY aclEditEntryFile[] = { { 2, GENERIC_READ, 0, L"&Read (R)" }, { 2, GENERIC_WRITE, 0, L"&Write (W)" }, { 2, GENERIC_EXECUTE, 0, L"E&xecute (X)" }, { 2, DELETE, 0, L"&Delete (D)" }, { 2, WRITE_DAC, 0, L"Change &Permissions (P)" }, { 2, WRITE_OWNER, 0, L"Change &Owner (O)" }, { 1, 0, 0, L"No Access" }, { 1, GENERIC_READ|GENERIC_EXECUTE, 0, L”Read” }, { 1, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, L”Change” }, { 1, GENERIC_ALL, 0, L"Full Control" }, };
The following is the entry used for the SedSystemAclEditor function:
ACLEDITENTRY saclEditEntry[] = { { 5, GENERIC_READ|ACCESS_SYSTEM_SECURITY, 0, L"&Read" }, { 5, GENERIC_WRITE|ACCESS_SYSTEM_SECURITY, 0, L"&Write" }, { 5, GENERIC_EXECUTE, 0, L"E&xecute" }, { 5, DELETE, 0, L"&Delete" }, { 5, WRITE_DAC, 0, L"Change &Permissions" }, { 5, WRITE_OWNER, 0, L"&Take Ownership" }, };
The ACLHELPCONTROL structure specifies the help item that will be displayed when a user presses the Help button in one of the security editor dialog boxes.
typedef struct { PWCHAR HelpFile; DWORD MainDialogTopic; DWORD ACLEditorDialogTopic; DWORD Reserved1; DWORD AddEntryDialogTopic; DWORD Reserved2; DWORD Reserved3; DWORD AccountDialogTopic; } ACLHELPCONTROL, *PACLHELPCONTROL;
Specifies the name of the help file that will be accessed (e.g. “Application.hlp”.
Specifies the topic ID in the help file that will be displayed, if appropriate.
Specifies the subtopic ID if appropriate.
An ACLCHANGE function is a callback function called by a security editor dialog box when the user indicates that they want to change a security descriptor. The function is invoked if the user presses the Okay button.
typedef DWORD CALLBACK (*ACLCHANGE )( HWND Owner, HANDLE Instance, PVOID CallbackContext, PSECURITY_DESCRIPTOR NewSD, PSECURITY_DESCRIPTOR NewObjectSD, BOOLEAN ApplyToSubContainers, BOOLEAN ApplyToSubObjects, PDWORD ChangeContextStatus );
Handle to dialog box owner window.
This is the instance handle of the application.
The unchanged context parameter that was passed to the dialog function.
The modified security descriptor. It is up to the callback function to apply this new security descriptor to the object if appropriate.
The security descriptor that should be applied to the new object if the dialog is for new object creation.
Indicates that permissions should be applied to subcontainers.
Indicates that permissions should be applied to subobjects.
A status that can be returned to the caller of the original dialog box function. The security editor dialog function does not look at this value.
The function should return a non-zero value to indicate failure