Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Under Linux, how can I find all the files and directories that are writable (or, actually, not writable) by a particular user?

Edit: To clarify, I meant under a particular subdir, not systemwide. And yes, that means all the permutations and combinations of user, group and world writability that would allow that user to write. I know what the question entails semantically, I was hoping for a one- or few-liner to execute to get a list of these files.

share|improve this question
    
Okay, thanks to everyone for the answers. I already found the "find" solution via google, but was wondering if there were some way to generically apply it to a given user. Looks like there is no other way than to su as the user, then run the find command -- unless anyone else chimes in? I will accept Ophidian's answer some time tomorrow barring any better responses. –  Pistos Jun 2 '09 at 2:51

6 Answers 6

up vote 12 down vote accepted

Use the 'find' command if you have findutils version 4.3.0 or greater installed:

For all files under the current directory that are writable by the current user:

find . -writable

For all files under the current directory that are not writable by the current user:

find . ! -writable

According to the man page:

This test makes use of the access(2) system call, and so can be fooled by NFS servers which do UID mapping (or root-squashing), since many systems implement access(2) in the client’s kernel and so cannot make use of the UID mapping information held on the server.

share|improve this answer
1  
Just thought I'd mention for further edification: I actually had to do this with a user who didn't have a login shell ( /sbin/nologin ). To do that, I used sudo, like this: sudo -u nobody find . ! -writable –  Pistos Jun 7 '09 at 17:09

Are you sure that is really the question that you want to be asking?

To say "I want to see all files that X account can write to" means every file owned by them with u+w, every file owned by any group they belong to that's set g+w, and every file world writable (o+w).

Not writable would be even harder. You'd be better off to make a list of every file, then exclude those that they can write to.

share|improve this answer
3  
Of course it is even more complicated if the system has ACLs enabled. –  Zoredache Jun 2 '09 at 0:08
2  
Not counting chattr +i files –  Matt Simmons Jun 2 '09 at 0:12

I'm not sure if this is the best way, but should do what you ask:

for file in *
do 
    if [ -w $file ] ; then 
        echo $file
    fi
done

key is of course in -w switch, which can also be negated

EDIT: Thinking more about this, this script prints what is writable by current user, it obviously wouldn't work for some given user.

share|improve this answer
    
Of course, you have to run this script as that user. –  Eddie Jun 2 '09 at 0:54
    
yeah, figured... –  Slartibartfast Jun 2 '09 at 0:57

You can create a Perl script (writable.pl) like this:

#!/usr/bin/perl

use strict;

sub recurse {
  my $path = shift;
  my @files = glob "$path/{*,.*}";
  for my $file (@files) {
    if (-d $file) {
      if ($file !~ /\/\.$/ && $file !~ /\/\.\.$/) {
        recurse($file);
      }
    } else {
      print "$file\n" if -w $file;
    }
  }
}

print "Writable files for " . getlogin() . "\n";
recurse($ARGV[0]);

and then use this script, as root, as follows:

su USERNAME -c "./writable.pl DIRECTORY"

filling in USERNAME and DIRECTORY as appropriate.

share|improve this answer
    
Excellent. Thank you. The $ARGV[0] is taken as empty in the bash shell on CentOS 6.2. Not sure why. I modified the script to read from a file. –  doon Apr 20 '13 at 12:42

I'll use the gnu find syntax for the -perm flag in this example:

Basically -- if you throw out wacky extensions like ACLs, you've got 3 chocies - owner, group, and "other" write access. Sounds like a job for a loop.

There is plenty of room to optimize this but I'll leave that to someone else... Also, I never can remember all the details of find and crossing filesystems and that sort of nonsense. Also, make sure the output of groups is the same as on my test linux system

$ groups snoopy
snoopy : snoopy doghouse linus admin wwI woodstock
$

This is a rough example of how you'd find files writable by a user. This will when run as any user, but if you run it as a non-uid0 user you'll only find things that are in directories that the user running the script has both read and execute permissions to.

#!/bin/sh

user=snoopy

directory=/

# first files owned by the user and writable
find "$directory" -follow -user "$user" -perm /u+w 2> /dev/null


# now for files that are group writable with the user in that group
for groups in $(groups snoopy 2> /dev/null | cut -f2 -d:)
do
  find "$directory" -follow -group "$user" -perm /g+w 2> /dev/null
done

# now for everything else
find "$directory" -follow -perm /o+w 2> /dev/null
share|improve this answer

For Eddie's answer if you throw in:

my $path = quotemeta shift;

Then it will traverse directories with spaces in their name as well.

share|improve this answer

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.