HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.109.1.lve.el8.x86_64 #1 SMP Thu Mar 5 20:23:46 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.30
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/beacons/__pycache__/btmp.cpython-310.pyc
o

�N�g�!�@s�dZddlZddlZddlZddlZddlZddlZddlZdZ	dZ
dZgd�Ze�
e�ZdZe�e�Zz
ddlmZdZWneyId	ZYnwd
d�Zdd
�Zdd�Zdd�Zdd�Zdd�Zdd�ZdS)a?	
Beacon to fire events at failed login of users

.. versionadded:: 2015.5.0

Example Configuration
=====================

.. code-block:: yaml

    # Fire events on all failed logins
    beacons:
      btmp: []

    # Matching on user name, using a default time range
    beacons:
      btmp:
        - users:
            gareth:
        - defaults:
            time_range:
                start: '8am'
                end: '4pm'

    # Matching on user name, overriding the default time range
    beacons:
      btmp:
        - users:
            gareth:
                time_range:
                    start: '8am'
                    end: '4pm'
        - defaults:
            time_range:
                start: '8am'
                end: '4pm'

    # Matching on group name, overriding the default time range
    beacons:
      btmp:
        - groups:
            users:
                time_range:
                    start: '8am'
                    end: '4pm'
        - defaults:
            time_range:
                start: '8am'
                end: '4pm'


Use Case: Posting Failed Login Events to Slack
==============================================

This can be done using the following reactor SLS:

.. code-block:: jinja

    report-wtmp:
      runner.salt.cmd:
        - args:
          - fun: slack.post_message
          - channel: mychannel      # Slack channel
          - from_name: someuser     # Slack user
          - message: "Failed login from `{{ data.get('user', '') or 'unknown user' }}` on `{{ data['id'] }}`"

Match the event like so in the master config file:

.. code-block:: yaml

    reactor:

      - 'salt/beacon/*/btmp/':
        - salt://reactor/btmp.sls

.. note::
    This approach uses the :py:mod:`slack execution module
    <salt.modules.slack_notify>` directly on the master, and therefore requires
    that the master has a slack API key in its configuration:

    .. code-block:: yaml

        slack:
          api_key: xoxb-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX

    See the :py:mod:`slack execution module <salt.modules.slack_notify>`
    documentation for more information. While you can use an individual user's
    API key to post to Slack, a bot user is likely better suited for this. The
    :py:mod:`slack engine <salt.engines.slack>` documentation has information
    on how to set up a bot user.
�NZbtmpz
/var/log/btmpshi32s4s32s256shhiii4i20x)
�typeZPID�lineZinittab�user�hostname�exit_status�session�time�addrzbtmp.locTFcCs0tj�t�rtSt�d�}t�dt|�d|fS)Nz does not exist.zUnable to load %s beacon: %sF)�os�path�isfile�BTMP�__virtualname__�log�error)�err_msg�r�E/opt/saltstack/salt/lib/python3.10/site-packages/salt/beacons/btmp.py�__virtual__�s

rcsD�s||fSt�t�sd}d}t�fdd�dD��sd}d}||fS)�
    Check time range
    Fz>The time_range parameter for btmp beacon must be a dictionary.c3s�|]}|�vVqdS)Nr)�.0�k��trangerr�	<genexpr>�s�z'_validate_time_range.<locals>.<genexpr>)�start�endzJThe time_range parameter for btmp beacon must contain start & end options.)�
isinstance�dict�all)r�status�msgrrr�_validate_time_range�s
�r"cCsFtd|�}|st�d|�dS|dD]}||vr ||||<qdS)z
    Gather group members
    z
group.infoz"Group %s does not exist, ignoring.N�members)Z__salt__r�warning)�group�groups�users�_group�memberrrr�_gather_group_members�s��r*cCsLtrt�|d�}t�|d�}t||ko|k�S�St�d�dS)rrrzDateutil is required.F)�_TIME_SUPPORTED�dateutil_parser�parse�boolrr)�
time_range�nowZ_startZ_endrrr�_check_time_range�s
r1cCsttvrttSdS)z)
    return the active file location
    N)�LOC_KEY�__context__rrrr�_get_loc�s�r4cCs@d}d}t|t�sd}d}||fStjj�|�}d|vrGt|dt�s(d}d}n|dD]}|d|�di�}t|||�\}}q,|sG||fSd|vrvt|dt�sWd}d	}n|dD]}|d|�di�}t|||�\}}q[|sv||fSd
|vr�t|d
t�s�d}d}n|d
�di�}t|||�\}}|s�||fS||fS)z+
    Validate the beacon configuration
    TzValid beacon configurationFz-Configuration for btmp beacon must be a list.r'z8User configuration for btmp beacon must be a dictionary.r/r&z9Group configuration for btmp beacon must be a dictionary.�defaultsz<Defaults configuration for btmp beacon must be a dictionary.)	r�list�salt�utilsZbeaconsZlist_to_dictr�getr")�configZvstatusZvmsgrZ_time_ranger%rrr�validate�sD
%�r;cCs8g}i}i}d}|D]}d|vr|d}d|vr|d}d|vr$|d}q
tjj�td���}t�td�}|dkrM|�dd�|�	�tt<|Wd�S|�|�	t
j
��}|�t
�}	t|	�t
krl|Wd�S|�	�tt<t�t|	�}
i}tt�D].\}}
|
|||
<t||
ttf�r�t||
t�r�tjj�||
�||
<||
�d	�||
<q~|D]}t|||�q�|r�|d
|vr�||d
}t|t�r�d|vr�t|d|�r�|�|�n4|r�d|vr�t|d|�r�|�|�n!|�|�n|�rd|v�rt|d|��r
|�|�n|�|�qS1�swY|S)zM
    Read the last btmp file and return information on the failed logins
    Nr'r&r5�rbr�T�rr/)r7r8�filesZfopenr
r3r9r2�seek�tell�datetimer0�read�SIZE�len�struct�unpack�FMT�	enumerate�FIELDSr�str�bytesZstringutilsZ
to_unicode�stripr*rr1�append)r:�retr'r&r5Zconfig_itemZfp_�locr0�raw�pack�eventZind�fieldr%�_userrrr�beacon�sv��


�
�
�
�
�
�
��,rV)�__doc__rB�loggingr
rFZsalt.utils.beaconsr7Zsalt.utils.filesZsalt.utils.stringutilsrr
rHrJ�calcsizerDr2�	getLogger�__name__rZdateutil.parser�parserr,r+�ImportErrorrr"r*r1r4r;rVrrrr�<module>s8\

�2