mirror of
https://github.com/ansible-collections/ansible.posix.git
synced 2026-07-25 00:44:46 +00:00
Compare commits
8 Commits
d9af430396
...
2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ac4603af5 | ||
|
|
a4805b92b7 | ||
|
|
ee1461f46c | ||
|
|
78fb77c8d5 | ||
|
|
d4ac6f63f4 | ||
|
|
b42cbb2a97 | ||
|
|
aaacdb9d13 | ||
|
|
955acdca44 |
@@ -37,8 +37,9 @@ variables:
|
||||
resources:
|
||||
containers:
|
||||
- container: default
|
||||
image: quay.io/ansible/azure-pipelines-test-container:8.0.0
|
||||
- container: legacy
|
||||
image: quay.io/ansible/azure-pipelines-test-container:7.0.0
|
||||
|
||||
pool: Standard
|
||||
|
||||
stages:
|
||||
@@ -128,6 +129,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
nameFormat: "{0}"
|
||||
testFormat: 2.17/{0}
|
||||
targets:
|
||||
@@ -145,6 +147,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
nameFormat: "{0}"
|
||||
testFormat: 2.16/{0}
|
||||
targets:
|
||||
@@ -237,6 +240,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.17/linux/{0}/1
|
||||
targets:
|
||||
- name: Fedora 39
|
||||
@@ -250,6 +254,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.16/linux/{0}/1
|
||||
targets:
|
||||
- name: Fedora 38
|
||||
@@ -266,10 +271,10 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}/1
|
||||
targets:
|
||||
- name: RHEL 10.1
|
||||
test: rhel/10.1
|
||||
- name: RHEL 9.7
|
||||
test: rhel/9.7
|
||||
- name: RHEL 10.2
|
||||
test: rhel/10.2
|
||||
- name: RHEL 9.8
|
||||
test: rhel/9.8
|
||||
- name: FreeBSD 14.4
|
||||
test: freebsd/14.4
|
||||
- name: FreeBSD 15.0
|
||||
@@ -321,8 +326,8 @@ stages:
|
||||
test: rhel/10.1
|
||||
- name: RHEL 9.7
|
||||
test: rhel/9.7
|
||||
- name: FreeBSD 14.2
|
||||
test: freebsd/14.2
|
||||
- name: FreeBSD 14.3
|
||||
test: freebsd/14.3
|
||||
- name: FreeBSD 13.5
|
||||
test: freebsd/13.5
|
||||
|
||||
@@ -347,6 +352,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.17/{0}/1
|
||||
targets:
|
||||
- name: RHEL 10.0
|
||||
@@ -360,6 +366,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.16/{0}/1
|
||||
targets:
|
||||
- name: RHEL 10.1
|
||||
|
||||
@@ -14,6 +14,12 @@ parameters:
|
||||
type: object
|
||||
default: []
|
||||
|
||||
# An optional container resource name to use for the test jobs.
|
||||
# Defaults to "default" if not specified.
|
||||
- name: container
|
||||
type: string
|
||||
default: default
|
||||
|
||||
# An optional format string used to generate the job name.
|
||||
# - {0} is the name of an item in the targets list.
|
||||
- name: nameFormat
|
||||
@@ -43,6 +49,7 @@ parameters:
|
||||
jobs:
|
||||
- template: test.yml
|
||||
parameters:
|
||||
container: ${{ parameters.container }}
|
||||
jobs:
|
||||
- ${{ if eq(length(parameters.groups), 0) }}:
|
||||
- ${{ each target in parameters.targets }}:
|
||||
|
||||
@@ -7,11 +7,17 @@ parameters:
|
||||
- name: jobs
|
||||
type: object
|
||||
|
||||
# An optional container resource name to use for the test jobs.
|
||||
# Defaults to "default" if not specified.
|
||||
- name: container
|
||||
type: string
|
||||
default: default
|
||||
|
||||
jobs:
|
||||
- ${{ each job in parameters.jobs }}:
|
||||
- job: test_${{ replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_') }}
|
||||
displayName: ${{ job.name }}
|
||||
container: default
|
||||
container: ${{ parameters.container }}
|
||||
workspace:
|
||||
clean: all
|
||||
steps:
|
||||
|
||||
@@ -4,6 +4,27 @@ ansible.posix Release Notes
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
v2.2.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is the minor release of the ``ansible.posix`` collection.
|
||||
This changelog contains all changes to the modules and plugins
|
||||
in the stable-2 branch that have been added after the release of
|
||||
``ansible.posix`` 2.2.0
|
||||
|
||||
Security Fixes
|
||||
--------------
|
||||
|
||||
- authorized_key - fix local privilege escalation via symlink-following when running as root (https://github.com/ansible-collections/ansible.posix/issues/759).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- sysctl - reload sysctl only if the sysctl file is ``/etc/sysctl.conf`` or ``/etc/sysctl.conf.local`` (https://github.com/ansible-collections/ansible.posix/issues/663).
|
||||
|
||||
v2.2.0
|
||||
======
|
||||
|
||||
|
||||
@@ -578,3 +578,27 @@ releases:
|
||||
- firewalld_info_warnings.yml
|
||||
- patch_removed.yml
|
||||
release_date: '2026-05-18'
|
||||
2.2.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- sysctl - reload sysctl only if the sysctl file is ``/etc/sysctl.conf`` or
|
||||
``/etc/sysctl.conf.local`` (https://github.com/ansible-collections/ansible.posix/issues/663).
|
||||
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
|
||||
|
||||
This changelog contains all changes to the modules and plugins
|
||||
|
||||
in the stable-2 branch that have been added after the release of
|
||||
|
||||
``ansible.posix`` 2.2.0'
|
||||
security_fixes:
|
||||
- authorized_key - fix local privilege escalation via symlink-following when
|
||||
running as root (https://github.com/ansible-collections/ansible.posix/issues/759).
|
||||
fragments:
|
||||
- 2.2.1.yml
|
||||
- 643-sysctl-docs.yml
|
||||
- 751_ci_test_container_update.yml
|
||||
- 755_ci_test_container_update.yml
|
||||
- 759_cve_2026_11837.yml
|
||||
- 763_ci_azp_update_devel.yml
|
||||
- freebsd_sysctl.yml
|
||||
release_date: '2026-07-01'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
namespace: ansible
|
||||
name: posix
|
||||
version: 2.2.0
|
||||
version: 2.2.1
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (github.com/ansible)
|
||||
|
||||
@@ -121,10 +121,10 @@ EXAMPLES = r'''
|
||||
ansible.posix.authorized_key:
|
||||
user: deploy
|
||||
state: present
|
||||
key: '{{ item }}'
|
||||
with_file:
|
||||
- public_keys/doe-jane
|
||||
- public_keys/doe-john
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- public_keys/doe-jane
|
||||
- public_keys/doe-john
|
||||
|
||||
- name: Set authorized key defining key options
|
||||
ansible.posix.authorized_key:
|
||||
@@ -307,6 +307,17 @@ class keydict(dict):
|
||||
return [item[1] for item in self.items()]
|
||||
|
||||
|
||||
def _safe_open_write(module, path, follow):
|
||||
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
|
||||
if not follow and hasattr(os, 'O_NOFOLLOW'):
|
||||
flags |= os.O_NOFOLLOW
|
||||
try:
|
||||
fd = os.open(path, flags, int('0600', 8))
|
||||
except OSError as e:
|
||||
module.fail_json(msg="File open failed %s : %s" % (path, to_native(e)))
|
||||
return fd
|
||||
|
||||
|
||||
def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False):
|
||||
"""
|
||||
Calculate name of authorized keys file, optionally creating the
|
||||
@@ -359,7 +370,7 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
|
||||
module.fail_json(msg="Failed to create directory %s : %s" % (sshdir, to_native(e)))
|
||||
if module.selinux_enabled():
|
||||
module.set_default_selinux_context(sshdir, False)
|
||||
os.chown(sshdir, uid, gid)
|
||||
os.chown(sshdir, uid, gid, follow_symlinks=follow)
|
||||
os.chmod(sshdir, int('0700', 8))
|
||||
|
||||
if not os.path.exists(keysfile):
|
||||
@@ -367,16 +378,13 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
|
||||
if not os.path.exists(basedir):
|
||||
os.makedirs(basedir)
|
||||
|
||||
f = None
|
||||
try:
|
||||
f = open(keysfile, "w") # touches file so we can set ownership and perms
|
||||
finally:
|
||||
f.close()
|
||||
fd = _safe_open_write(module, keysfile, follow)
|
||||
os.close(fd)
|
||||
if module.selinux_enabled():
|
||||
module.set_default_selinux_context(keysfile, False)
|
||||
|
||||
try:
|
||||
os.chown(keysfile, uid, gid)
|
||||
os.chown(keysfile, uid, gid, follow_symlinks=follow)
|
||||
os.chmod(keysfile, int('0600', 8))
|
||||
except OSError:
|
||||
pass
|
||||
@@ -607,7 +615,7 @@ def enforce_state(module, params):
|
||||
|
||||
# check current state -- just get the filename, don't create file
|
||||
do_write = False
|
||||
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
|
||||
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir, follow)
|
||||
existing_content = readfile(module, params["keyfile"])
|
||||
existing_keys = parsekeys(module, existing_content)
|
||||
|
||||
@@ -696,6 +704,11 @@ def enforce_state(module, params):
|
||||
|
||||
if not module.check_mode:
|
||||
writefile(module, filename, new_content)
|
||||
user_entry = pwd.getpwnam(user)
|
||||
uid = user_entry.pw_uid
|
||||
gid = user_entry.pw_gid
|
||||
os.chown(filename, uid, gid, follow_symlinks=follow)
|
||||
os.chmod(filename, int('0600', 8))
|
||||
params['changed'] = True
|
||||
|
||||
return params
|
||||
|
||||
@@ -44,6 +44,7 @@ options:
|
||||
- If V(true), performs a C(/sbin/sysctl -p) if the O(sysctl_file) is
|
||||
updated. If V(false), does not reload C(sysctl) even if the
|
||||
O(sysctl_file) is updated.
|
||||
- For FreeBSD, can not be used with O(sysctl_file) other than C(/etc/sysctl.conf) or C(/etc/sysctl.conf.local).
|
||||
type: bool
|
||||
default: true
|
||||
sysctl_file:
|
||||
@@ -56,6 +57,17 @@ options:
|
||||
- Verify token value with the sysctl command and set with C(-w) if necessary.
|
||||
type: bool
|
||||
default: false
|
||||
attributes:
|
||||
check_mode:
|
||||
support: full
|
||||
description: Can run in check_mode and return changed status prediction without modifying target.
|
||||
diff_mode:
|
||||
support: none
|
||||
description: Does not support differences output.
|
||||
platform:
|
||||
platforms: posix
|
||||
support: full
|
||||
description: Supported on POSIX-compliant systems.
|
||||
author:
|
||||
- David CHANIAL (@davixx)
|
||||
'''
|
||||
@@ -155,6 +167,11 @@ class SysctlModule(object):
|
||||
|
||||
self.platform = platform.system().lower()
|
||||
|
||||
# system specific tests
|
||||
freebsd_sysctl_files = ['/etc/sysctl.conf', '/etc/sysctl.conf.local']
|
||||
if self.platform == 'freebsd' and self.sysctl_file not in freebsd_sysctl_files and self.args['reload']:
|
||||
self.module.fail_json(msg="%s can not be reloaded. Set reload=False." % self.sysctl_file)
|
||||
|
||||
# Whitespace is bad
|
||||
self.args['name'] = self.args['name'].strip()
|
||||
self.args['value'] = self._parse_value(self.args['value'])
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
#
|
||||
# Check: keysfile is symlink and follow=false
|
||||
#
|
||||
- name: Try to add key with keysfile as symlink
|
||||
ansible.posix.authorized_key:
|
||||
user: testuser
|
||||
key: "{{ rsa_key_basic }}"
|
||||
state: present
|
||||
manage_dir: false
|
||||
follow: false
|
||||
|
||||
- name: Assert target file ownership unchanged
|
||||
ansible.builtin.stat:
|
||||
path: /tmp/symlink_test_target/target_file
|
||||
register: target_file_stat
|
||||
|
||||
- name: Verify target file is still owned by root
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- target_file_stat.stat.uid == 0
|
||||
...
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Remove testuser
|
||||
ansible.builtin.user:
|
||||
name: testuser
|
||||
state: absent
|
||||
remove: true
|
||||
|
||||
- name: Remove symlink target directory
|
||||
ansible.builtin.file:
|
||||
path: /tmp/symlink_test_target
|
||||
state: absent
|
||||
...
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: Create testuser for symlink tests
|
||||
ansible.builtin.user:
|
||||
name: testuser
|
||||
create_home: true
|
||||
register: testuser_result
|
||||
|
||||
- name: Create symlink target directory
|
||||
ansible.builtin.file:
|
||||
path: /tmp/symlink_test_target
|
||||
state: directory
|
||||
owner: root
|
||||
mode: '0700'
|
||||
|
||||
- name: Create a target file owned by root
|
||||
ansible.builtin.copy:
|
||||
dest: /tmp/symlink_test_target/target_file
|
||||
content: "sensitive data"
|
||||
owner: root
|
||||
mode: '0600'
|
||||
|
||||
- name: Remove .ssh directory if exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ testuser_result.home }}/.ssh"
|
||||
state: absent
|
||||
|
||||
- name: Create .ssh directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ testuser_result.home }}/.ssh"
|
||||
state: directory
|
||||
mode: '0700'
|
||||
|
||||
- name: Create symlink from authorized_keys to target file
|
||||
ansible.builtin.file:
|
||||
src: /tmp/symlink_test_target/target_file
|
||||
dest: "{{ testuser_result.home }}/.ssh/authorized_keys"
|
||||
state: link
|
||||
...
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
- name: Setup testing environment
|
||||
- name: Setup for testing environment
|
||||
ansible.builtin.import_tasks: setup_steps.yml
|
||||
|
||||
- name: Test for multiple keys handling
|
||||
@@ -37,3 +37,12 @@
|
||||
|
||||
- name: Test for permission denied files
|
||||
ansible.builtin.import_tasks: check_permissions.yml
|
||||
|
||||
- name: CVE-2026-11837 Setup for symlink tests
|
||||
ansible.builtin.import_tasks: check_symlink_setup.yml
|
||||
|
||||
- name: CVE-2026-11837 Test for symlink tests
|
||||
ansible.builtin.import_tasks: check_symlink.yml
|
||||
|
||||
- name: CVE-2026-11837 Cleanup symlink test
|
||||
ansible.builtin.import_tasks: check_symlink_cleanup.yml
|
||||
|
||||
Reference in New Issue
Block a user