Enable Constrained Delegation with a Perl Script

An Active Directory Script to Enable Constrained Delegation:  Delegation is a confusing word (used for different things in AD). In this case, delegation means "allowed to impersonate". For example, if a user logs onto a web server, and the web server must get data from a database or a file share on behalf of the user, the web server must impersonate the user when logging into the database or fileshare. In order for this to work, you must configure the web server's computer account in Active Directory to be "trusted for delegation".

There are two options for delegation: trusted for delegation to any service (wide open), and trusted for delegation to specified services only (contrained).

Two attributes in Active Directory control delegation. One is the userAccountControl attribute, and the other is the msDs-AllowedToDelegateTo attribute. The userAccountControl attribute contains a number that represents a binary bitmask. The msDs-AllowedToDelegateTo attribute contains a list of services that the computer is allowed to delegate to. To enable wide-open delegation we set a specific bit in the userAccountControl attribute, and clear the contents of msDs-AllowedToDelegateTo. To enable constrained delegation, we clear the userAccountControl bit and populate the list of services in the msDs-AllowedToDelegateTo attribute.

You can see a script to configure wide open trust for delegation here.

Below is an example of how to configure constrained delegation. We specify the name of the computer and the SPN (servicePrincipalName) that we want to allow this computer to access when impersonating a user. We search for the computer account using ADO, then we add that SPN (fully qualified and shortened) to the msDs-AllowedToDelegateTo attribute. The attribute is multivalued, so just in case there are already entries, we get the existing entries, then add our new ones, so we don't overwrite the existing list.

use Win32::OLE;
$TRUSTED_FOR_DELEGATION = 524288;
$computer="myComputer";
$spn="HTTP/myweb.mydomain.com";
$base="<GC://".Win32::OLE->GetObject("LDAP://RootDSE")->Get("RootDomainNamingContext").">";
$connection = Win32::OLE->new("ADODB.Connection");
$connection->{Provider} = "ADsDSOObject";
$connection->Open("ADSI Provider");
$command=Win32::OLE->new("ADODB.Command");
$command->{ActiveConnection}=$connection;
$command->{Properties}->{'Page Size'}=1000;
$rs = Win32::OLE->new("ADODB.RecordSet");
$command->{CommandText}="$base;(cn=$computer);distinguishedName;subtree";
$rs=$command->Execute;
if($rs->{recordCount} < 1){ print "Computer account not found\n"; }
until ($rs->EOF){
 $dn=$rs->Fields(0)->{Value};
 if($obj=Win32::OLE->GetObject("LDAP://$dn")){
  print "$obj->{userAccountControl}\n";
  if($obj->{userAccountControl} & $TRUSTED_FOR_DELEGATION){ $obj->{userAccountControl} ^= $TRUSTED_FOR_DELEGATION; }
  $spns=$obj->Get("msDS-AllowedToDelegateTo");
  push(@{$spns},$spn);
  ($shortspn,$domain)=split /\./,$spn;
  push(@{$spns},$shortspn);
  $obj->Put('msDS-AllowedToDelegateTo',$spns);
  $obj->SetInfo();
  $error=Win32::OLE->LastError();
  if($error == 0){
   print uc($computer)." configured for constrained delegation successfully\n";
  }else{
   print "Failed with error $error\n";
  }
 }else{
  print "Failed to connect to computer object\n";
 }
 $rs->MoveNext;
}

0 comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...