2.5.3.1.5 EvaluateAceCondition

A support function, EvaluateAceCondition, evaluates the ACE ApplicationData field utilizing the authorization information passed in as parameters. The ApplicationData is stored in binary format in Postfix notation. In this notation, every operator follows all of its required operands and the notion of parenthesis is built into the construction of this data.

The evaluation takes place by scanning the ApplicationData from left to right. Operands are pushed onto the stack, and when an operator is encountered, the appropriate items are popped off the stack. The result of the operation is then pushed back onto the stack.

 INT32 Result
 AuthzBasepEvaluateAceCondition(
       TOKEN Token,
       ACL Sacl,
       BYTE[] ApplicationData,
       ULONG ApplicationDataSize )
 --
 -- On entry 
 -- Token - the Authz context or NT Token representing the user.
 -- Sacl – SecurityDescriptor SACL field containing ACE’s with resource claims.
 -- ApplicationData – the condition to be evaluated.
 -- ApplicationDataSize – the length of the condition passed in.
 -- Result - The result of the evaluation. 1: true; 0: false; -1: unknown. 
     "unknown" is returned when the Token/Sacl doesn't contain enough information
     to evaluate the ApplicationData. 
  
  
 Dim StackElement
 {
     STRING Type
     -- Could be "User Attribute" from Token
     -- or "Device Attribute" from the Token
     -- or "Local Attribute" from the Token
     -- or "Resource Attribute" from the Sacl
     -- or a "Literal" from ApplicationData stream
     -- or a processed "Result Value"
  
     CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 Operand
     -- Unprocessed attribute or literal data
  
     INT32 Result
     -- Processed result of an operator evaluation
  
 }
 Dim StackElement ResultStack[]
 Dim WCHAR AttributeName
 Dim BYTE TokenType
 Set StackPos to 0
  
 IF ApplicationData does not begin with ACE_CONDITION_SIGNATURE THEN
     Set Result to -1
     Return Result
 END IF
  
 Set i to size of ACE_CONDITION_SIGNATURE
 WHILE i less than ApplicationDataSize
 - Begin scanning the ApplicationData byte stream.
  
     Set TokenType to ApplicationData[i]
  
     CASE TokenType OF
  
         -- Byte codes for attributes are defined in Byte-Code column in the table in section 2.4.4.17.8.
        -- ATTRIBUTE TOKEN
         CASE 0xf8-0xfb:
  
             -- Extraction rules for these byte codes are defined in Token Data Encoding 
             -- column in the table in section 2.4.4.17.8.
             Set AttributeName to unicode string extracted from ApplicationData stream
  
             IF TokenType equals 0xfa THEN
                 -- Resource attributes
                 CALL LookupAttributeInSacl(AttributeName, Sacl)
             ELSE
                 -- User/Device/Legacy attributes
                 CALL LookupAttributeInToken(AttributeName, Token, TokenType)
             ENDIF
         
             Set TempOperand to return value of above lookup
             CALL PushStackOperand(ResultStack, StackPos, TokenType, TempOperand)
  
             -- Bytes consumed for these byte codes are defined in Token Data Encoding column 
             -- in the table in section 2.4.4.17.8.
             Increment i by ApplicationData consumed + 1
  
  
          
         -- Byte codes for literals are defined in Byte-code column in the table in section 
         -- 2.4.4.17.5
         -- LITERALS
         CASE 0x01-0x04,0x10,0x18,0x50,0x51: 
  
           -- Extraction rules for these byte codes are defined in Token Data Encoding column in 
           -- the table in section 2.4.4.17.5
             Set TempOperand to extracted literal from ApplicationData stream
  
             CALL PushStackOperand(ResultStack, StackPos, "Literal", TempOperand)
  
             -- Bytes consumed for these byte codes are defined in Token Data Encoding column
             -- in the table in section 2.4.4.17.5
             Increment i by ApplicationData consumed + 1
  
  
         -- Byte codes for unary logical operators are defined in Byte-code column in the
         -- Unary Logical Operators table in section 2.4.4.17.7
         -- UNARY LOGICAL OPERATORS
         CASE 0xa2,0x87,0x8d:
  
             -- Requires 1 operand
             CALL PopStack(ResultStack, StackPos)
             Set Operand to popped stack item
  
             -- Validation and evaluation rules for these byte codes are defined in Processing 
             -- column in the Unary Logical Operators table in section 2.4.4.17.7
             Set TempResult to evaluation of Operand for this operator
  
             -- Push the result onto the stack
             CALL PushStackResult(ResultStack, StackPos, TempResult)
  
             -- Bytes consumed for these operators is 1
             Increment i by 1
  
         -- BINARY LOGICAL OPERATORS
         -- Byte codes for binary logical operators are defined in Byte-code column in the 
         -- Binary Logical Operators table in section 2.4.4.17.7
         CASE 0xa0,0xa1:
  
             -- Requires 2 operands
             CALL PopStack(ResultStack, StackPos)
             Set RHS to popped stack item
  
             CALL PopStack(ResultStack, StackPos)
             Set LHS to popped stack item
  
             -- Validation and evaluation rules for these byte codes are defined in Processing 
             -- column in the Binary Logical Operators table in section 2.4.4.17.7
             Set TempResult to evaluation of LHS & RHS for this operator
  
             -- Push the result onto the stack
             CALL PushStackResult(ResultStack, StackPos, TempResult)
  
             -- Bytes consumed for these operators is 1
             Increment i by 1
  
  
         -- Byte codes for unary relational operators are defined in Byte-code column in the 
         -- Unary Relational Operators table in section 2.4.4.17.6
  
         -- UNARY RELATIONAL OPERATORS
         CASE 0x89-0x8c, 0x90-0x93:
  
             -- Requires 1 operand
             CALL PopStack(ResultStack, StackPos)
             Set Operand to popped stack item
  
             -- Validation and evaluation rules for these byte codes are defined in Processing 
             -- column in the Unary Relational Operators table in section 2.4.4.17.6
             Set TempResult to evaluation of Operand for this operator
  
             -- Push the result onto the stack
             CALL PushStackResult(ResultStack, StackPos, TempResult)
  
              -- Bytes consumed for these operators is 1
             Increment i by 1
  
  
  
         -- Byte codes for binary relational operators are defined in Byte-code column in the 
         -- Binary Relational Operators table in section 2.4.4.17.6
         -- BINARY RELATIONAL OPERATORS
         CASE 0x80-0x86,0x88,0x8e,0x8f:
  
             -- Requires 1 operand
             CALL PopStack(ResultStack, StackPos)
             Set RHS to popped stack item
  
             CALL PopStack(ResultStack, StackPos)
             Set LHS to popped stack item
  
             -- Validation and evaluation rules for these byte codes are defined in Processing 
             -- column in the Binary Relational Operators table in section 2.4.4.17.6
             Set TempResult to evaluation of LHS & RHS for this operator
  
             -- Push the result onto the stack
             CALL PushStackResult(ResultStack, StackPos, TempResult)
  
             -- Bytes consumed for these operators is 1
             Increment i by 1
  
 DEFAULT CASE 
  Set Result to -1 
 Return Result
  
     END CASE
 END WHILE
  
 IF StackPos is equal to 1 THEN
     Set Result to ResultStack[0].Result
 ELSE
     Set Result to -1
 ENDIF
  
 Return Result
  
 END-SUBROUTINE