
    Vh#                     (   d dl mZmZmZ eZdZdZd dlZdZ		 d dl
Z
dZdZ	 d dlZdZd dlmZmZ d dlmZ dd	Zd
 Zd ZddZddZd Zedk(  r e        yy# e$ r  ej                         Z	dZY Tw xY w# e$ r  ej                         ZdZY iw xY w)    )absolute_importdivisionprint_functionaW  
module: seport
short_description: Manages SELinux network port type definitions
description:
  - Manages SELinux network port type definitions.
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  ports:
    description:
      - Ports or port ranges.
      - Can be a list (since 2.6) or comma separated string.
    type: list
    elements: str
    required: true
  proto:
    description:
      - Protocol for the specified port.
    type: str
    required: true
    choices: [tcp, udp]
  setype:
    description:
      - SELinux type for the specified port.
    type: str
    required: true
  state:
    description:
      - Desired boolean value.
    type: str
    choices: [absent, present]
    default: present
  reload:
    description:
      - Reload SELinux policy after commit.
    type: bool
    default: true
  ignore_selinux_state:
    description:
      - Run independent of selinux runtime state.
    type: bool
    default: false
  local:
    description:
      - Work with local modifications only.
    type: bool
    default: false
    version_added: 5.6.0
notes:
  - The changes are persistent across reboots.
  - Not tested on any Debian based system.
requirements:
  - libselinux-python
  - policycoreutils-python
author:
  - Dan Keder (@dankeder)
ac  
- name: Allow Apache to listen on tcp port 8888
  community.general.seport:
    ports: 8888
    proto: tcp
    setype: http_port_t
    state: present

- name: Allow sshd to listen on tcp port 8991
  community.general.seport:
    ports: 8991
    proto: tcp
    setype: ssh_port_t
    state: present

- name: Allow memcached to listen on tcp ports 10000-10100 and 10112
  community.general.seport:
    ports: 10000-10100,10112
    proto: tcp
    setype: memcache_port_t
    state: present

- name: Allow memcached to listen on tcp ports 10000-10100 and 10112
  community.general.seport:
    ports:
      - 10000-10100
      - 10112
    proto: tcp
    setype: memcache_port_t
    state: present

- name: Remove tcp port 22 local modification if exists
  community.general.seport:
    ports: 22
    protocol: tcp
    setype: ssh_port_t
    state: absent
    local: true
NTF)AnsibleModulemissing_required_lib)	to_nativec                 2    | xs t        j                         S )N)selinuxis_selinux_enabled)ignore_selinux_states    l/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/seport.pyget_runtime_statusr      s    ?7#=#=#??    c                 D    | j                  |      }||f|v r|||f   S g S )aX   Get the list of ports that have the specified type definition.

    :param community.general.seport: Instance of seobject.portRecords

    :type setype: str
    :param setype: SELinux type.

    :type proto: str
    :param proto: Protocol ('tcp' or 'udp')

    :rtype: list
    :return: List of ports that have the specified SELinux type.
    )	locallist)get_all_by_type)seportsetypeprotolocalrecordss        r   semanage_port_get_portsr      s7     $$u$5G'!''	r   c                 
   t        |t              r2|j                  dd      }t        |      dk(  r|j	                  |       n||f}t        |d         t        |d         |f}| j                         }|j                  |      S )a}   Get the SELinux type of the specified port.

    :param community.general.seport: Instance of seobject.portRecords

    :type port: str
    :param port: Port or port range (example: "8080", "8080-9090")

    :type proto: str
    :param proto: Protocol ('tcp' or 'udp')

    :rtype: tuple
    :return: Tuple containing the SELinux type and MLS/MCS level, or None if not found.
    -   r   )
isinstancestrsplitlenextendintget_allget)r   portr   portskeyr   s         r   semanage_port_get_typer'      su     $

3"u:?LLtuQx=#eAh-
/CnnG;;sr   c                    d}	 t        j                  |      }	|	j                  |       t        |	|||      }
|D ]N  }||
v rd}| j                  rt        |	||      }||	j                  ||||       ;|	j                  ||||       P 	 |S # t        t        t        t        t        f$ rS}| j                  |j                  j                  dt!        |      dt#        j$                                Y d}~|S d}~ww xY w)a   Add SELinux port type definition to the policy.

    :type module: AnsibleModule
    :param module: Ansible module

    :type ports: list
    :param ports: List of ports and port ranges to add (e.g. ["8080", "8080-9090"])

    :type proto: str
    :param proto: Protocol ('tcp' or 'udp')

    :type setype: str
    :param setype: SELinux type

    :type do_reload: bool
    :param do_reload: Whether to reload SELinux policy after commit

    :type serange: str
    :param serange: SELinux MLS/MCS range (defaults to 's0')

    :type sestore: str
    :param sestore: SELinux store

    :rtype: bool
    :return: True if the policy was changed, otherwise False
    FTN: 
msg	exception)seobjectportRecords
set_reloadr   
check_moder'   addmodify
ValueErrorIOErrorKeyErrorOSErrorRuntimeError	fail_json	__class____name__r   	traceback
format_exc)moduler%   r   r   	do_reloadserangesestorer   changer   ports_by_typer$   	port_typees                 r   semanage_port_addrF      s    6 Fr%%g.)$/uM 	<D}$F  .vtUCI 

48dE7F;	<  M 7LA r1;;+?+?1NZcZnZnZpqqMrs   BB C?,AC::C?c                    d}	 t        j                  |      }|j                  |       t        ||||      }	|D ](  }
|
|	v sd}| j                  r|j                  |
|       * 	 |S # t        t        t        t        t        f$ rS}| j                  |j                  j                  dt        |      dt        j                                 Y d}~|S d}~ww xY w)aM   Delete SELinux port type definition from the policy.

    :type module: AnsibleModule
    :param module: Ansible module

    :type ports: list
    :param ports: List of ports and port ranges to delete (e.g. ["8080", "8080-9090"])

    :type proto: str
    :param proto: Protocol ('tcp' or 'udp')

    :type setype: str
    :param setype: SELinux type.

    :type do_reload: bool
    :param do_reload: Whether to reload SELinux policy after commit

    :type sestore: str
    :param sestore: SELinux store

    :rtype: bool
    :return: True if the policy was changed, otherwise False
    FTr)   r*   r+   N)r.   r/   r0   r   r1   deleter4   r5   r6   r7   r8   r9   r:   r;   r   r<   r=   )r>   r%   r   r   r?   rA   r   rB   r   rC   r$   rE   s               r   semanage_port_delrI      s    0 Fr%%g.)$/uM 	/D}$((MM$.		/ M 7LA r1;;+?+?1NZcZnZnZpqqMrs$   =A( A( A( (CACCc                  f   t        t        t        dd      t        ddd      t        dddd	g
      t        dd      t        ddddg      t        dd      t        dd            d      } t        s | j                  t	        d      t
               t        s | j                  t	        d      t               | j                  d   }t        |      s| j                  d       | j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }||||d}|dk(  rt        | |||||      |d<   n;|dk(  rt        | |||||      |d<   n!| j                  d j                  |              | j                  d!i | y )"NboolF)typedefaultlistr   T)rL   elementsrequiredtcpudp)rL   rP   choices)rL   rP   presentabsent)rL   rM   rS   )r   r%   r   r   statereloadr   )argument_specsupports_check_modezlibselinux-pythonr+   zpolicycoreutils-pythonr   z!SELinux is disabled on this host.)r,   r%   r   r   rV   rW   r   )r%   r   r   rV   )r   changedz&Invalid value of argument "state": {0} )r   dictHAVE_SELINUXr9   r   SELINUX_IMP_ERRHAVE_SEOBJECTSEOBJECT_IMP_ERRparamsr   rF   rI   format	exit_json)	r>   r   r%   r   r   rV   r?   r   results	            r   mainre     s   !%65!AFUTBED5%.IUT2E9x>STVT2FE2
 !F 12EFRab12JKWgh!==)?@23@AMM'"EMM'"E]]8$FMM'"Eh'IMM'"E 	F 	-feUFI]bcy	(	-feUFI]bcyELLUSTFvr   __main__)F)s0 F)rh   F)
__future__r   r   r   rL   __metaclass__DOCUMENTATIONEXAMPLESr<   r^   r
   r]   ImportErrorr=   r`   r.   r_   ansible.module_utils.basicr   r   +ansible.module_utils.common.text.convertersr   r   r   r'   rF   rI   re   r;   r[   r   r   <module>rp      s    A @=~&P L
  M
 K A@*60f&R.b zF c  *i**,OL  +y++-Ms"   A A6 A32A36BB