Open strarsis opened 11 months ago
This is the generated file that is passed to cupsd -t -c
for validation (which fails validation with non-zero exit code):
#
# Ansible managed
#
MaxLogSize 0
#
# Configuration file for the CUPS scheduler. See "man cupsd.conf" for a
# complete description of this file.
#
# Log general information in error_log - change "warn" to "debug"
# for troubleshooting...
LogLevel warn
# PreserveJobHistory specifies whether metadata is preserved after a job is
# printed.
PreserveJobHistory Yes
# Only listen for connections from the local machine.
ServerAlias *
Listen localhost:631
Listen /run/cups/cups.sock
# Show shared printers on the local network.
Browsing Off
BrowseLocalProtocols dnssd
# Default authentication type, when authentication is required...
DefaultAuthType Basic
# Web interface setting...
WebInterface Yes
# Restrict access to the server...
<Location />
Order allow,deny
Allow @LOCAL
</Location>
<Location /admin>
Order allow,deny
Allow @LOCAL
</Location>
<Location /admin/conf>
Order allow,deny
AuthType Default
require user @SYSTEM
Allow @LOCAL
</Location>
<Location /admin/log>
Order allow,deny
AuthType Default
require user @SYSTEM
</Location>
# Set the default printer/job policies...
<Policy default>
# Job/subscription privacy...
JobPrivateAccess default
JobPrivateValues default
SubscriptionPrivateAccess default
SubscriptionPrivateValues default
# Job-related operations must be done by the owner or an administrator...
<Limit Create-Job Print-Job Print-URI Validate-Job>
Order deny,allow
</Limit>
<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>
# All administration operations require an administrator to authenticate...
<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default CUPS-Get-Devices>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>
# All printer operations require a printer operator to authenticate...
<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>
# Only the owner or an administrator can cancel or authenticate a job...
<Limit Cancel-Job CUPS-Authenticate-Job>
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>
<Limit All>
Order deny,allow
</Limit>
</Policy>
# Set the authenticated printer/job policies...
<Policy authenticated>
# Job/subscription privacy...
JobPrivateAccess default
JobPrivateValues default
SubscriptionPrivateAccess default
SubscriptionPrivateValues default
# Job-related operations must be done by the owner or an administrator...
<Limit Create-Job Print-Job Print-URI Validate-Job>
AuthType Default
Order deny,allow
</Limit>
<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
AuthType Default
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>
# All administration operations require an administrator to authenticate...
<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>
# All printer operations require a printer operator to authenticate...
<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>
# Only the owner or an administrator can cancel or authenticate a job...
<Limit Cancel-Job CUPS-Authenticate-Job>
AuthType Default
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>
<Limit All>
Order deny,allow
</Limit>
</Policy>
# Set the kerberized printer/job policies...
<Policy kerberos>
# Job/subscription privacy...
JobPrivateAccess default
JobPrivateValues default
SubscriptionPrivateAccess default
SubscriptionPrivateValues default
# Job-related operations must be done by the owner or an administrator...
<Limit Create-Job Print-Job Print-URI Validate-Job>
AuthType Negotiate
Order deny,allow
</Limit>
<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
AuthType Negotiate
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>
# All administration operations require an administrator to authenticate...
<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>
# All printer operations require a printer operator to authenticate...
<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>
# Only the owner or an administrator can cancel or authenticate a job...
<Limit Cancel-Job CUPS-Authenticate-Job>
AuthType Negotiate
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>
<Limit All>
Order deny,allow
</Limit>
</Policy>
This cups configuration is correct.
When I copy the temporary file created by ansible to /etc/cups
the configuration test actually works!
cupsd -t -c /etc/cups/cupsd.conf.ansible
"/etc/cups/cups-files.conf" is OK.
"/etc/cups/cupsd.conf" is OK.
(Exit code 0
)
So cups
does not like the given configuration file being outside of the usual directory,
hence it fails the configuration test right at the start.
Let me check, thanks for the notification.
When I place a working config in /tmp:
cupsd -t -c /tmp/cupsd.conf
"/tmp/cups-files.conf" is OK.
"/tmp/cupsd.conf" is OK.
Especially /tmp/cups-files.conf
does not exist. This role does not place it.
Maybe a validate
command that also point so /etc/cups/cups-files.confas
cupsd -t -s /etc/cups/cups-files.conf -c %s` works better. Let me try.
By the way; I can't reproduce the issue. Can you past the variables fed to the role by your playbook/inventory/(group|host)_vars?
@robertdebock: Maybe this is an ansible version thing? The temporary file is shown when running ansible in verbose mode.
The issue is that ansible
uses the path to the temporary file in validate
.
I am using the variables that are shown in the README.
Edit: I also tried this on Ubuntu 22.04 LTS (minimal server installation), with the same issue.
Hm, the versions of Ansible. That sounds like a good lead.
I'm currently testing on Ansible 6, 7 & 8:
tox.ini
:
ansible6: ansible == 6.*
ansible7: ansible == 7.*
ansible8: ansible == 8.*
You're using Ansible-core 2.15.0, pretty recent.
And since you're using the default variable values, that's also what I'm testing. In other words, can't reproduce, so let's figure out what the differences are.
I'm not sure where to begin finding the difference between your setup and mine as you've explained all the details already.
I've added that cups-files.conf in the last push and converted some variables into booleans. (Was: "Yes"
, is yes
).
Please try 3.0.0. Be are, some variables have changed type. Were string, are boolean.
@robertdebock: I provisioned with 3.0.0
, but the error persists.
Ubuntu 22.04 LTS Server minimal base is the system used for this.
It appears that the cups
package has additional permission checks built in for the config file validation?
(Side note: I use become: yes
for root
user, as otherwise Configure cups
would fail with Destination /etc/cups not writable
.)
That could be a lead; permissions on the (temporary) files. Let me work that out. Thanks for getting back!
Some testing on the system: On Ubuntu LTS 22.04 LTS server minimal base system:
cupsd
configuration as ansible would under /home/admin/.ansible/tmp/ansible-tmp-1696464574.0848813-31244-201540201837497/source
.cupsd -t -s /etc/cups/cups-files.conf -c /home/admin/.ansible/tmp/ansible-tmp-1696464574.0848813-31244-201540201837497/source
Note that exit status is non-zero (1
) and no success messages are printed./etc
and repeat the validation command.
Note that validation still fails./etc/cups
- file name does not matter, it can still be just source
, and repeat validation command.
Note that validation now passes with zero exit status and success messages.The actual validation code (upstream) for cups
2.4.1
(as used by Ubuntu 22.04 LTS ("jammy")):
https://github.com/OpenPrinting/cups/blob/v2.4.1/scheduler/main.c#L549
The validation code uses the return value from a general function for loading configuration files:
https://github.com/OpenPrinting/cups/blob/v2.4.1/scheduler/conf.c
As this function is apparently primarily used by cupsd
daemon, error details during load are logged and not printed.
And finally, the syslog logs the following on a failed validation attempt (where the configuration file is outside of /etc/cups
):
[...] audit[1964]: AVC apparmor="DENIED" operation="open" profile="/usr/sbin/cupsd" name="/tmp/source" pid=1964 comm="cupsd" requested_mask="r" denied_mask="r" fsuid=0 ouid=1002
[...] cupsd[1964]: Unable to open "/tmp/source" - Permission denied
[...] kernel: audit: type=1400 audit(1696465133.482:33): apparmor="DENIED" operation="open" profile="/usr/sbin/cupsd" name="/tmp/source" pid=1964 comm="cupsd" requested_mask="r" denied_mask="r" fsuid=0 ouid=1002
So apparmor
denies cupsd
access to files outside of /etc/cups
.
On Ubuntu 22.04 LTS apparmor
is installed and enabled by default.
After disabling apparmor
(on a test system), the Configure cups
step works, so apparmor
was indeed the reason for this.
As apparmor
should still be used, including cupsd
, the challenge is to get around this issue with ansible
template validation.
Discussion related to appamor
blocking ansible
template validation:
Super, that's good information and I am able to reproduce the issue now. Let me think of a solution. What comes up now:
Awesome, managing apparmor
is the best way, but also the most ambitious!
@robertdebock: I tried the new adjustments, it appears that there is an incompatibility (shell interpreter? my ansible version?)
RUNNING HANDLER [robertdebock.cups : Load the AppArmor cups profile] ***********
fatal: [staging-3]: FAILED! => {"changed": true, "cmd": "set -o pipefail && cat /etc/apparmor.d/usr.sbin.cupsd | apparmor_parser -a", "delta": "0:00:00.005895", "end": "2023-10-05 18:20:23.481508", "msg": "non-zero return code", "rc": 2, "start": "2023-10-05 18:20:23.475613", "stderr": "/bin/sh: 1: set: Illegal option -o pipefail", "stderr_lines": ["/bin/sh: 1: set: Illegal option -o pipefail"], "stdout": "", "stdout
I've just released version 3.1.0. Please try.
@robertdebock: On first provision using the new role (using a system snapshot where it had not been installed yet) the configuration step works now, there is a warning though:
TASK [robertdebock.cups : Configure cups] **************************************
[WARNING]: Error deleting remote temporary files (rc: 1, stderr: })
On second provision there are no warnings.
This fix doesnt work, if the host is ubuntu, and run the molecule test. the centos 8 image havent appamor, but the host apparmor catch the cupsd, and denied the access at validation.
@elsoa-invitech: So apparmor requires a different configuration on CentOS for cupsd
to access the temporary file?
Possible solution to change validate command: copy the temp file to etc/cups directory.
validate: >-
bash -c
'cp $1 /etc/cups/cupsd-test.conf && cupsd -t -s /etc/cups/cups-files.conf -c /etc/cups/cupsd-test.conf'
- %s
Maybe you can add some randomisation for test file.
@elsoa-invitech: What exactly logs apparmor when it denies cupsd
access? This can be used to adjust the apparmor profile for CentOS. And, is there a file /etc/apparmor.d/usr.sbin.cupsd
on the CentOS system?
this is the dmesg log line:
[50956.691635] audit: type=1400 audit(1698156427.422:89): apparmor="DENIED" operation="open" class="file" profile="/usr/sbin/cupsd" name="/root/.ansible/tmp/ansible-tmp-1698156426.3260856-44738-266792785480578/source" pid=45148 comm="cupsd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
And there is no apparmor files in centos. you can check it, if you run the molecule converge, and login into the container.
The ubuntu workaround breaks idempotency also, as it registers changes due to the disable/enable apparmor steps even when no updates are required. eg. from a 20.04 managed host:
TASK [cups : Disable AppArmor cups profile] **************************************************************************************************************************************************************
changed: [10.3.128.249]
TASK [cups : Flush handlers] *****************************************************************************************************************************************************************************
RUNNING HANDLER [cups : Reload disabled AppArmor cups profile] *******************************************************************************************************************************************
changed: [10.3.128.249]
TASK [cups : Configure cups] *****************************************************************************************************************************************************************************
ok: [10.3.128.249]
TASK [cups : Enable AppArmor cups profile] ***************************************************************************************************************************************************************
changed: [10.3.128.249]
TASK [cups : Flush handlers] *****************************************************************************************************************************************************************************
RUNNING HANDLER [cups : Load the AppArmor cups profile] **************************************************************************************************************************************************
changed: [10.3.128.249]
Edit: Created a PR to fix this. Hope it helps.
Describe the bug
The
Configure cups
task fails with:failed to validate
Playbook
Output
Environment
Ubuntu 22.04.3 LTS
ansible [core 2.15.0]
Ubuntu 20.04.5 LTS