Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Trying lots of different linux, on all kinds of hardware I find my self typing commands like this quite often:

sudo dd if=xubuntu-13.10-desktop-amd64.iso of=/dev/sdc bs=10240

Needless to say, sooner or later I will mistype the destination and wipe a harddrive instead of the intended USB drive. I would like not to use sudo everytime here.

On my system, a fairly modern Ubuntu, permissions on /dev/sdc are like: (when a stick is present):

$ ls -al /dev/sdc*
brw-rw---- 1 root disk 8, 32 Apr  6 22:10 /dev/sdc

How do I grant my regular user write access to random USB sticks but not other disks present in my system?

share|improve this question

1 Answer 1

up vote 9 down vote accepted

I think you can use UDEV to do what you want. Creating a rules file such as/etc/udev/rules.d/99-thumbdrives.rules you'd simply add a rule that will allow either a Unix group or user access to arbitrary USB thumb drives.

KERNEL=="sd*", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", OWNER="<user>", GROUP="<group>", MODE="0660"

Would create the device using the user <user> and group <group>.

Example

  1. After adding this line to my system.

    KERNEL=="sd*", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", OWNER="saml", GROUP="saml", MODE="0660"
    
  2. And reloading my rules:

    $ sudo udevadm control --reload-rules
    
  3. If I now insert a thumbdrive into my system, my /var/log/messages shows up as follows:

    $ sudo tail -f /var/log/messages
    Apr 13 11:48:45 greeneggs udisksd[2249]: Mounted /dev/sdb1 at /run/media/saml/HOLA on behalf of uid 1000
    Apr 13 11:51:18 greeneggs udisksd[2249]: Cleaning up mount point /run/media/saml/HOLA (device 8:17 is not mounted)
    Apr 13 11:51:18 greeneggs udisksd[2249]: Unmounted /dev/sdb1 on behalf of uid 1000
    Apr 13 11:51:18 greeneggs kernel: [171038.843969] sdb: detected capacity change from 32768000 to 0
    Apr 13 11:51:39 greeneggs kernel: [171058.964358] usb 2-1.2: USB disconnect, device number 15
    Apr 13 11:51:46 greeneggs kernel: [171066.053922] usb 2-1.2: new full-speed USB device number 16 using ehci-pci
    Apr 13 11:51:46 greeneggs kernel: [171066.134401] usb 2-1.2: New USB device found, idVendor=058f, idProduct=9380
    Apr 13 11:51:46 greeneggs kernel: [171066.134407] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    Apr 13 11:51:46 greeneggs kernel: [171066.134410] usb 2-1.2: Product: USBDrive
    Apr 13 11:51:46 greeneggs kernel: [171066.134412] usb 2-1.2: Manufacturer: JMTek
    Apr 13 11:51:46 greeneggs kernel: [171066.135470] usb-storage 2-1.2:1.0: USB Mass Storage device detected
    Apr 13 11:51:46 greeneggs kernel: [171066.136121] scsi17 : usb-storage 2-1.2:1.0
    Apr 13 11:51:46 greeneggs mtp-probe: checking bus 2, device 16: "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2"
    Apr 13 11:51:46 greeneggs mtp-probe: bus: 2, device: 16 was not an MTP device
    Apr 13 11:51:47 greeneggs kernel: [171067.139462] scsi 17:0:0:0: Direct-Access     JMTek    USBDrive         7.77 PQ: 0 ANSI: 2
    Apr 13 11:51:47 greeneggs kernel: [171067.140251] sd 17:0:0:0: Attached scsi generic sg2 type 0
    Apr 13 11:51:47 greeneggs kernel: [171067.142105] sd 17:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB)
    Apr 13 11:51:47 greeneggs kernel: [171067.144236] sd 17:0:0:0: [sdb] Write Protect is off
    Apr 13 11:51:47 greeneggs kernel: [171067.145988] sd 17:0:0:0: [sdb] No Caching mode page found
    Apr 13 11:51:47 greeneggs kernel: [171067.145998] sd 17:0:0:0: [sdb] Assuming drive cache: write through
    Apr 13 11:51:47 greeneggs kernel: [171067.153721] sd 17:0:0:0: [sdb] No Caching mode page found
    Apr 13 11:51:47 greeneggs kernel: [171067.153728] sd 17:0:0:0: [sdb] Assuming drive cache: write through
    Apr 13 11:51:47 greeneggs kernel: [171067.159028]  sdb: sdb1
    Apr 13 11:51:47 greeneggs kernel: [171067.164760] sd 17:0:0:0: [sdb] No Caching mode page found
    Apr 13 11:51:47 greeneggs kernel: [171067.164768] sd 17:0:0:0: [sdb] Assuming drive cache: write through
    Apr 13 11:51:47 greeneggs kernel: [171067.164775] sd 17:0:0:0: [sdb] Attached SCSI removable disk
    Apr 13 11:51:47 greeneggs kernel: [171067.635474] FAT-fs (sdb1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
    Apr 13 11:51:47 greeneggs udisksd[2249]: Mounted /dev/sdb1 at /run/media/saml/HOLA on behalf of uid 1000
    
  4. Now checking out the device files under /dev shows the following:

    $ ls -l /dev/sd*
    brw-rw----. 1 root disk 8,  0 Apr 13 09:17 /dev/sda
    brw-rw----. 1 root disk 8,  1 Apr 13 09:17 /dev/sda1
    brw-rw----. 1 root disk 8,  2 Apr 13 09:17 /dev/sda2
    brw-rw----. 1 saml saml 8, 16 Apr 13 11:51 /dev/sdb
    brw-rw----. 1 root disk 8, 17 Apr 13 11:51 /dev/sdb1
    

So it would seem to have worked.

Being more explicit

The above will work but will likely have these rules getting applied to every block device which isn't quite what we want. To narrow its focus a bit you can use ATTRS{..}==... attribute rules to restrict the application to specific hardware. In my case I only want it to be applied to a single USB thumbdrive.

Step #1 - uniquely id device

So to start we can use this command once we've mounted the particular thumb drive so that we can use udevadm to scrutinize it, groping it for its particular attributes.

Here I'm focusing on looking at the "manufacturer" and "product" attributes.

$ udevadm info -a -p $(udevadm info -q path -n /dev/sdb)|grep -iE "manufacturer|product"
    ATTRS{manufacturer}=="JMTek"
    ATTRS{idProduct}=="9380"
    ATTRS{product}=="USBDrive"
    ATTRS{idProduct}=="0020"
    ATTRS{manufacturer}=="Linux 3.13.7-100.fc19.x86_64 ehci_hcd"
    ATTRS{idProduct}=="0002"
    ATTRS{product}=="EHCI Host Controller"

NOTE: ATTRS{..}==.. attributes are attributes to parent devices in the hierarchy of where this device's device file is ultimately deriving from. So in our case the block device being added, /dev/sdb is coming from a USB parent device, so we're looking for this parent's attributes, ATTRS{manufacturer}=..., for example.

So in this example I'm selecting the manufacturer "JMTek" and the product "USBDrive".

Step #2 - modify .rules flie

So with these additional bits in hand let's add them to our original .rules file.

KERNEL=="sd*", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ATTRS{manufacturer}=="JMTek", ATTRS{product}=="USBDrive", OWNER="saml", GROUP="saml", MODE="0660"

Step #3 - Trying it out

Now when we reload our rules and unmount/remove/reinsert our USB thumbdrive again we get this rule:

$ ls -l /dev/sdb*
brw-rw----. 1 saml saml 8, 16 Apr 13 12:29 /dev/sdb
brw-rw----. 1 root disk 8, 17 Apr 13 12:29 /dev/sdb1

However if I insert a completely different device:

$ ls -l /dev/sdb*
brw-rw----. 1 root disk 8, 16 Apr 13 12:41 /dev/sdb
brw-rw----. 1 root disk 8, 17 Apr 13 12:41 /dev/sdb1

References

share|improve this answer
    
This, already, is the most correct answer. You don't often disappoint, slm. –  mikeserv Apr 13 at 14:25
    
@mikeserv - thanks! I try. 8-) –  slm Apr 13 at 14:32
    
Shouldn't you use the block subsystem? If i am not mistaken, this rule will match the /dev/usb/xxx/yyy device instead of /dev/sdc. ATTRS rather than ATTR should match parent devices (i.e. block). –  Lekensteyn Apr 13 at 15:30
    
@Lekensteyn - thanks it wasn't quite working for me originally and I couldn't figure out why. With your big clue and moving the rule to the end (99-...) I'm now able to actually show a real demo that works. Thanks again for the guidance! –  slm Apr 13 at 15:57
    
I had to fight a little but I ended up using SUBSYSTEM=="block", ENV{ID_BUS}=="usb", GROUP="mogul" Which I read as "any USB disk will be in group mogul". using a 99 rule helped too –  mogul Apr 13 at 17:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.