Warning: fopen(/dev/usb/lp0): Failed to open stream: Permission denied

I am trying to use mike42/escpos-php module I have the printer installed and works from terminal. But I cannot get permissions right on my localhost and I get this error.

Warning: fopen(/dev/usb/lp0): Failed to open stream: Permission denied in /var/www/html/vendor/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php on line 35

Fatal error: Uncaught Exception: Cannot initialise FilePrintConnector. in /var/www/html/vendor/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php:37 Stack trace: #0 /var/www/html/thermal_printer.php(9): Mike42\Escpos\PrintConnectors\FilePrintConnector->__construct() #1 {main} thrown in /var/www/html/vendor/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php on line 37

apache is using my user ‘andrewclarke’

[andrewclarke@localhost-live ~]$ ps aux | egrep '(apache|http)'
egrep: warning: egrep is obsolescent; using grep -E
root         995  0.0  0.1  18788 11196 ?        Ss   10:24   0:00 /usr/sbin/httpd -DFOREGROUND
apache      1056  0.0  0.2 394368 16208 ?        S    10:24   0:00 php-fpm: pool www
apache      1057  0.0  0.1 394368 10064 ?        S    10:24   0:00 php-fpm: pool www
apache      1058  0.0  0.1 394368 10064 ?        S    10:24   0:00 php-fpm: pool www
apache      1059  0.0  0.1 394368 10064 ?        S    10:24   0:00 php-fpm: pool www
apache      1060  0.0  0.1 394368 10064 ?        S    10:24   0:00 php-fpm: pool www
apache      1119  0.0  0.0  18860  6920 ?        S    10:24   0:00 /usr/sbin/httpd -DFOREGROUND
apache      1121  0.0  0.1 2420140 9372 ?        Sl   10:24   0:00 /usr/sbin/httpd -DFOREGROUND
apache      1122  0.0  0.1 2223468 8348 ?        Sl   10:24   0:00 /usr/sbin/httpd -DFOREGROUND
apache      1156  0.0  0.1 2223468 8092 ?        Sl   10:24   0:00 /usr/sbin/httpd -DFOREGROUND
andrewc+    3416  0.0  0.0 222544  2432 pts/0    S+   10:30   0:00 grep -E --color=auto (apache|http)

lp has my user in the group

[andrewclarke@localhost-live ~]$ groups 'andrewclarke'
andrewclarke : andrewclarke lp wheel

[andrewclarke@localhost-live ~]$ stat /dev/usb/lp0
  File: /dev/usb/lp0
  Size: 0         	Blocks: 0          IO Block: 4096   character special file
Device: 0,5	Inode: 811         Links: 1     Device type: 180,0
Access: (0660/crw-rw----)  Uid: (    0/    root)   Gid: (    7/      lp)
Context: system_u:object_r:printer_device_t:s0
Access: 2024-01-11 10:24:48.051135900 +0000
Modify: 2024-01-11 10:24:48.051135900 +0000
Change: 2024-01-11 10:24:48.051135900 +0000
 Birth: 2024-01-11 10:24:48.050135904 +0000

Running from the terminal using php it works as expected.

[andrewclarke@localhost-live html]$ php thermal_printer.php

I think this is the SELinux policy preventing the web server process from accessing the USB device file. You could do this (as root) to find out if this is the case and get details:

ausearch -m avc -sv no -ts recent | audit2why
1 Like

My result

type=AVC msg=audit(1704979345.613:177): avc:  denied  { getattr } for  pid=1015 comm="php-fpm" path="/dev/usb/lp0" dev="devtmpfs" ino=819 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:printer_device_t:s0 tclass=chr_file permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1704979345.631:178): avc:  denied  { read } for  pid=3066 comm="sudo" name="ts" dev="tmpfs" ino=1487 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:pam_var_run_t:s0 tclass=dir permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1704979345.631:179): avc:  denied  { read } for  pid=3066 comm="sudo" name="sudo" dev="tmpfs" ino=1486 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:pam_var_run_t:s0 tclass=dir permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1704979345.634:181): avc:  denied  { read } for  pid=3066 comm="sudo" name="shadow" dev="sda3" ino=537375 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:shadow_t:s0 tclass=file permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1704979345.640:182): avc:  denied  { read } for  pid=3067 comm="unix_chkpwd" name="shadow" dev="sda3" ino=537375 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:shadow_t:s0 tclass=file permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1704979345.640:183): avc:  denied  { read } for  pid=3066 comm="sudo" name="lectured" dev="sda3" ino=144246 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:sudo_db_t:s0 tclass=dir permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1704979347.992:184): avc:  denied  { getattr } for  pid=1015 comm="php-fpm" path="/dev/usb/lp0" dev="devtmpfs" ino=819 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:printer_device_t:s0 tclass=chr_file permissive=0

	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

I have tried to set a rule using audit2allow but it doesn’t allow me to print, still permission issue.

I have ‘disabled’ SELinux and rebooted and I still have a permission error.

Setting
chmod 666 /dev/usb/lp0

Seems to have done the trick !

The only problem I have now is on reboot I have to set this command again. How can I make this a permanent permission change ?

what are the permissions on that device before you change it?

The stat command above seems to indicate it is 660 by default, but I am not 100% confident with your group results.

Please show us the results of groups when you are logged in as your user. It will produce results similar to what you showed above but the way you did that command was different than would be given in this way.

$ groups
jvian wheel cdrom dialout vboxusers boinc libvirt

$ groups jvian
jvian : jvian wheel cdrom dialout libvirt boinc vboxusers

You are right 660

$ groups
andrewclarke lp wheel

$ groups andrewclarke
andrewclarke : andrewclarke lp wheel
$stat -c 'a%' /dev/usb/lp0
660

Before chmod command

[andrewclarke@localhost-live ~]$ ls -l /dev/usb/lp0
crw-rw---- 1 root lp 180, 0 Jan 12 09:45 /dev/usb/lp0

Ok, that shows that the file has the correct and expected permissions.
It is possible that something else may be the case now – including a potential miss-configuration of the printer.

  1. SELinux may be involved. If so then doing a restore of context may fix this – possibly with
    sudo fixfiles onboot which will set up the system to restore the context of all files on the system during the next boot and may cause a significant delay during booting next time.

  2. The device may not be correct – my system only has the lp devices under /dev and not under /dev/usb (I don’t use a usb attached printer). I don’t expect this since you say that simply changing the permissions of that file allows printing.

  3. The user that actually performs the printing may not have appropriate access.
    What happens if you do a simple test, immediately after booting and before changing the permissions with the command lpr /etc/fstab which should print the text file /etc/fstab on your default printer.

I have ‘disabled’ SELinux

This prints the text in the file /etc/fstab directly to the thermal printer as it is the default printer. as normal.

Reading other peoples settings with the same printer they also have it printing as /dev/usb/lp0