Unix: How can I allow only one person to see my folder in the same fs?

I want to give an access to a dir for a friend. He has the access to the file system, where the dir is located. I don't want to set the permissions to all users. How can I allow only a person to see the dir? None of us is a superuser.

[BOUNTY CHALLENGE] None of the replies work, using Ubuntu:

1. jamuraa's Approach not working

$ setfacl -m user:friend:rwx classroom.xml 
setfacl: classroom.xml: Operation not supported

2. nik's Approach not working: cannot access non-existent file

3. ba's Approach not working: I cannot create groups, not a root.

4. ToK's Approach not working, users are in two groups: "users" and "field"

chown -R myFriend:users ~/TEST
chown: changing ownership of `/u/myFriend/TEST/you_see_it': Operation not permitted
chown: changing ownership of `/u/myFriend/TEST': Operation not permitted

Solution 1:

With just normal UNIX permissions (user, group, everyone), you can't do this easily. If you don't need access to the directory anymore, you can possibly change the owner of the directory to your friend, which is valid on some Unices, but most of them it is not.

However - if you have ACLs enabled on Linux, you can do this if you are the owner of the file. Just run the command setfacl -m user:friend:rwx filename where friend is the account name of your friend and filename is the file. You can check that it went into effect by running getfacl filename, you should see the triad user:friend:rwx in the list. I haven't seen too many Linux systems which have the ACLs enabled though.

Solution 2:

This is something we had discussed back in school.
Goes roughly like this,

  1. Create a directory (named data, for reference here)
    • change permissions as "chmod 711 data"
    • group and others have only x -- access to enter the directory
    • they cannot list the directory
    • Now, create a directory difficult-name-here (this could be a hashed-string)
    • change permissions as "chmod a+rx difficult-name-here"
    • contents of this directory are secure while the outer directory cannot be listed
    • people who know the "difficult name" can jump into this second directory
      • "cd path/to/data/difficult-name-here"
      • others cannot see the name and cannot access directory contents
      • However, the root can always access everything (which is not a problem here)
    • share the difficult-name-here with the people you want to give this data
    • Keep shared files in this second directory

Quite crude, but if this can be broken without the unix access control breakage, I'd like to know.


Update on comment from dmckee,
This is exactly the conclusion we reached!
"security by obscurity" has limited safety.

Having said that, when designing protection for data,
it is important to identify its value.

You should target for,

  • A Cost of breaking-the-security that is higher than,
  • The Cost of secured content,
  • By a factor proportional to your paranoia

In this case, if the root decides to enumerate the directory tree somewhere in public access,
your secret is out! But, are you protecting from the root or their potential irresponsibility?
If that is the case, you have a lot more to worry about then shared files.


Update about not-working note in the question.
I've used this in early days of linux to know that it works.
If you get 'cannot access non-existant file' instead of 'permissions denied' you have very likely made a mistake in the sequence. What you want should look like this,

 755      711      755     whatever     --=== Access permissions

 BasePath/CoverDir/Obscure/protectedFile.txt
          |        |       ^^^^^^^^^^^^^^^^^ Can't be seen without 
          |        ^^^^^^^ Directory Name         read access to 
          ^^^^^ Public     shared with friend.    Obscure directory.
                accessible 
                directory.
  1. If you set 'CoverDir' access as 'rwx--x--x',
    group and others can only enter the directory but cannot read its contents.
  2. Now, if you use an obscure directory name,
    'Obscure', inside it and give full read access with 'rwxr-xr-x',
    anyone knowning this name can list its contents.
  3. This access will have to be done from outside with a 'ls BasePath/CoverDir/Obscure'
    Because people in your group and others will not be able to 'ls BasePath/CoverDir'.

Solution 3:

Ryan was actually 100% correct, just backward. Since your friend (likely) has a unique group associated with his/her user name change the group ownership of the directory in question to that group, most likely the friend's user name. In order to be able to share the contents between the two of you you should retain ownership as the user:

chown -R youruser:friendgroup ~/foo/bar

Then assign appropriate permissions to the directory, dependent upon what access you wish the other user to have:

chmod -R 770 ~/foo/bar

would grant both of you full rwx access to the directory and its entire contents.

Please note that this assumes that no other user has been added to your friend's group. The system would not have likely have made this assignment, however, as was mentioned before, the root user may do what they choose. You may use the groups command to see each group to which your friend, or arbitrary user, belong. Additionally, unless the permissions have been changed for some reason, you should be able to view the /etc/group file which contains the group assignments for each group on the system.

Solution 4:

I would make a new group for you and your friend and set the folder permissions to full for owner and group together with the setgid bit for the directory.

But depending on your needs you may also have to look into changing you and your friends umask so it automatically sets the group to be able change new files.

# groupadd bestfriends
# chmod 2770 dir
# chgrp bestfriends dir
# usermod -G bestfriends FRIENDLOGIN