Quantcast
Channel: Software Communities : Popular Discussions - ActiveRoles
Viewing all articles
Browse latest Browse all 1277

How do I get the onCheckPropertyValue handler to fire first?

$
0
0

The way the WebUI handles errors is horrible!  So when checking for a policy violation if you use Throw "You can't do that!" in the onPreModify handler the MMC shows an error message and the change never happens but the web UI shows a 500 error with a page full of garbage - not nice.  Apparently if you lower the security on the web server there is a way of getting the error message to display but I don't think I want to go there especially as the answer would really be to use the onCheckPropertyValue Handler.

 

So I tested my policy with an onPreModify - so changes in ARS are blocked if they don't comply and also an onPostModify handler to roll back the change is someone makes a change outside of ARS.  This is working OK but then I hit the horrible failure message in the WebUI so I added an onCheckPropertyValue handler.  I tested the WebUI and it just fails in exactly the same way.  So I tried commenting out the onPreModify handler and the script fails totally saying "the term onPreModify is not recognised as the name of a cmdlet" - hmmm strange so I uncommented just teh fucntion name so I could get past that and the onPostModify Handler kicked in - so no error but the onCheckPropertyValue doesn't seem to run.  Finally I restored the onPreModify handler completed and retested in the MMC and on clicking OK or apply after making the changes I get the error message from the "Throw" so the onPreModify Handler is firing OK again, then I clicked OK again without correcting the change I'm making and this time the onPreCheckValue handler does fire and displays my custom error message.  The webUI never shows teh custom message as it cannot get past the onPreModify handler throw and displays the 500 error!  NASTY.

 

So am I missing something?  How do I get my onCheckPropertyValue handler to fire first?

 

My actual task is to prevent a NESTED group circular loop.  So if groupA is a member of GroupB then I cannot add GroupA as a member of GroupB because that would cause a circular loop.  Why AD allows this I do not know.  Programmatically it means any script you write has to check for an infinite loop and it appears in my environment some Linux based LDAP applications cant do this and fail if they encounter this condition.

 

Here is the full script - in case anyone else woul dliek to do the same thing in thier environment - obviously the onCheckPropertyValue handler is not working as expected until someone can tell me why :-)

 

 

 

##################################################################################################
#
# Group-PreventNestingLoops
# Version 1.0
#
##################################################################################################
#
################################################
#
# Initialisation function
#
function onInit($Context) {
$par01 = $context.AddParameter("debugging")
$par01.MultiValued = $false
$par01.PossibleValues = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
$par01.DefaultValue = "1"
$par01.Description = "Debugging EventLog Level where: 0 is no debugging; 9 is the most verbose; 1 is the least verbose"
$par01.Required = $false
#
$par02 = $Context.AddParameter("EmailTo")
$par02.MultiValued = $false
$par02.Description = "Specify the account(s) to email failure alerts, separate email address with commas."
$par02.Defaultvalue = "UAM@myDomain.com"
#
$par03 = $Context.AddParameter("EmailFrom")
$par03.MultiValued = $false
$par03.Description = "Specify the email sender address, e.g. ARSAccountStatusChange@myDomain.com"
$par03.Defaultvalue = "ARSAccountGroupNestingAlert@myDomain.com"
#
$par04 = $Context.AddParameter("SMTPServer")
$par04.MultiValued = $false
$par04.Description = "Specify the SMTP gateway server to use"
$par04.Defaultvalue = "smtp.myDomain.com"
#
}#
###########################################################################
################# MAIN FUNCTION ###########################################
###########################################################################
#
# Global Variables:
$Global:scriptVersion = "1.0"
###
################################################
#
# Helper functions
#
function IsAttributeModified ($strAttributeName, $Request)
{
# function used to detect if a specific attribute was modified as part of the object update
# $strAttributeName = the LDAP attribute name to check
# $Request = the object modified
$objEntry = $Request.GetPropertyItem($strAttributeName, $Constants.ADSTYPE_CASE_IGNORE_STRING)
if ($objEntry -eq $null) { return $false}
$nControlCode = $objEntry.ControlCode
if ($nControlCode -eq 0) { return $false }
return $true
}
#
function OutputDebugString([int]$verbosity, [string]$str )
{
# outputs debug info to the EDM event log
if ( [string]$PolicyEntry.Parameter("debugging") -ne '0' )
{
  $strDebuggingSwitch = [string]$PolicyEntry.Parameter("debugging")
  if ( $verbosity -le [int]$strDebuggingSwitch )
  {
   $EventLog.ReportEvent(2,$str)
  }
}
}
#
###########################################################################
################# EVENT HANDLERS ##########################################
###########################################################################
#
function onCheckPropertyValues($Request)  {
if ($Request.Class -ne "Group") { return }
OutputDebugString -verbosity 9 -str "Group-PreventNestingLoops onCheckPropertyValues"
if ( $(IsAttributeModified -strAttributeName 'member' -Request $Request) -eq $null ) { Return }
for ($i = 0; $i -lt $Request.PropertyCount; $i++) {
  $item = $Request.Item($i)
  $Name = $item.Name
  # enumerate the objects attributes until we locate the "member" attribute
  if ($Name -eq "member") {
   # check that the member attribute was modified
   if($item.ControlCode -eq $Constants.ADS_PROPERTY_APPEND ) {
    $members = @()
    try { Get-QADMemberOf $request.dn -Indirect | ForEach-Object { $members += $_.dn } } catch { Send-MailMessage -To "lee.andrews@myDomain.com" -From "Group-PreventNestingLoops@myDomain.com" -Subject "Error in script run" -Body "error in premodify request = $($request.dn)" }
    # iterate through the group members
    foreach ($v in $item.Values) {
     OutputDebugString -verbosity 9 -str "Value = $v"
     #try { Get-QADMemberOf $v -Indirect | ForEach-Object { $members += $_.dn } } catch { Send-MailMessage -To "lee.andrews@myDomain.com" -From "Group-PreventNestingLoops@myDomain.com" -Subject "Error in script run" -Body "error in premodify $v" }
     if ( $members -contains $v ) {
      #throw "You cannot add this group ""$v"" as it will cause a NESTING VIOLATION"
      $Request.SetPolicyComplianceInfo("member",
        $constants.EDS_POLICY_COMPLIANCE_ERROR,
        "You cannot add this group ""$v"" as it will cause a NESTING VIOLATION",$false)
     }
    } # end foreach ($v in $item.Values)
   } # end if property changed
  } # end if member found
} # end for iterate group members

 

function onPreModify($Request) {
if ($Request.Class -ne "Group") { return }
OutputDebugString -verbosity 9 -str "Group-PreventNestingLoops onPreModify"
# check that a member was added - or removed (although we don't do anything on the latter operation)
if ( $(IsAttributeModified -strAttributeName 'member' -Request $Request) -eq $null )  { Return }
for ($i = 0; $i -lt $Request.PropertyCount; $i++) {
  $item = $Request.Item($i)
  $Name = $item.Name
  # enumerate the objects attributes until we locate the "member" attribute
  if ($Name -eq "member") {
   # check that the member attribute was modified
   if($item.ControlCode -eq $Constants.ADS_PROPERTY_APPEND ) {
    $members = @()
    try { Get-QADMemberOf $request.dn -Indirect | ForEach-Object { $members += $_.dn } } catch { Send-MailMessage -To "lee.andrews@myDomain.com" -From "Group-PreventNestingLoops@myDomain.com" -Subject "Error in script run" -Body "error in premodify request = $($request.dn)" }
    # iterate through the group members
    foreach ($v in $item.Values) {
     OutputDebugString -verbosity 9 -str "Value = $v"
     #try { Get-QADMemberOf $v -Indirect | ForEach-Object { $members += $_.dn } } catch { Send-MailMessage -To "lee.andrews@myDomain.com" -From "Group-PreventNestingLoops@myDomain.com" -Subject "Error in script run" -Body "error in premodify $v" }
     if ( $members -contains $v ) { throw "You cannot add this group ""$v"" as it will cause a NESTING VIOLATION" }
    } # end foreach ($v in $item.Values)
   } # end if property changed
  } # end if member found
} # end for iterate group members
} # end function

function onPostModify($Request) {
if ($Request.Class -ne "Group") { return }
OutputDebugString -verbosity 9 -str "Group-PreventNestingLoops onPostModify"
# check that a member was added - or removed (although we don't do anything on the latter operation)
if ( $(IsAttributeModified -strAttributeName 'member' -Request $Request) -eq $null )  { Return }
for ($i = 0; $i -lt $Request.PropertyCount; $i++) {
  $item = $Request.Item($i)
  $Name = $item.Name
  # enumerate the objects attributes until we locate the "member" attribute
  if ($Name -eq "member") {
   # check that the member attribute was modified
   if($item.ControlCode -eq $Constants.ADS_PROPERTY_APPEND ) {
    $members = @()
    try { Get-QADMemberOf $request.dn -Indirect -Proxy  | ForEach-Object { $members += $_.dn } } catch { Send-MailMessage -To "lee.andrews@myDomain.com" -From "Group-PreventNestingLoops@myDomain.com" -Subject "Error in script run" -Body "error in POSTmodify $($request.dn)" }
    # iterate through the group members
    foreach ($v in $item.Values) {
     OutputDebugString -verbosity 9 -str "Group-PreventNestingLoops onPostModify Value = $v"    
     #try { Get-QADMemberOf $v -Indirect -Proxy  | ForEach-Object { $members += $_.dn } } catch { Send-MailMessage -To "lee.andrews@myDomain.com" -From "Group-PreventNestingLoops@myDomain.com" -Subject "Error in script run" -Body "error in POSTmodify value = $v request = $($request.dn)" }
     if ( $members -contains $v ) {
      $ToEmail = [string]$PolicyEntry.Parameter("EmailTo")
      $FromEmail = [string]$PolicyEntry.Parameter("EmailFrom")
      $SMTPServer = [string]$PolicyEntry.Parameter("SMTPServer")
      $ToEmail = $ToEmail.split(",")
      OutputDebugString -verbosity 9 -str "Group-PreventNestingLoops ERROR NESTED GROUP - FIXING! $($request.dn)"
      OutputDebugString -verbosity 9 -str "Group-PreventNestingLoops To Email: $toEmail FromEmail : $fromEmail SMTP Server: $smtpServer"                           
      try { Remove-QADGroupMember -Identity $request.DN -Member $v -Proxy  -Control @{OperationReason="Group-PreventNestingLoops_v$Global:scriptVersion"} } catch { Send-MailMessage -To $ToEmail -From $FromEmail -SmtpServer $SMTPServer -Subject "Group NESTING ERROR - FAILED to ROLLBACK the CHANGE" -Body "An attempt to add a group ""$v"" to ""$($request.DN)"" was blocked as it would have resulted in a Group NESTING LOOP.  This change was made using Active Directory Users and Conputers and was REVERSED by Active Rolese Server - Please investigate and advise the person attempting to change the group membership that this has been blocked as they may not realise the NESTING has been removed `n`nGroup-PreventNestingLoops To Email: $toEmail FromEmail : $fromEmail SMTP Server: $smtpServer `n the ROLLBACK ATTEMPT FAILED please manually fix" }
      Send-MailMessage -To $ToEmail -From $FromEmail -SmtpServer $SMTPServer -Subject "Group NESTING ERROR - script Version $Global:scriptVersion" -Body "An attempt to add a group:`n`n ""$v"" `n`nto `n`n""$($request.DN)"" `n`nWAS BLOCKED as it would have resulted in a Group NESTING LOOP. `n`nThis change was made using ACTIVE DIRECTORY USERS AND COMPUTERS and was REVERSED by Active Roles Server - Please investigate using CAAD and advise the person attempting to change the group membership that this has been BLOCKED as they may not realise the NESTING has been removed.`n`nNESTING LOOPS can cause non windows applications to fail as they encounter INFINITE LOOPs when checking a groups members."
     } # if ( $members -contains $v )
    } # end for each
   } # end if property changed
  } # end if member found
} # end for iterate group members
} # end function


Viewing all articles
Browse latest Browse all 1277

Trending Articles