Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ACL's on Printers (NT4/W2K)

1 view
Skip to first unread message

Maarten

unread,
Nov 24, 2002, 5:02:43 PM11/24/02
to
Hi,

I'm trying to get this issue resolved for quiete some time now, but i
must be missing something major.

I'm creating printers automatically, and i want to set the appropriate
permissions for that printer, being: SYSTEM:F, <user>:F, en
Administrators:F.

The pseudo code for creating the ACL, looks something like:

- InitializeSecurityDescriptor()
- 3 x LookupAccountName() (SYSTEM, Username, Administrators)
- 3 x AllocateAndInitializeSid()
- InitializeAcl()
- 3 x AddAccessAllowedAce()
- SetSecurityDescriptorDacl()

The code of AddAccessAllowedAce() looks like this (Delphi):


if NOT AddAccessAllowedAce(Acl^,
{ Acl }
ACL_REVISION, { revision
level }
PRINTER_ALL_ACCESS, {
access mask }
SystemSid) then
{ sid }

The ACL gets properly created, but the ACL editor of NT4, shows the
permissions as being "special permissions" instead of "Full Control".
W2K shows all permissions enabled, except the "Manage documents"
permission. The intention is to have the permissions set to Full
Control, but no matter what i do, it doesnt happen.

Is there anyone that can offer me some insight? I attached the code to
this message (it wont compile as it is missing some units, but should
show you completely how the ACL is built)

----- (code) --
unit Security;

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
INTERFACE
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

uses WinSpool,
Windows,
Classes,
SysUtils,
Messages,
Dialogs,
Debug,
Registry;

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

function GetSecForEveryone(var SecurityDescriptor:
PSecurityDescriptor;
var Username: PChar;
var Acl: PACL): Boolean;

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
IMPLEMENTATION
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

const
DOMAIN_ALIAS_RID_ADMINS = ($00000220);

SECURITY_BUILTIN_DOMAIN_RID = ($00000020);
SECURITY_LOCAL_SYSTEM_RID = ($00000012);


const
STANDARD_RIGHTS_ALL = ($001F0000);
SPECIFIC_RIGHTS_ALL = ($0000FFFF);

const
GENERIC_READ = DWORD($80000000);
{$EXTERNALSYM GENERIC_READ}
GENERIC_WRITE = ($40000000);
{$EXTERNALSYM GENERIC_WRITE}
GENERIC_EXECUTE = ($20000000);
{$EXTERNALSYM GENERIC_EXECUTE}
GENERIC_ALL = ($10000000);
{$EXTERNALSYM GENERIC_ALL}
const
SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0,
0, 0, 5));

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

const
ACL_REVISION = 2;

type
ACCESS_MASK = DWORD;
{$EXTERNALSYM ACCESS_MASK}
PACCESS_MASK = ^ACCESS_MASK;
{$EXTERNALSYM PACCESS_MASK}

type
PACE_HEADER = ^ACE_HEADER;
{$EXTERNALSYM PACE_HEADER}
_ACE_HEADER = record
AceType: Byte;
AceFlags: Byte;
AceSize: Word;
end;
{$EXTERNALSYM _ACE_HEADER}
ACE_HEADER = _ACE_HEADER;
{$EXTERNALSYM ACE_HEADER}
TAceHeader = ACE_HEADER;
PAceHeader = PACE_HEADER;

type
PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
{$EXTERNALSYM PACCESS_ALLOWED_ACE}
_ACCESS_ALLOWED_ACE = record
Header: ACE_HEADER;
Mask: ACCESS_MASK;
SidStart: DWORD;
end;
{$EXTERNALSYM _ACCESS_ALLOWED_ACE}
ACCESS_ALLOWED_ACE = _ACCESS_ALLOWED_ACE;
{$EXTERNALSYM ACCESS_ALLOWED_ACE}
TAccessAllowedAce = ACCESS_ALLOWED_ACE;
PAccessAllowedAce = PACCESS_ALLOWED_ACE;

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

function GetSecForEveryone(var SecurityDescriptor:
PSecurityDescriptor;
var Username: PChar;
var Acl: PACL): Boolean;
var DomainName: Array[0..4095] of Char; { array to hold
domainname }
DomainLen : DWORD;

AdminSid : PSID; { SID the administrator SID
will use }
SystemSid : PSID; { PSID the SYSTEM sid
will use }
Sid : PSID; { actual sid we
will use }
SidLen : DWORD; { bytes we need
for SID }
SidNameUse: SID_NAME_USE; { type of SID we want to see
returned }

// Acl : PACL; { we define this as a parameter
cause the }
{ caller has to free
this memory }
AclLen : DWORD;
begin
Acl := nil;

{-- Log some info ----------------------------------------------------------}
DoDebug('GetSecForEveryone - begin');

{-- Initialize this security descriptor
------------------------------------}
SecurityDescriptor := PSecurityDescriptor(LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH));
if (NOT InitializeSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION)) then
begin
DoDebugError('GetSecForEveryone - InitializeSecurityDescriptor -
fail');

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- We will now call LookUpAccountName() with dummy values to get
the ------}
{-- actual lengths required
------------------------------------------------}
{-- This will fail, only to get the sid and domain lengths
-----------------}
Sid := nil;
SidNameUse := SidTypeUser; { we want the type
of user }
SidLen := 0;
DomainLen := 0;

LookupAccountName(nil, {
Systemname }
Username, {
username }
Sid,
{ Sid }
SidLen, { size what SID
should be }
DomainName, {
domainname }
DomainLen, { Length of
domain }
SidNameUse);

{-- we now know how large Sid and Domain should be,
------------------------}
{-- allocate memory for SID
------------------------------------------------}
GetMem(Sid, SidLen);

{-- now make sure that DomainLen isn't actually larger than it
really is ---}
DomainLen := SizeOf(DomainName) - 1;

{-- and try to look it up
--------------------------------------------------}
if NOT LookupAccountName(nil, {
Systemname }
Username, {
username }
Sid,
{ Sid }
SidLen, { size what SID
should be }
DomainName, {
domainname }
DomainLen, { Length of
domain }
SidNameUse) then
begin
DoDebugError('GetSecForEveryone - LookupAccountName - fail');
FreeMem(Sid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- ok, now lets get the sid for the Administrators *group*
----------------}
if NOT AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, { NT
authority }
2, {
SubAuthorityCount }
SECURITY_BUILTIN_DOMAIN_RID, {
SubA - 1 }
DOMAIN_ALIAS_RID_ADMINS, {
SubB - 1 }
0, 0, 0, 0, 0, 0,
AdminSid) then
begin
DoDebugError('GetSecForEveryone - LookupAccountName - fail');
FreeMem(Sid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- ok, now lets get the sid for the Administrators *group*
----------------}
if NOT AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, { NT
authority }
1, {
SubAuthorityCount }
SECURITY_LOCAL_SYSTEM_RID, {
SubA - 1 }
0, 0, 0, 0, 0, 0, 0,
SystemSid) then
begin
DoDebugError('GetSecForEveryone - LookupAccountName(2) - fail');
FreeMem(Sid);
FreeSid(AdminSid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }


{-- Now initialize an Access Control List (ACL)
----------------------------}
{ OLD: ****
AclLen := ((SizeOf(ACL) + (SizeOf(TAccessAllowedAce) * 2)) +
(GetLengthSid(Sid) + GetLengthSid(AdminSid))) -
SizeOf(DWORD);
*********
}
AclLen := ((SizeOf(ACL) + (SizeOf(TAccessAllowedAce) * 3)) +
(GetLengthSid(Sid) + GetLengthSid(AdminSid) +
GetLengthSid(SystemSid))) - SizeOf(DWORD);

{-- allocate memory for what we want
---------------------------------------}
Acl := PACL(LocalAlloc(LPtr, AclLen));

{-- and see if we can get this access control list initialized
-------------}
if NOT InitializeAcl(Acl^,
{ Acl }
AclLen, { length of
this ACL }
ACL_REVISION) then
begin
DoDebugError('GetSecForEveryone - IntiailizeAcl - fail');
LocalFree(Cardinal(Acl));
FreeMem(Sid);
FreeSid(AdminSid);
FreeSid(SystemSid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- Log some extra info just cause we are a friendly bunch
-----------------}
DoDebug('GetSecForEveryone - Username: ' + StrPas(Username));
DoDebug('GetSecForEveryone - Domain : ' + StrPas(DomainName));

{-- Now add this ACE to the ACL
--------------------------------------------}
if NOT AddAccessAllowedAce(Acl^,
{ Acl }
ACL_REVISION, {
revision level }
PRINTER_ALL_ACCESS, {
access mask }
Sid) then
{ sid }
begin
DoDebugError('GetSecForEveryone - AddAccessAllowedAce - fail');
LocalFree(Cardinal(Acl));
FreeMem(Sid);
FreeSid(AdminSid);
FreeSid(SystemSid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- Now add the 2nd ACE to the ACL (administrators group)
------------------}
if NOT AddAccessAllowedAce(Acl^,
{ Acl }
ACL_REVISION, {
revision level }
PRINTER_ALL_ACCESS, {
access mask }
AdminSid) then
{ sid }
begin
DoDebugError('GetSecForEveryone - AddAccessAllowedAce(2) -
fail');
LocalFree(Cardinal(Acl));
FreeMem(Sid);
FreeSid(SystemSid);
FreeSid(AdminSid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- Now add the 3rd ACE to the ACL (SYSTEM group)
--------------------------}
if NOT AddAccessAllowedAce(Acl^,
{ Acl }
ACL_REVISION, {
revision level }
PRINTER_ALL_ACCESS, {
access mask }
SystemSid) then
{ sid }
begin
DoDebugError('GetSecForEveryone - AddAccessAllowedAce(3) -
fail');
LocalFree(Cardinal(Acl));
FreeMem(Sid);
FreeSid(SystemSid);
FreeSid(AdminSid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- and free up the memory we used
-----------------------------------------}
FreeSid(adminSid);
FreeSid(SystemSid);
FreeMem(Sid);

{-- and set the security descriptor
----------------------------------------}
if NOT SetSecurityDescriptorDacl(SecurityDescriptor,
TRUE, {
bDaclPresent }
Acl,
{ pDacl }
FALSE) then {
bAclDefaulted }
begin
DoDebugError('GetSecForEveryone - SetSecurityDecriptorDacl -
fail');
LocalFree(Cardinal(Acl));
FreeMem(Sid);

GetSecForEveryone := FALSE;
EXIT;
end; { if }

{-- freeup the memory we used
----------------------------------------------}
// LocalFree(Cardinal(Acl));

{-- we succeeded! ----------------------------------------------------------}
GetSecForEveryone := TRUE;

{-- Log some info ----------------------------------------------------------}
DoDebug('GetSecForEveryone - leave');
end; { func. GetSecForEveryone }

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

end.

0 new messages