Title: Message
I was tech reviewing a book chapter and realized I had a perl script that others may find useful in the AD world, especially if they are doing ACE/ACL coding via scripts. I wrote this like a year ago so be gentle as I may have done silly things or may not even recall why I did certain things.
 
It uses ADFIND because I hate using ADO for searching and I don't like burying passwords in scripts or having to ask for them. ADFIND is a free download from www.joeware.net and is harmless except that it gets your mind wondering what else you can do which some people find dangerous enough by itself. You will note that any perl script I do AD searches from I always fall back to adfind. I may use adsi to open up a specific object sometimes, but it is always search via adfind.
 
Anyway, I use this script when I am really looking close at AD ACL's and when I have to whip up a quick script to do something. I set the perms manually through the GUI and then see what it produced with this. If you use the /verbose switch it will show you GUIDs and such that you need to insert into your script for control access rights and property sets, etc. The debug switch isn't fleshed out at all.
 
I guess I should work on getting this up on the website. :op
 
I had started writing it in vbscript but vbscript pisses me off more times than not, I wish MS would just get it over with and buy ActiveState and have perl be default on all of its OS's. MS has nothing else that touches it and I won't argue this point. You can do simple things simply and bigger things with a little more work and you don't have to keep going back to a book for objectclass references. Once simple web reference page will generally do the trick.
 
Hope it is helpful.
 
   joe
 
 
 
Usage is
 
#**************************************************************************
#AccessMask constants
#**************************************************************************
$ADS_RIGHT_GENERIC_READ = 0x80000000;
$ADS_RIGHT_GENERIC_WRITE = 0x40000000;
$ADS_RIGHT_GENERIC_EXECUTE = 0x20000000;
$ADS_RIGHT_GENERIC_ALL = 0x10000000;
$ADS_RIGHT_SYSTEM_SECURITY = 0x1000000;
$ADS_RIGHT_SYNCHRONIZE = 0x100000;
$ADS_RIGHT_WRITE_OWNER = 0x80000;
$ADS_RIGHT_WRITE_DAC = 0x40000;
$ADS_RIGHT_READ_CONTROL = 0x20000;
$ADS_RIGHT_DELETE = 0x10000;
$ADS_RIGHT_DS_CONTROL_ACCESS = 0x100;
$ADS_RIGHT_DS_LIST_OBJECT = 0x80;
$ADS_RIGHT_DS_DELETE_TREE = 0x40;
$ADS_RIGHT_DS_WRITE_PROP = 0x20;
$ADS_RIGHT_DS_READ_PROP = 0x10;
$ADS_RIGHT_DS_SELF = 0x8;
$ADS_RIGHT_ACTRL_DS_LIST = 0x4;
$ADS_RIGHT_DS_DELETE_CHILD = 0x2;
$ADS_RIGHT_DS_CREATE_CHILD = 0x1;
$FULL_CONTROL = -1;    # This isn't right...
 

#**************************************************************************
#AceType constants
#**************************************************************************
$ADS_ACETYPE_SYSTEM_ALARM_OBJECT = 0x8;
$ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = 0x7;
$ADS_ACETYPE_ACCESS_DENIED_OBJECT = 0x6;
$ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 0x5;
$ADS_ACETYPE_SYSTEM_AUDIT = 0x2;
$ADS_ACETYPE_ACCESS_DENIED = 0x1;
$ADS_ACETYPE_ACCESS_ALLOWED = 0x0;
 
#**************************************************************************
#AceFlags constants
#**************************************************************************
$ADS_ACEFLAG_FAILED_ACCESS = 0x80;
$ADS_ACEFLAG_SUCCESSFUL_ACCESS = 0x40;
$ADS_ACEFLAG_VALID_INHERIT_FLAGS = 0x1F;
$ADS_ACEFLAG_INHERITED_ACE = 0x10;
$ADS_ACEFLAG_INHERIT_ONLY_ACE = 0x8;
$ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = 0x4;
$ADS_ACEFLAG_INHERIT_ACE = 0x2;
 
#**************************************************************************
#Security Descriptor constants
#**************************************************************************
$ADS_SD_CONTROL_SE_OWNER_DEFAULTED = 0x1;
$ADS_SD_CONTROL_SE_GROUP_DEFAULTED = 0x2;
$ADS_SD_CONTROL_SE_DACL_PRESENT = 0x4;
$ADS_SD_CONTROL_SE_DACL_DEFAULTED = 0x8;
$ADS_SD_CONTROL_SE_SACL_PRESENT = 0x10;
$ADS_SD_CONTROL_SE_SACL_DEFAULTED = 0x20;
$ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ = 0x100;
$ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ = 0x200;
$ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED = 0x400;
$ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED = 0x800;
$ADS_SD_CONTROL_SE_DACL_PROTECTED = 0x1000;
$ADS_SD_CONTROL_SE_SACL_PROTECTED = 0x2000;
 
#**************************************************************************
#Flags constants
#**************************************************************************
$ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT = 0x2;
$ADS_FLAG_OBJECT_TYPE_PRESENT = 0x1;
 
 
 
 
 
#**************************************************************************
#MAIN
#**************************************************************************
use Win32::OLE;
use Win32::OLE::Enum;
 
%schemaids=();
%propertysetids=();
$debug=0;
$verbose=0;
 
print "\nPerlChkSec V01.00.00pl  Joe Richards ([EMAIL PROTECTED])  June 2002\n\n";
 
$obj=shift;
 
if (grep(/\/debug/i,@ARGV))
 {
  $debug=1;
 }
 
if (grep(/\/verbose/i,@ARGV))
 {
  $verbose=1;
 }
 

if ($debug) {print "Debugging enabled...\n"};
 

if (!$obj)
 {
  print "Usage PerlChkSec RFC1779_Object_Name\n";
  exit;
 }
 
$adsrootdse=Win32::OLE->GetObject("LDAP://RootDse") or die("RootDSE: $!\n");
$dnshostname=$adsrootdse->Get("dnsHostName");
$SchemaPath=$adsrootdse->Get("schemaNamingContext");
$ConfigurationPath=$adsrootdse->Get("configurationNamingContext");
 
$adobject = "LDAP://$obj";
 
$oComputer = Win32::OLE->GetObject($adobject) or die("Couldn't bind to $adobject\n");
$sd = $oComputer->ntSecurityDescriptor;
$control=$sd->Control;
print "Control         : $control\n";
 
if ($control & $ADS_SD_CONTROL_SE_OWNER_DEFAULTED) {print "\t\t\tADS_SD_CONTROL_SE_OWNER_DEFAULTED\n"};
if ($control & $ADS_SD_CONTROL_SE_GROUP_DEFAULTED) {print "\t\t\tADS_SD_CONTROL_SE_GROUP_DEFAULTED\n"};
if ($control & $ADS_SD_CONTROL_SE_DACL_PRESENT) {print "\t\t\tADS_SD_CONTROL_SE_DACL_PRESENT\n"};
if ($control & $ADS_SD_CONTROL_SE_DACL_DEFAULTED) {print "\t\t\tADS_SD_CONTROL_SE_DACL_DEFAULTED\n"};
if ($control & $ADS_SD_CONTROL_SE_SACL_PRESENT) {print "\t\t\tADS_SD_CONTROL_SE_SACL_PRESENT\n"};
if ($control & $ADS_SD_CONTROL_SE_SACL_DEFAULTED) {print "\t\t\tADS_SD_CONTROL_SE_SACL_DEFAULTED\n"};
if ($control & $ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ) {print "\t\t\tADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ\n"};
if ($control & $ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ) {print "\t\t\tADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ\n"};
if ($control & $ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED) {print "\t\t\tADS_SD_CONTROL_SE_DACL_AUTO_INHERITED\n"};
if ($control & $ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED) {print "\t\t\tADS_SD_CONTROL_SE_SACL_AUTO_INHERITED\n"};
if ($control & $ADS_SD_CONTROL_SE_DACL_PROTECTED) {print "\t\t\tADS_SD_CONTROL_SE_DACL_PROTECTED\n"};
if ($control & $ADS_SD_CONTROL_SE_SACL_PROTECTED) {print "\t\t\tADS_SD_CONTROL_SE_SACL_PROTECTED\n"};
 
print "Group           : ",$sd->Group,"\n";
print "Owner           : ",$sd->Owner,"\n";
print "Default Owner   : ",$sd->OwnerDefaulted,"\n";
print "Revision        : ",$sd->Revision,"\n";
 
$dACL = $sd->DiscretionaryAcl;
 
$dACLEnum = Win32::OLE::Enum->new($dACL);
 
while ($ace=$dACLEnum->Next)
 {
  print "  ACE\n";
  print "      Trustee          : ";
  $trustee=$ace->trustee;
  if ($trustee=~/s-\d+-\d+/i)
   {
    @output=`sidtoname $trustee $dnshostname 2>&1`;
    chomp @output;
    $o=$output[0];
    if ($o ne "\\") {$trustee="[$o]"};
    if ($verbose) {$trustee="(".$ace->trustee.") - $trustee"};
   }
  print "$trustee\n";
 
  $AceFlags = $ace->Flags;
  if ($AceFlags & $ADS_FLAG_OBJECT_TYPE_PRESENT)
   {
    print "      Ace Type Flags   : ADS_FLAG_OBJECT_TYPE_PRESENT\n";
    $ObjectType=GetObjectType($ace->ObjectType);
    if ($verbose) {$ObjectType="(".$ace->ObjectType.") - $ObjectType"};
    print "      ObjectType       : $ObjectType\n";
   }
  if ($AceFlags & $ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT)
   {
    print "      Ace Type Flags   : ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT\n";
    $InheritedObjectType=GetObjectType($ace->InheritedObjectType);
    if ($verbose) {$InheritedObjectType="(".$ace->InheritedObjectType.") - $InheritedObjectType"};
    print "      ObjectType       : $InheritedObjectType\n";
   }
 
  $AceType = $ace->AceType;
  if ($AceType == $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT)
    {$acestring="ADS_ACETYPE_ACCESS_ALLOWED_OBJECT"}
  elsif ($AceType == $ADS_ACETYPE_ACCESS_DENIED_OBJECT)
    {$acestring="ADS_ACETYPE_ACCESS_DENIED_OBJECT"}
  elsif ($AceType == $ADS_ACETYPE_ACCESS_ALLOWED)
    {$acestring="ADS_ACETYPE_ACCESS_ALLOWED"}
  elsif ($AceType = $ADS_ACETYPE_ACCESS_DENIED)
    {$acestring="ADS_ACETYPE_ACCESS_DENIED"}
  else
    {$acestring="UNKNOWN TYPE: $AceType\n"};
  if ($verbose) {$acestring="(".$AceType.") - $acestring"};
  print "      Ace Type         : $acestring\n";
 
  $aceflags=$ace->aceflags;
  print "      Ace Flag         : $aceflags\n";
  if ($aceflags & $ADS_ACEFLAG_FAILED_ACCESS) {print "\t\t\t\tADS_ACEFLAG_FAILED_ACCESS\n"};
  if ($aceflags & $ADS_ACEFLAG_SUCCESSFUL_ACCESS) {print "\t\t\t\tADS_ACEFLAG_SUCCESSFUL_ACCESS\n"};
  if ($aceflags & $ADS_ACEFLAG_VALID_INHERIT_FLAGS) {print "\t\t\t\tADS_ACEFLAG_VALID_INHERIT_FLAGS\n"};
  if ($aceflags & $ADS_ACEFLAG_INHERITED_ACE) {print "\t\t\t\tADS_ACEFLAG_INHERITED_ACE\n"};
  if ($aceflags & $ADS_ACEFLAG_INHERIT_ONLY_ACE) {print "\t\t\t\tADS_ACEFLAG_INHERIT_ONLY_ACE\n"};
  if ($aceflags & $ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE) {print "\t\t\t\tADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE\n"};
  if ($aceflags & $ADS_ACEFLAG_INHERIT_ACE) {print "\t\t\t\tADS_ACEFLAG_INHERIT_ACE\n"};
 
 
  $lmask=$ace->accessmask;
  print "      Access Mask      : $lmask\n";
  if ($lmask == $FULL_CONTROL) {print "\t\t\tFULL_CONTROL\n"};
  if ($lmask & $ADS_RIGHT_GENERIC_READ) {print "\t\t\t\tADS_RIGHT_GENERIC_READ\n"};
  if ($lmask & $ADS_RIGHT_GENERIC_WRITE) {print "\t\t\t\tADS_RIGHT_GENERIC_WRITE\n"};
  if ($lmask & $ADS_RIGHT_GENERIC_EXECUTE) {print "\t\t\t\tADS_RIGHT_GENERIC_EXECUTE\n"};
  if ($lmask & $ADS_RIGHT_GENERIC_ALL) {print "\t\t\t\tADS_RIGHT_GENERIC_ALL\n"};
  if ($lmask & $ADS_RIGHT_SYSTEM_SECURITY) {print "\t\t\t\tADS_RIGHT_SYSTEM_SECURITY\n"};
  if ($lmask & $ADS_RIGHT_SYNCHRONIZE) {print "\t\t\t\tADS_RIGHT_SYNCHRONIZE\n"};
  if ($lmask & $ADS_RIGHT_WRITE_OWNER) {print "\t\t\t\tADS_RIGHT_WRITE_OWNER\n"};
  if ($lmask & $ADS_RIGHT_WRITE_DAC) {print "\t\t\t\tADS_RIGHT_WRITE_DAC\n"};
  if ($lmask & $ADS_RIGHT_READ_CONTROL) {print "\t\t\t\tADS_RIGHT_READ_CONTROL\n"};
  if ($lmask & $ADS_RIGHT_DELETE) {print "\t\t\t\tADS_RIGHT_DELETE\n"};
  if ($lmask & $ADS_RIGHT_DS_CONTROL_ACCESS) {print "\t\t\t\tADS_RIGHT_DS_CONTROL_ACCESS\n"};
  if ($lmask & $ADS_RIGHT_DS_LIST_OBJECT) {print "\t\t\t\tADS_RIGHT_DS_LIST_OBJECT\n"};
  if ($lmask & $ADS_RIGHT_DS_DELETE_TREE) {print "\t\t\t\tADS_RIGHT_DS_DELETE_TREE\n"};
  if ($lmask & $ADS_RIGHT_DS_WRITE_PROP) {print "\t\t\t\tADS_RIGHT_DS_WRITE_PROP\n"};
  if ($lmask & $ADS_RIGHT_DS_READ_PROP) {print "\t\t\t\tADS_RIGHT_DS_READ_PROP\n"};
  if ($lmask & $ADS_RIGHT_DS_SELF) {print "\t\t\t\tADS_RIGHT_DS_SELF\n"};
  if ($lmask & $ADS_RIGHT_ACTRL_DS_LIST) {print "\t\t\t\tADS_RIGHT_ACTRL_DS_LIST\n"};
  if ($lmask & $ADS_RIGHT_DS_DELETE_CHILD) {print "\t\t\t\tADS_RIGHT_DS_DELETE_CHILD\n"};
  if ($lmask & $ADS_RIGHT_DS_CREATE_CHILD) {print "\t\t\t\tADS_RIGHT_DS_CREATE_CHILD\n"};
 
 } 
 
 
 
sub GetObjectType
 {
  $ot=shift;
  if ($ot!~/\w/) {return ""};
  $origot=$ot;
  if (!$schemaids{LOADED}) {LoadSchema()};
  $ot=~s/[-{}]//ig;
  $ot=lc($ot);
  $value=$schemaids{$ot};
  if (!$value) {$value=$propertysetids{$ot}};
  if (!$value)
   {
    print "****COULDN'T RESOLVE --- $ot\n";
    return "UNRESOLVEABLE: $origot";
   }
  return $value;
 }
 
sub LoadSchema
 {
  $currentdisplayname="";
  $currentschemaid="";
  @output=`adfind -q -b $SchemaPath -s onelevel -f schemaidguid=* schemaidguid ldapdisplayname 2>&1`;
  chomp @output;
  foreach $thisline (@output)
   {
    next unless $thisline=~/\w/;
    next if $thisline=~/using server/i;
    next if $thisline=~/objects returned/i;
    if ($thisline=~/^dn:/i)
     {
      if ($currentdisplayname)
       {
        $currentschemaid=~s/[-{}]//ig;
        $schemaids{lc($currentschemaid)}=$currentdisplayname;
        $currentschemaid="";
        $currentdisplayname="";
       }
     }
    if ($thisline=~/^>ldapdisplayname: (.+)/i) {$currentdisplayname=$1};
    if ($thisline=~/^>schemaidguid: (.+)/i) {$currentschemaid=$1};
   }
  if ($currentdisplayname)
   {
    $currentschemaid=~s/[-{}]//ig;
    $schemaids{lc($currentschemaid)}=$currentdisplayname;
    $currentschemaid="";
    $currentdisplayname="";
   }
  $schemaids{LOADED}=1;
 
  #
  # Now load property set GUIDs
  #
  $currentdisplayname="";
  $currentrightsid="";
  @output=`adfind -q -b CN=Extended-Rights,$ConfigurationPath -s onelevel -f rightsguid=* rightsguid displayname 2>&1`;
  chomp @output;
  foreach $thisline (@output)
   {
    next unless $thisline=~/\w/;
    next if $thisline=~/using server/i;
    next if $thisline=~/objects returned/i;
    if ($thisline=~/^dn:/i)
     {
      if ($currentdisplayname)
       {
        $currentrightsid=~s/[-{}]//ig;
        $propertysetids{lc($currentrightsid)}=$currentdisplayname;
        $currentrightsid="";
        $currentdisplayname="";
       }
     }
    if ($thisline=~/^>displayname: (.+)/i) {$currentdisplayname=$1};
    if ($thisline=~/^>rightsguid: (.+)/i) {$currentrightsid=$1};
   }
  if ($currentdisplayname)
   {
    $currentrightsid=~s/[-{}]//ig;
    $propertysetids{lc($currentrightsid)}=$currentdisplayname;
    $currentrightsid="";
    $currentdisplayname="";
   }
 
#  foreach (sort keys %propertysetids) {print "$_\t$propertysetids{$_}\n"};
 
 }

Reply via email to