1

Background:

I'm trying to share a folder between two users on the same machine . The normal way would be to have the two users in the same group set the parent folder to that group with rw and the s bit set.

That works great. Except .... the folder I am trying to share is one used by Chromium. When Chromium launches it writes some session files with only owner rw (i.e 600) permission ignroing the s bit. I guess some misbehaved programs can do that. That means when the other user tries later to open that same chromimum profile they can't set those sessions files cause they already exist with the owner only rw of the other user. :(

I gave bindfs a try but that requires sudo at login and thus I have to use a sudoers.d file if I want to get that set up non-interactive at login.

Anway I gave ACL a try and am not grokking some aspect because it's not working like I think it should.


# user1: syadmin
# user2: david
# directory: /opt/stest
# user1 sysadmin is logged in.

# sysadmin owns /opt/stest
$ llag stest
drwxrwsr-x+  2 sysadmin users    4096 Feb  3 13:45 stest/

$getfacl stest
# file: stest
# owner: sysadmin
# group: sysadmin
user::rwx
group::rwx
other::r-x

# now run
setfacl -R -m u:david:rwX /opt/stest
setfacl -dR -m u:david:rwX /opt/stest

# gives
user:david:rwx
default:user:david:rwx

#now create a file as other user
$ su david -c "touch /opt/stest/test"
-rw-rw-r--+  1 david    users    0 Feb  3 13:51 test

#set with owner only rw like how chromium does
-rw-------+  1 david    users    0 Feb  3 13:51 test

$ getfacl test
# file: test
# owner: david
# group: users
user::rw-
user:david:rwx          #effective:---
group::rwx          #effective:---
mask::---
other::---

So this is the part I'm not getting. Why is the "non-acl" owner of the file test david

# file: test
# owner: david

instead of sysadmin given sysadmin owns the directory. Bascially I thought that setfacl would always give access to the directory owner. It seems as though even if the acl entry was made by sysadmin sysdamin must be manually added to any file created by another allowed user or it can get locked out of its own files. That was not intuitive for me.

Is that what i need to do? Do I need to run inotify wait on the directory and then add sysamdin to the acl list if another user creates a file. What is the best solution to my situation ACL or otherwise.

I am running ubuntu 20.04 with kernel 5.4.0-65-

--two days later

I tried another tack. I added both users to the file and default acl list using sudo. Then I logged out and into the other user. Then did a getfacl on one of the offending files. You see both users listed but under effective there is nothing instead of rw. Arrgh. Still the current user sysadmin can't access the file created by david. Why is effective not showing rw???

-rw-------+ 1 david david 125146 Feb 6 09:12 Preferences

getfacl Preferences 
# file: Preferences
# owner: david
# group: david
user::rw-
user:sysadmin:rwx       #effective:---
user:david:rwx          #effective:---
group::rwx          #effective:---
group:users:rwx         #effective:---
mask::---
other::---
3
  • Can reproduce the problem, but unsure the best solution. It partly depends on factors such as who else is using the computer. Eg, if it's just a single user machine so you're not too worried the permissions on chromium itself, you could run it setuid sysadmin, maybe? The idea of using inotifywait is also not terrible.
    – cryptarch
    Commented Feb 4, 2021 at 0:49
  • setuid AFAIK only is for executables. The offending files are not exectued only rw. @cryptarch I tried another tack and added both users to default and file acl. See results above. "effective" is not being calculated.
    – DKebler
    Commented Feb 6, 2021 at 17:52
  • 1
    YEA. Just needed to chmod that file to 660 and then the mask is set which then calculates the effective permissions correctly. I think I have this solved. I need to do a bit of testing to be sure and then I'll write up an answer.
    – DKebler
    Commented Feb 6, 2021 at 18:02

1 Answer 1

2

Ok, looking like I solved this. I can open chromium from either user with exact same user-dir/profile.

The trick is add all users to the acl owners list both for existing files and as default. Then to get the mask set run some chmod commands and do that all recursively.

To make this easy I wrote script and it's here.

https://gist.github.com/dkebler/23c8651bd06769770773f07854e161fc

I will keep it updated and with bug fixes but so far its working for me. If you are going to try it I strongly suggest experimenting on a test directory as you can easily mess things up. I did write in a bunch of confirmations to avoid this but still read the script and use at your own risk.

That said here is output from the script showning the commands executed.

david@giskard:[common/applications] $ share_dir -o root . sysadmin david
share directory /mnt/AllData/users/common/applications/ with users: sysadmin david ? confirm y
adding acl user sysadmin
these are the acl commands that you will run
******************
sudo setfacl -R -m u:sysadmin:rwX /mnt/AllData/users/common/applications/
sudo setfacl -dR -m u:sysadmin:rwX /mnt/AllData/users/common/applications/
******************
Double Check. Do you want to continue? y
*** new acl entries ***
user:sysadmin:rwx
default:user:sysadmin:rwx
adding acl user david
these are the acl commands that you will run
******************
sudo setfacl -R -m u:david:rwX /mnt/AllData/users/common/applications/
sudo setfacl -dR -m u:david:rwX /mnt/AllData/users/common/applications/
******************
Double Check. Do you want to continue? y
*** new acl entries ***
user:david:rwx
default:user:david:rwx
done adding acl users sysadmin david
these are the chown/chmod commands that you will run
******************
sudo chown -R root:users /mnt/AllData/users/common/applications/
sudo chmod -R u+rwX /mnt/AllData/users/common/applications/
sudo chmod -R g+rwX /mnt/AllData/users/common/applications/
sudo find /mnt/AllData/users/common/applications/ -type d -exec chmod g+s {} +
******************
Double Check. Do you want to continue? y
all done!
total 24
drwxrwsr-x+ 2 root users 4096 Feb  6 13:05  ./
drwxrwsr-x+ 5 root users 4096 Feb  6 11:39  ../
-rwxrwxr-x+ 1 root users  169 Jan 30 11:01 'Hacking Chromium.desktop'*
-rwxrwxr-x+ 1 root users  161 Jan 30 16:03 'Incognito Chromium.desktop'*
# file: /mnt/AllData/users/common/applications/
# owner: root
# group: users
# flags: -s-
user::rwx
user:sysadmin:rwx
user:david:rwx
group::rwx
mask::rwx
other::r-x
default:user::rwx
default:user:sysadmin:rwx
default:user:david:rwx
default:group::rwx
default:mask::rwx
default:other::r-x

here is script (as of 5/24) but I will not be updating this so see the gist for latest

#!/bin/bash

# Usage: 
#  share_dir [ -o <owner> -g <group> ] <directory> <list of space delimited users names/uid>
#  use . for current directory
# -o forces own for directory, default is $USER
# -g forces group name for directory, default is "users" and if not available then $USER
#  Note: script operates recursively on given directory!, use with caution

## HELPERS

adirname() {
  # passed entire path
 echo "$(cd "$(dirname "$1")" >/dev/null 2>&1 ; pwd -P )"
}

chmod_dirs() {
  # passed entire path
  local usesudo 
  [[ $1 == -s ]] && usesudo="sudo" && shift 2
  $usesudo find $1 -type f -exec chmod $2 {} +
}


function confirm()
{
    echo -n "$@ "
    read -e answer
    for response in y Y yes YES Yes Sure sure SURE OK ok Ok
    do
        if [ "_$answer" == "_$response" ]
        then
            return 0
        fi
    done

    # Any answer other than the list above is considered a "no" answer
    return 1
}

# End Helpers


# Usage: 
#  adding: acladduserdir <user> <directory>
#  deleting: acladduserdir -d <user> <directory>
# add -s flag to force run as sudo
#  Note: script operates recursively on given directory!, use with caution

acladduserdir() {

  module_load confirm
  local uid
  local usesudo
  local del
  local spec
  local dir
  local cmd="-R  -m "
  local cmdd="-dR  -m"

  declare OPTION
  declare OPTARG
  declare OPTIND

  while getopts 'ds' OPTION; do
    # echo $OPTION $OPTARG
    case "$OPTION" in
    d)
      del=true
      ;;
    s)
      usesudo="sudo"
      ;;
    *)
      echo unknown option $OPTION
      ;;
    esac
  done

  shift $((OPTIND - 1))

  if [[ $del ]]; then
    echo deleting an acl entries for $1
    opts="-R  -x"
    optsd="-dR  -x"
    spec="u:$1"
  else
    opts="-R  -m "
    optsd="-dR  -m"
    spec="u:$1:rwX"
  fi
  [[ ! $2 ]] && echo acluserdir: both user and direcotory must be passed && return 1
  dir=$2
  uid=$(id -u $1 2>/dev/null)
  [[ $uid -lt 1000 ]] && echo no such regular user $1 && return 2
  [[ ! -d $2 ]] && echo no such directory $2 && return 3
  if [[ ! -w $2 ]]; then
    echo $2 not writable by current user $USER
    if [[ ! $(sudo -l -U $USER 2>/dev/null) ]]; then
      echo user does not have sudo privilges, aborting
      return 4
    else
      confirm "do you want to elevate to root and continue?" || return 5
      usesudo="sudo"
    fi
  fi
  echo these are the acl commands that you will run
  echo '******************'
  echo $usesudo setfacl $opts $spec $dir
  echo $usesudo setfacl $optsd $spec $dir
  echo '******************'
  confirm Double Check. Do you want to continue? || return 6
  $usesudo setfacl $opts $spec $dir
  $usesudo setfacl $optsd $spec $dir
  echo '*** new acl entries ***'
  $usesudo getfacl -p --omit-header $2 | grep $1

}

# Usage: 
#  share_dir [ -o <owner> -g <group> ] <directory> <list of space delimited users names/uid>
# -o forces own for directory, default is $USER
# -g forces group name for directory, default is "users" and if not available then $USER
#  Note: script operates recursively on given directory!, use with caution

share_dir() {
  [[ ! $(sudo -l -U $USER 2>/dev/null) ]] && echo current user does not have sudo privilges, aborting && return 4
  local group
  local owner=$USER
  [[ $(getent group users) ]] && group=users || group=$USER

  declare OPTION
  declare OPTARG
  declare OPTIND

  while getopts 'g:o:' OPTION; do
    # echo $OPTION $OPTARG
    case "$OPTION" in
    o)
      owner=$OPTARG
      ;;
    g)
      group=$OPTARG
      ;;
    *)
      echo unknown option $OPTION
      ;;
    esac
  done

  shift $((OPTIND - 1))
  
  local dir=$([[ ! $1 == /* ]] && echo $(adirname $1)/)$([[ $1 == . ]] && echo "" || echo $1)
  if [[ ! -d $dir ]]; then
    confirm no such directory $dir, create it? && sudo mkdir -p $dir || return 6
  fi
  shift
  confirm share directory $dir with users: $@ ? confirm || return 6
  for user in "$@"; do
    echo adding acl user $user
    acladduserdir -s $user $dir
  done
  echo done adding acl users $@
  echo these are the chown/chmod commands that you will run
  echo '******************'
  echo sudo chown -R $owner:$group $dir
  echo sudo chmod -R u+rwX $dir
  echo sudo chmod -R g+rwX $dir
  echo sudo find $dir -type d -exec chmod g+s {} +
  echo '******************'
  confirm Double Check. Do you want to continue? || return 6
  sudo chown -R $owner:$group $dir
  sudo chmod -R u+rwX $dir
  sudo find $dir -type d -exec chmod g+s {} +
  echo all done!
  ls -la $dir
  getfacl -p $dir

}

4
  • Bonus> now that I have this script I ran it on my /opt directory since that is set up to share between users on my dev machine. This will fix similar issues there.
    – DKebler
    Commented Feb 6, 2021 at 21:28
  • Please post the script here or describe the solution here. One should not have to log-in to git hub to see the solution. I click the link and git hub wants me to haul out my USB key. If I sound annoyed, it's because I'm annoyed with M$'s takeover of github and this two-factor nonsense for everything!
    – tallen
    Commented May 31 at 13:39
  • gist.github.com/dkebler/… Not sure why you are required to sign in I just visited this in an incognito session with no login and it's public doesn't require a login.
    – DKebler
    Commented Jun 1 at 20:38
  • 1
    that said I added the script
    – DKebler
    Commented Jun 1 at 23:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .