@@ -518,19 +518,42 @@ private static NtResult<NtToken> DuplicateForAccessCheck(NtToken token, bool thr
518518 }
519519 }
520520
521+ private static SafeArrayBuffer < ObjectTypeList > ConvertObjectTypes ( IEnumerable < ObjectTypeEntry > object_types )
522+ {
523+ if ( object_types == null || ! object_types . Any ( ) )
524+ return SafeArrayBuffer < ObjectTypeList > . Null ;
525+
526+ var guids = object_types . Select ( o => o . ObjectType ) . ToArray ( ) ;
527+ var ret = new SafeArrayBuffer < ObjectTypeList > ( new ObjectTypeList [ guids . Length ] , guids . Length * 16 ) ;
528+ try
529+ {
530+ IntPtr ptr = ret . Data . DangerousGetHandle ( ) ;
531+ var arr = object_types . Select ( ( t , i ) => new ObjectTypeList ( ) { Level = ( short ) t . Level , ObjectType = ptr + ( i * 16 ) } ) . ToArray ( ) ;
532+ ret . WriteArray ( 0 , arr , 0 , arr . Length ) ;
533+ ret . Data . WriteArray ( 0 , guids , 0 , guids . Length ) ;
534+ return ret ;
535+ }
536+ catch
537+ {
538+ ret ? . Dispose ( ) ;
539+ throw ;
540+ }
541+ }
542+
521543 /// <summary>
522544 /// Do an access check between a security descriptor and a token to determine the allowed access.
523545 /// </summary>
524546 /// <param name="sd">The security descriptor</param>
525547 /// <param name="token">The access token.</param>
526- /// <param name="access_rights ">The set of access rights to check against</param>
548+ /// <param name="desired_access ">The set of access rights to check against</param>
527549 /// <param name="principal">An optional principal SID used to replace the SELF SID in a security descriptor.</param>
528550 /// <param name="generic_mapping">The type specific generic mapping (get from corresponding NtType entry).</param>
551+ /// <param name="object_types">List of object types to check against.</param>
529552 /// <param name="throw_on_error">True to throw on error.</param>
530553 /// <returns>The result of the access check.</returns>
531554 /// <exception cref="NtException">Thrown if an error occurred in the access check.</exception>
532555 public static NtResult < AccessCheckResult > AccessCheck ( SecurityDescriptor sd , NtToken token ,
533- AccessMask access_rights , Sid principal , GenericMapping generic_mapping ,
556+ AccessMask desired_access , Sid principal , GenericMapping generic_mapping , IEnumerable < ObjectTypeEntry > object_types ,
534557 bool throw_on_error )
535558 {
536559 if ( sd == null )
@@ -543,7 +566,7 @@ public static NtResult<AccessCheckResult> AccessCheck(SecurityDescriptor sd, NtT
543566 throw new ArgumentNullException ( "token" ) ;
544567 }
545568
546- if ( access_rights . IsEmpty )
569+ if ( desired_access . IsEmpty )
547570 {
548571 return new AccessCheckResult ( NtStatus . STATUS_ACCESS_DENIED , 0 , null ) . CreateResult ( ) ;
549572 }
@@ -558,13 +581,14 @@ public static NtResult<AccessCheckResult> AccessCheck(SecurityDescriptor sd, NtT
558581 }
559582 var self_sid = list . AddResource ( principal ? . ToSafeBuffer ( ) ?? SafeSidBufferHandle . Null ) ;
560583 var privs = list . AddResource ( new SafePrivilegeSetBuffer ( ) ) ;
584+ var object_type_list = list . AddResource ( ConvertObjectTypes ( object_types ) ) ;
561585 int repeat_count = 1 ;
562586
563587 while ( true )
564588 {
565589 int buffer_length = privs . Length ;
566- NtStatus status = NtSystemCalls . NtAccessCheckByType ( sd_buffer , self_sid , imp_token . Result . Handle , access_rights ,
567- SafeHGlobalBuffer . Null , 0 , ref generic_mapping , privs ,
590+ NtStatus status = NtSystemCalls . NtAccessCheckByType ( sd_buffer , self_sid , imp_token . Result . Handle , desired_access ,
591+ object_type_list , 0 , ref generic_mapping , privs ,
568592 ref buffer_length , out AccessMask granted_access , out NtStatus result_status ) ;
569593 if ( repeat_count == 0 || status != NtStatus . STATUS_BUFFER_TOO_SMALL )
570594 {
@@ -583,15 +607,33 @@ public static NtResult<AccessCheckResult> AccessCheck(SecurityDescriptor sd, NtT
583607 /// </summary>
584608 /// <param name="sd">The security descriptor</param>
585609 /// <param name="token">The access token.</param>
586- /// <param name="access_rights">The set of access rights to check against</param>
610+ /// <param name="desired_access">The set of access rights to check against</param>
611+ /// <param name="principal">An optional principal SID used to replace the SELF SID in a security descriptor.</param>
612+ /// <param name="generic_mapping">The type specific generic mapping (get from corresponding NtType entry).</param>
613+ /// <param name="throw_on_error">True to throw on error.</param>
614+ /// <returns>The result of the access check.</returns>
615+ /// <exception cref="NtException">Thrown if an error occurred in the access check.</exception>
616+ public static NtResult < AccessCheckResult > AccessCheck ( SecurityDescriptor sd , NtToken token ,
617+ AccessMask desired_access , Sid principal , GenericMapping generic_mapping ,
618+ bool throw_on_error )
619+ {
620+ return AccessCheck ( sd , token , desired_access , principal , generic_mapping , null , throw_on_error ) ;
621+ }
622+
623+ /// <summary>
624+ /// Do an access check between a security descriptor and a token to determine the allowed access.
625+ /// </summary>
626+ /// <param name="sd">The security descriptor</param>
627+ /// <param name="token">The access token.</param>
628+ /// <param name="desired_access">The set of access rights to check against</param>
587629 /// <param name="principal">An optional principal SID used to replace the SELF SID in a security descriptor.</param>
588630 /// <param name="generic_mapping">The type specific generic mapping (get from corresponding NtType entry).</param>
589631 /// <returns>The result of the access check.</returns>
590632 /// <exception cref="NtException">Thrown if an error occurred in the access check.</exception>
591633 public static AccessCheckResult AccessCheck ( SecurityDescriptor sd , NtToken token ,
592- AccessMask access_rights , Sid principal , GenericMapping generic_mapping )
634+ AccessMask desired_access , Sid principal , GenericMapping generic_mapping )
593635 {
594- return AccessCheck ( sd , token , access_rights , principal , generic_mapping , true ) . Result ;
636+ return AccessCheck ( sd , token , desired_access , principal , generic_mapping , true ) . Result ;
595637 }
596638
597639 /// <summary>
0 commit comments