@@ -440,6 +440,116 @@ public async Task ACLProcessor_ProcessACL_GenericAll() {
440440 Assert . Equal ( actual . RightName , EdgeNames . GenericAll ) ;
441441 }
442442
443+ [ Fact ]
444+ public async Task ACLProcessor_ProcessACL_GenericAll_WriteSPN ( ) {
445+ var expectedPrincipalType = Label . Group ;
446+ var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512" ;
447+
448+ var mockLDAPUtils = new Mock < ILdapUtils > ( ) ;
449+ var mockSecurityDescriptor = new Mock < ActiveDirectorySecurityDescriptor > ( MockBehavior . Loose , null ) ;
450+ var mockRule = new Mock < ActiveDirectoryRuleDescriptor > ( MockBehavior . Loose , null ) ;
451+ var collection = new List < ActiveDirectoryRuleDescriptor > ( ) ;
452+ mockRule . Setup ( x => x . AccessControlType ( ) ) . Returns ( AccessControlType . Allow ) ;
453+ mockRule . Setup ( x => x . IsAceInheritedFrom ( It . IsAny < string > ( ) ) ) . Returns ( true ) ;
454+ mockRule . Setup ( x => x . IdentityReference ( ) ) . Returns ( expectedPrincipalSID ) ;
455+ mockRule . Setup ( x => x . ActiveDirectoryRights ( ) ) . Returns ( ActiveDirectoryRights . GenericAll ) ;
456+ mockRule . Setup ( x => x . ObjectType ( ) ) . Returns ( new Guid ( ACEGuids . WriteSPN ) ) ;
457+ collection . Add ( mockRule . Object ) ;
458+
459+ mockSecurityDescriptor . Setup ( m => m . GetAccessRules ( It . IsAny < bool > ( ) , It . IsAny < bool > ( ) , It . IsAny < Type > ( ) ) )
460+ . Returns ( collection ) ;
461+ mockSecurityDescriptor . Setup ( m => m . GetOwner ( It . IsAny < Type > ( ) ) ) . Returns ( ( string ) null ) ;
462+ mockLDAPUtils . Setup ( x => x . MakeSecurityDescriptor ( ) ) . Returns ( mockSecurityDescriptor . Object ) ;
463+ mockLDAPUtils . Setup ( x => x . ResolveIDAndType ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
464+ . ReturnsAsync ( ( true , new TypedPrincipal ( expectedPrincipalSID , expectedPrincipalType ) ) ) ;
465+ var mockData = new [ ] { LdapResult < IDirectoryObject > . Fail ( ) } ;
466+ mockLDAPUtils . Setup ( x => x . PagedQuery ( It . IsAny < LdapQueryParameters > ( ) , It . IsAny < CancellationToken > ( ) ) )
467+ . Returns ( mockData . ToAsyncEnumerable ( ) ) ;
468+
469+ var processor = new ACLProcessor ( mockLDAPUtils . Object ) ;
470+ var bytes = Utils . B64ToBytes ( UnProtectedUserNtSecurityDescriptor ) ;
471+ var result = await processor . ProcessACL ( bytes , _testDomainName , Label . User , false ) . ToArrayAsync ( ) ;
472+
473+ Assert . Single ( result ) ;
474+ var actual = result . First ( ) ;
475+ Assert . Equal ( actual . PrincipalType , expectedPrincipalType ) ;
476+ Assert . Equal ( actual . PrincipalSID , expectedPrincipalSID ) ;
477+ Assert . False ( actual . IsInherited ) ;
478+ Assert . Equal ( actual . RightName , EdgeNames . WriteSPN ) ;
479+ }
480+
481+ [ Fact ]
482+ public async Task ACLProcessor_ProcessACL_GenericAll_ForceChangePassword ( ) {
483+ var expectedPrincipalType = Label . Group ;
484+ var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512" ;
485+
486+ var mockLDAPUtils = new Mock < ILdapUtils > ( ) ;
487+ var mockSecurityDescriptor = new Mock < ActiveDirectorySecurityDescriptor > ( MockBehavior . Loose , null ) ;
488+ var mockRule = new Mock < ActiveDirectoryRuleDescriptor > ( MockBehavior . Loose , null ) ;
489+ var collection = new List < ActiveDirectoryRuleDescriptor > ( ) ;
490+ mockRule . Setup ( x => x . AccessControlType ( ) ) . Returns ( AccessControlType . Allow ) ;
491+ mockRule . Setup ( x => x . IsAceInheritedFrom ( It . IsAny < string > ( ) ) ) . Returns ( true ) ;
492+ mockRule . Setup ( x => x . IdentityReference ( ) ) . Returns ( expectedPrincipalSID ) ;
493+ mockRule . Setup ( x => x . ActiveDirectoryRights ( ) ) . Returns ( ActiveDirectoryRights . GenericAll ) ;
494+ mockRule . Setup ( x => x . ObjectType ( ) ) . Returns ( new Guid ( ACEGuids . UserForceChangePassword ) ) ;
495+ collection . Add ( mockRule . Object ) ;
496+
497+ mockSecurityDescriptor . Setup ( m => m . GetAccessRules ( It . IsAny < bool > ( ) , It . IsAny < bool > ( ) , It . IsAny < Type > ( ) ) )
498+ . Returns ( collection ) ;
499+ mockSecurityDescriptor . Setup ( m => m . GetOwner ( It . IsAny < Type > ( ) ) ) . Returns ( ( string ) null ) ;
500+ mockLDAPUtils . Setup ( x => x . MakeSecurityDescriptor ( ) ) . Returns ( mockSecurityDescriptor . Object ) ;
501+ mockLDAPUtils . Setup ( x => x . ResolveIDAndType ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
502+ . ReturnsAsync ( ( true , new TypedPrincipal ( expectedPrincipalSID , expectedPrincipalType ) ) ) ;
503+ var mockData = new [ ] { LdapResult < IDirectoryObject > . Fail ( ) } ;
504+ mockLDAPUtils . Setup ( x => x . PagedQuery ( It . IsAny < LdapQueryParameters > ( ) , It . IsAny < CancellationToken > ( ) ) )
505+ . Returns ( mockData . ToAsyncEnumerable ( ) ) ;
506+
507+ var processor = new ACLProcessor ( mockLDAPUtils . Object ) ;
508+ var bytes = Utils . B64ToBytes ( UnProtectedUserNtSecurityDescriptor ) ;
509+ var result = await processor . ProcessACL ( bytes , _testDomainName , Label . User , false ) . ToArrayAsync ( ) ;
510+
511+ Assert . Single ( result ) ;
512+ var actual = result . First ( ) ;
513+ Assert . Equal ( actual . PrincipalType , expectedPrincipalType ) ;
514+ Assert . Equal ( actual . PrincipalSID , expectedPrincipalSID ) ;
515+ Assert . False ( actual . IsInherited ) ;
516+ Assert . Equal ( actual . RightName , EdgeNames . ForceChangePassword ) ;
517+ }
518+
519+ [ Fact ]
520+ public async Task ACLProcessor_ProcessACL_GenericAll_WrongOjectType ( ) {
521+ var expectedPrincipalType = Label . Group ;
522+ var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512" ;
523+ var expectedRightName = ActiveDirectoryRights . GenericAll ;
524+
525+ var mockLDAPUtils = new Mock < ILdapUtils > ( ) ;
526+ var mockSecurityDescriptor = new Mock < ActiveDirectorySecurityDescriptor > ( MockBehavior . Loose , null ) ;
527+ var mockRule = new Mock < ActiveDirectoryRuleDescriptor > ( MockBehavior . Loose , null ) ;
528+ var collection = new List < ActiveDirectoryRuleDescriptor > ( ) ;
529+ mockRule . Setup ( x => x . AccessControlType ( ) ) . Returns ( AccessControlType . Allow ) ;
530+ mockRule . Setup ( x => x . IsAceInheritedFrom ( It . IsAny < string > ( ) ) ) . Returns ( true ) ;
531+ mockRule . Setup ( x => x . IdentityReference ( ) ) . Returns ( expectedPrincipalSID ) ;
532+ mockRule . Setup ( x => x . ActiveDirectoryRights ( ) ) . Returns ( expectedRightName ) ;
533+ mockRule . Setup ( x => x . ObjectType ( ) ) . Returns ( new Guid ( ACEGuids . WriteTitle ) ) ;
534+ collection . Add ( mockRule . Object ) ;
535+
536+ mockSecurityDescriptor . Setup ( m => m . GetAccessRules ( It . IsAny < bool > ( ) , It . IsAny < bool > ( ) , It . IsAny < Type > ( ) ) )
537+ . Returns ( collection ) ;
538+ mockSecurityDescriptor . Setup ( m => m . GetOwner ( It . IsAny < Type > ( ) ) ) . Returns ( ( string ) null ) ;
539+ mockLDAPUtils . Setup ( x => x . MakeSecurityDescriptor ( ) ) . Returns ( mockSecurityDescriptor . Object ) ;
540+ mockLDAPUtils . Setup ( x => x . ResolveIDAndType ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
541+ . ReturnsAsync ( ( true , new TypedPrincipal ( expectedPrincipalSID , expectedPrincipalType ) ) ) ;
542+ var mockData = new [ ] { LdapResult < IDirectoryObject > . Fail ( ) } ;
543+ mockLDAPUtils . Setup ( x => x . PagedQuery ( It . IsAny < LdapQueryParameters > ( ) , It . IsAny < CancellationToken > ( ) ) )
544+ . Returns ( mockData . ToAsyncEnumerable ( ) ) ;
545+
546+ var processor = new ACLProcessor ( mockLDAPUtils . Object ) ;
547+ var bytes = Utils . B64ToBytes ( UnProtectedUserNtSecurityDescriptor ) ;
548+ var result = await processor . ProcessACL ( bytes , _testDomainName , Label . User , false ) . ToArrayAsync ( ) ;
549+
550+ Assert . Empty ( result ) ;
551+ }
552+
443553 [ Fact ]
444554 public async Task ACLProcessor_ProcessACL_WriteDacl ( ) {
445555 var expectedPrincipalType = Label . Group ;
@@ -479,6 +589,40 @@ public async Task ACLProcessor_ProcessACL_WriteDacl() {
479589 Assert . Equal ( actual . RightName , expectedRightName . ToString ( ) ) ;
480590 }
481591
592+ [ Fact ]
593+ public async Task ACLProcessor_ProcessACL_WriteDacl_WrongOjectType ( ) {
594+ var expectedPrincipalType = Label . Group ;
595+ var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512" ;
596+ var expectedRightName = ActiveDirectoryRights . WriteDacl ;
597+
598+ var mockLDAPUtils = new Mock < ILdapUtils > ( ) ;
599+ var mockSecurityDescriptor = new Mock < ActiveDirectorySecurityDescriptor > ( MockBehavior . Loose , null ) ;
600+ var mockRule = new Mock < ActiveDirectoryRuleDescriptor > ( MockBehavior . Loose , null ) ;
601+ var collection = new List < ActiveDirectoryRuleDescriptor > ( ) ;
602+ mockRule . Setup ( x => x . AccessControlType ( ) ) . Returns ( AccessControlType . Allow ) ;
603+ mockRule . Setup ( x => x . IsAceInheritedFrom ( It . IsAny < string > ( ) ) ) . Returns ( true ) ;
604+ mockRule . Setup ( x => x . IdentityReference ( ) ) . Returns ( expectedPrincipalSID ) ;
605+ mockRule . Setup ( x => x . ActiveDirectoryRights ( ) ) . Returns ( expectedRightName ) ;
606+ mockRule . Setup ( x => x . ObjectType ( ) ) . Returns ( new Guid ( ACEGuids . WriteSPN ) ) ;
607+ collection . Add ( mockRule . Object ) ;
608+
609+ mockSecurityDescriptor . Setup ( m => m . GetAccessRules ( It . IsAny < bool > ( ) , It . IsAny < bool > ( ) , It . IsAny < Type > ( ) ) )
610+ . Returns ( collection ) ;
611+ mockSecurityDescriptor . Setup ( m => m . GetOwner ( It . IsAny < Type > ( ) ) ) . Returns ( ( string ) null ) ;
612+ mockLDAPUtils . Setup ( x => x . MakeSecurityDescriptor ( ) ) . Returns ( mockSecurityDescriptor . Object ) ;
613+ mockLDAPUtils . Setup ( x => x . ResolveIDAndType ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
614+ . ReturnsAsync ( ( true , new TypedPrincipal ( expectedPrincipalSID , expectedPrincipalType ) ) ) ;
615+ var mockData = new [ ] { LdapResult < IDirectoryObject > . Fail ( ) } ;
616+ mockLDAPUtils . Setup ( x => x . PagedQuery ( It . IsAny < LdapQueryParameters > ( ) , It . IsAny < CancellationToken > ( ) ) )
617+ . Returns ( mockData . ToAsyncEnumerable ( ) ) ;
618+
619+ var processor = new ACLProcessor ( mockLDAPUtils . Object ) ;
620+ var bytes = Utils . B64ToBytes ( UnProtectedUserNtSecurityDescriptor ) ;
621+ var result = await processor . ProcessACL ( bytes , _testDomainName , Label . User , false ) . ToArrayAsync ( ) ;
622+
623+ Assert . Empty ( result ) ;
624+ }
625+
482626 [ Fact ]
483627 public async Task ACLProcessor_ProcessACL_WriteOwner ( ) {
484628 var expectedPrincipalType = Label . Group ;
@@ -518,6 +662,40 @@ public async Task ACLProcessor_ProcessACL_WriteOwner() {
518662 Assert . Equal ( actual . RightName , expectedRightName . ToString ( ) ) ;
519663 }
520664
665+ [ Fact ]
666+ public async Task ACLProcessor_ProcessACL_WriteOwner_WrongOjectType ( ) {
667+ var expectedPrincipalType = Label . Group ;
668+ var expectedPrincipalSID = "S-1-5-21-3130019616-2776909439-2417379446-512" ;
669+ var expectedRightName = ActiveDirectoryRights . WriteOwner ;
670+
671+ var mockLDAPUtils = new Mock < ILdapUtils > ( ) ;
672+ var mockSecurityDescriptor = new Mock < ActiveDirectorySecurityDescriptor > ( MockBehavior . Loose , null ) ;
673+ var mockRule = new Mock < ActiveDirectoryRuleDescriptor > ( MockBehavior . Loose , null ) ;
674+ var collection = new List < ActiveDirectoryRuleDescriptor > ( ) ;
675+ mockRule . Setup ( x => x . AccessControlType ( ) ) . Returns ( AccessControlType . Allow ) ;
676+ mockRule . Setup ( x => x . IsAceInheritedFrom ( It . IsAny < string > ( ) ) ) . Returns ( true ) ;
677+ mockRule . Setup ( x => x . IdentityReference ( ) ) . Returns ( expectedPrincipalSID ) ;
678+ mockRule . Setup ( x => x . ActiveDirectoryRights ( ) ) . Returns ( expectedRightName ) ;
679+ mockRule . Setup ( x => x . ObjectType ( ) ) . Returns ( new Guid ( ACEGuids . WriteSPN ) ) ;
680+ collection . Add ( mockRule . Object ) ;
681+
682+ mockSecurityDescriptor . Setup ( m => m . GetAccessRules ( It . IsAny < bool > ( ) , It . IsAny < bool > ( ) , It . IsAny < Type > ( ) ) )
683+ . Returns ( collection ) ;
684+ mockSecurityDescriptor . Setup ( m => m . GetOwner ( It . IsAny < Type > ( ) ) ) . Returns ( ( string ) null ) ;
685+ mockLDAPUtils . Setup ( x => x . MakeSecurityDescriptor ( ) ) . Returns ( mockSecurityDescriptor . Object ) ;
686+ mockLDAPUtils . Setup ( x => x . ResolveIDAndType ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
687+ . ReturnsAsync ( ( true , new TypedPrincipal ( expectedPrincipalSID , expectedPrincipalType ) ) ) ;
688+ var mockData = new [ ] { LdapResult < IDirectoryObject > . Fail ( ) } ;
689+ mockLDAPUtils . Setup ( x => x . PagedQuery ( It . IsAny < LdapQueryParameters > ( ) , It . IsAny < CancellationToken > ( ) ) )
690+ . Returns ( mockData . ToAsyncEnumerable ( ) ) ;
691+
692+ var processor = new ACLProcessor ( mockLDAPUtils . Object ) ;
693+ var bytes = Utils . B64ToBytes ( UnProtectedUserNtSecurityDescriptor ) ;
694+ var result = await processor . ProcessACL ( bytes , _testDomainName , Label . User , false ) . ToArrayAsync ( ) ;
695+
696+ Assert . Empty ( result ) ;
697+ }
698+
521699 [ Fact ]
522700 public async Task ACLProcessor_ProcessACL_Self ( ) {
523701 var expectedPrincipalType = Label . Group ;
0 commit comments