10

I want to scan from my PHP script. I'm using Ubuntu 14.04 LTS, a Brother MFC-7840W scanner (located at work), and a Brother MFC-9840CDW (located at home). I can scan from the terminal and PHP when either scanner is connected to the computer as a network scanner. However, I cannot scan from PHP when either scanner is connected to the computer as a USB scanner (I can still scan from terminal).

Why is my PHP script unable to access the USB scanner(s) but $USER is able to?

I started this question at work, but now I am at home, so I will display my attempt to access the Brother MFC-9840CDW USB scanner from my PHP script.

Here is the snippet of PHP code that I am using to scan:

if($_POST['ScanDevice'] == "brother3:net1;dev0") // if MFC-7840W network scanner
{$scanner = escapeshellarg($_POST['ScanDevice']);} 
elseif($_POST['ScanDevice'] == "brother3:bus3;dev1") // if MFC-7840W USB scanner
{$scanner = escapeshellarg($_POST['ScanDevice']);}
elseif($_POST['ScanDevice'] == "brother3:net1;dev1") // if MFC-9840CDW network scanner
{$scanner = escapeshellarg($_POST['ScanDevice']);}
elseif($_POST['ScanDevice'] == "brother3:bus6;dev1") // if MFC-9840CDW USB scanner
{$scanner = escapeshellarg($_POST['ScanDevice']);}

$command = "scanimage -d {$scanner} --resolution {$_POST[ScanResolution]} --mode {$_POST[ScanColor]}  > {$filename}";

echo exec($command,$op,$result);
if($result > 0)
{die("ERROR");}

The PHP script works for the network scanner(s) but does not work for the USB scanner(s).
If I select either of the USB scanners (currently MFC-9840CDW) and run the script, then the file /var/log/apache2/error.log shows:

scanimage: open of device brother3:bus6;dev1 failed: Invalid argument  

The question arises: Does the device brother3:bus6;dev1 exist?

Here is what scanimage --list-devices shows when entered in the terminal at home (where MFC-9840CDW is):

[pixma] udp_command: No data received (select): timed out
[pixma] udp_command: No data received (select): timed out
[pixma] udp_command: No data received (select): timed out
[pixma] Cannot read scanner make & model: �+�&
device `brother3:net1;dev1' is a Brother MFC-7840W SCANNER
device `brother3:net1;dev0' is a Brother MFC-9840CDW Scanner-MFC-9840CDW
device `brother3:bus6;dev1' is a Brother MFC-9840CDW USB scanner

To demonstrate that the USB scanner(s) work for $USER, I enter the following command in the terminal:

scanimage --test -d 'brother3:bus6;dev1'  

which shows:

scanimage: rounded value of br-x from 215.9 to 215.88
scanimage: rounded value of br-y from 355.6 to 355.567
scanimage: scanning image of size 1664x2776 pixels at 24 bits/pixel
scanimage: acquiring RGB frame, 8 bits/sample
scanimage: reading one scanline, 4992 bytes...  PASS
scanimage: reading one byte...      PASS
scanimage: stepped read, 2 bytes...     PASS
scanimage: stepped read, 4 bytes...     PASS  

To demonstrate that user www-data cannot access the USB scanner(s), I enter the following command in the terminal:

sudo -u www-data scanimage --test -d 'brother3:bus6;dev1'  

which shows:

scanimage: open of device brother3:bus6;dev1 failed: Invalid argument
Arya
  • 566
  • 2
  • 9
  • 22
  • 3
    Apache may not have the rights to use your hardware, which leads to the open failure. You can use su/sudo to try the command in your shell running as your apache user. Anyway, you must have granted some rights to your user to be allowed to scan, do the same for apache's user, or create a sudo entry for apache for `scanimage`. – Aif Dec 11 '14 at 23:41
  • what does `print_r($op)` say? Permission denied? – blots Dec 11 '14 at 23:56
  • 2
    @Carpetsmoker I said to try to impersonate apache user to try, and fix rights. Otherwize, grant sudo but *only* for scanimage command, which is not a big deal. This is one of the most famous use case of sudo (granting a subset of commands). – Aif Dec 11 '14 at 23:58
  • 1
    Please don't use `
    ` and backticks for blocks of code. Use Markdown code format - select the block and click the 'code' button (or indent four spaces per line).
    – halfer Dec 11 '14 at 23:59
  • @Carpetsmoker Aif uses of the superuser was to test Apache user on the server. – Ian Brindley Dec 11 '14 at 23:59
  • 1
    Maybe the limited permissions of the `www-data` user (or whatever you have on your system) does not set up `HOME` or other env vars that are required? I've found that with some system commands. – halfer Dec 12 '14 at 00:01
  • @Aif must of misread/understood for some reason >_< I'm sorry. – Martin Tournoij Dec 12 '14 at 00:27
  • Thank you. I updated the question to show the actions I took based on comments received. I have not attempted to set up **HOME** for **www-data** as I do not yet know how to. But I am researching to understand how to, then I will do so if comments received in the meantime do not direct me to do otherwise. – Arya Dec 12 '14 at 20:03
  • 1
    You should be using [`escapeshellarg`](http://php.net/escapeshellarg) on all your shell arguments, otherwise one could inject arbitrary shell commands. – Gumbo Dec 13 '14 at 19:46
  • @Gumbo Thank you, I updated the question to incorporate your suggestion. – Arya Dec 13 '14 at 20:53
  • 1
    @Aria, may be you want to separate your current "question" to QA-style? – vp_arth Dec 13 '14 at 21:03
  • @vp_arth Thank you, I updated the post to be more like QA-style. Meaning, I added the question(s) that prefaced the action(s) taken. I'm not certain if this is what is meant by QA-style, please advise. – Arya Dec 14 '14 at 01:57
  • 1
    @Arya If you've answered your own question, you should post the answer as an actual answer (in the answer section below), and then accept it. – Matt Gibson Dec 14 '14 at 02:36
  • @MattGibson Thank you, I cut the solution from the question and posted it as the answer (with some grammatical re-arrangements), then accepted it. – Arya Dec 14 '14 at 07:04
  • Now it much more useful, thanks :) – vp_arth Dec 14 '14 at 07:54

1 Answers1

5

PHP cannot access the USB scanner because www-data (the user who is running the PHP script) is not a member of the group that the USB scanner belongs to. Add the user, www-data, to the group the USB scanner belongs to.

To find the group the USB scanner belongs to, the name of the USB scanner must be known. To find the name of the USB scanner, enter the the command:

lsusb -v  

which shows (amongst other lines):

Bus 002 Device 007: ID 04f9:01cc Brother Industries, Ltd  

Then, find the group the USB scanner belongs to, by entering the command:

ls -al /dev/bus/usb/002/007  

which shows:

crw-rw-r--+ 1 root lp 189, 134 Dec 12 22:30 /dev/bus/usb/002/007  

The group the USB scanner belongs to is lp. The reason $USER is able to access the USB scanner is because $USER is a member of the lp group, www-data is not. This is demonstrated by entering the command:

grep ^lp /etc/group  

which shows:

lp:x:7:root,arya  

Add the user, www-data, to the group, lp, by entering the command:

sudo usermod -a -G lp www-data  

Then, test the result again, by entering grep ^lp /etc/group, which now shows:

lp:x:7:root,arya,www-data  

Then, restart apache to make sure the actions above are registered:

sudo apache2ctl -k restart  

Then, test to see if www-data can access the USB scanner from the terminal:

sudo -u www-data scanimage --test -d 'brother3:bus6;dev1'  

which shows:

scanimage: rounded value of br-x from 215.9 to 215.88  
scanimage: rounded value of br-y from 355.6 to 355.567  
scanimage: scanning image of size 1664x2776 pixels at 24 bits/pixel  
scanimage: acquiring RGB frame, 8 bits/sample  
scanimage: reading one scanline, 4992 bytes...  PASS  
scanimage: reading one byte...      PASS  
scanimage: stepped read, 2 bytes...     PASS  
scanimage: stepped read, 4 bytes...     PASS  

Then, run the original PHP script again to see if it can access the USB scanner(s) and scan a document...

Success!

Arya
  • 566
  • 2
  • 9
  • 22