Checks a path to verify the ACE (access control entry) specified exists

    Args:
        path:  path to the file/reg key
        objectType: The type of object (FILE, DIRECTORY, REGISTRY)
        user:  user that the ACL is for
        permission:  permission to test for (READ, FULLCONTROL, etc)
        acetype:  the type of ACE (ALLOW or DENY)
        propagation:  the propagation type of the ACE (FILES, FOLDERS, KEY, KEY&SUBKEYS, SUBKEYS, etc)
        exactPermissionMatch:  the ACL must match exactly, IE if READ is specified, the user must have READ exactly and not FULLCONTROL (which also has the READ permission obviously)

    Returns (dict): 'Exists' true if the ACE exists, false if it does not

    CLI Example:

    .. code-block:: bash

        salt 'minion-id' win_dacl.check_ace c:\temp directory <username> fullcontrol

def check_ace(path, objectType, user, permission=None, acetype=None, propagation=None, exactPermissionMatch=False):
    '''
    Checks a path to verify the ACE (access control entry) specified exists

    Args:
        path:  path to the file/reg key
        objectType: The type of object (FILE, DIRECTORY, REGISTRY)
        user:  user that the ACL is for
        permission:  permission to test for (READ, FULLCONTROL, etc)
        acetype:  the type of ACE (ALLOW or DENY)
        propagation:  the propagation type of the ACE (FILES, FOLDERS, KEY, KEY&SUBKEYS, SUBKEYS, etc)
        exactPermissionMatch:  the ACL must match exactly, IE if READ is specified, the user must have READ exactly and not FULLCONTROL (which also has the READ permission obviously)

    Returns (dict): 'Exists' true if the ACE exists, false if it does not

    CLI Example:

    .. code-block:: bash

        salt 'minion-id' win_dacl.check_ace c:\temp directory <username> fullcontrol
    '''
    ret = {'result': False,
           'Exists': False,
           'comment': ''}

    dc = daclConstants()
    objectTypeBit = dc.getObjectTypeBit(objectType)
    path = dc.processPath(path, objectTypeBit)

    permission = permission.upper() if permission else None
    acetype = acetype.upper() if permission else None
    propagation = propagation.upper() if propagation else None

    permissionbit = dc.getPermissionBit(objectTypeBit, permission) if permission else None
    acetypebit = dc.getAceTypeBit(acetype) if acetype else None
    propagationbit = dc.getPropagationBit(objectTypeBit, propagation) if propagation else None

    sidRet = _getUserSid(user)
    if not sidRet['result']:
        return sidRet

    dacls = _get_dacl(path, objectTypeBit)
    ret['result'] = True
    if dacls:
        for counter in range(0, dacls.GetAceCount()):
            ace = dacls.GetAce(counter)
            if ace[2] == sidRet['sid']:
                if not acetypebit or ace[0][0] == acetypebit:
                    if not propagationbit or (ace[0][1] & propagationbit) == propagationbit:
                        if not permissionbit:
                            ret['Exists'] = True
                            return ret
                        if exactPermissionMatch:
                            if ace[1] == permissionbit:
                                ret['Exists'] = True
                                return ret
                        else:
                            if (ace[1] & permissionbit) == permissionbit:
                                ret['Exists'] = True
                                return ret
    else:
        ret['comment'] = 'No DACL found for object.'
    return ret