Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: access to files needed for user management #220

Closed
wants to merge 1 commit into from

Conversation

st3v3nmw
Copy link
Collaborator

@st3v3nmw st3v3nmw commented Feb 27, 2024

TL;DR

This change grants write permissions to files, folders, and interfaces required for user management to work on the snap when it's running on Ubuntu classic.


DETAILS

After #218, I realized I was testing in devmode where permissions are lax. After switching to dangerous which is strict, I realized that nothing works 😞. This PR should get landscape-client snap's user management working on Ubuntu classic.

Here's a laundry list of the issues I played whack-a-mole with along the way (it should also justify choices made with the fixes):

1. adduser overwriting $PATH

Trying to run adduser inside the snap's shell (essentially what landscape.client.user.management.UserManagement does) led to the following error:

$ adduser test --debug
Adding user `test' ...
Selecting UID from range 1000 to 59999 ...
Selecting GID from range 1000 to 59999 ...
Adding new group `test' (1001) ...
/sbin/groupadd -g 1001 test
adduser: `/sbin/groupadd -g 1001 test' returned error code 72057594037927935. Exiting.

The issue here is we're trying to use /sbin/groupadd which we don't have access to:

$ /sbin/groupadd
bash: /sbin/groupadd: Permission denied

Though we already have groupadd inside the snap (from the staged passwd package):

$ which groupadd
/snap/landscape-client/x14/usr/sbin/groupadd
$ which adduser
/snap/landscape-client/x14/usr/sbin/adduser
$ echo $PATH
/snap/landscape-client/x14/usr/sbin:/snap/landscape-client/x14/usr/bin:/snap/landscape-client/x14/sbin:/snap/landscape-client/x14/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Digging deeper, we find that the adduser package modifies $PATH here:

# explicitly set PATH, because super (1) cleans up the path and makes adduser unusable;
# this is also a good idea for sudo (which doesn't clean up)
$ENV{"PATH"}="/bin:/usr/bin:/sbin:/usr/sbin";

Then it runs which with the modified $PATH here:

log_info( mtx("Adding group `%s' (GID %d) ..."), $new_name, $gid_option);
my $groupadd = &which('groupadd');

The fix here is to delete the offending line while building the snap:

sed -i '\#/bin:/usr/bin:/sbin:/usr/sbin#d' $SNAPCRAFT_PART_INSTALL/usr/sbin/adduser

2. Access to the kernel's audit interface

Next, we find that groupadd can't open the kernel's audit interface:

$ adduser test --debug
Adding user `test' ...
Selecting UID from range 1000 to 59999 ...
Selecting GID from range 1000 to 59999 ...
Adding new group `test' (1001) ...
/snap/landscape-client/x22/usr/sbin/groupadd -g 1001 test
Cannot open audit interface - aborting.
adduser: `/snap/landscape-client/x22/usr/sbin/groupadd -g 1001 test' returned error code 1. Exiting.

Fixed by adding the netlink-audit interface.

3. Read & write access to /etc

Next, we find that groupadd can't create the /etc/group.lock lock file to prevent simultaneous updates to /etc/group.

$ adduser test --debug
Adding user `test' ...
Selecting UID from range 1000 to 59999 ...
Selecting GID from range 1000 to 59999 ...
Adding new group `test' (1001) ...
/snap/landscape-client/x23/usr/sbin/groupadd -g 1001 test
groupadd: cannot lock /etc/group; try again later.
adduser: `/snap/landscape-client/x23/usr/sbin/groupadd -g 1001 test' returned error code 10. Exiting.

Tried fixing this by plugging the system-files interface with read & write access to the following files:

- /etc/.pwd.lock
- /etc/shadow
- /etc/shadow-
- /etc/shadow.lock
- /etc/passwd
- /etc/passwd-
- /etc/passwd.lock
- /etc/pam.d/passwd
- /etc/subuid
- /etc/subuid-
- /etc/adduser.conf
- /etc/default/useradd
- /etc/deluser.conf
- /etc/group
- /etc/group-
- /etc/group.lock
- /etc/gshadow
- /etc/gshadow-
- /etc/gshadow.lock
- /etc/login.defs
- /etc/subgid
- /etc/subgid-
- /etc/skel

And it still doesn't work since groupadd keeps creating files with random suffixes /etc/group.N:

$ adduser test --debug
Adding user `test' ...
Selecting UID from range 1000 to 59999 ...
Selecting GID from range 1000 to 59999 ...
Adding new group `test' (1001) ...
/snap/landscape-client/x25/usr/sbin/groupadd -g 1001 test
groupadd: /etc/group.716838: Permission denied
groupadd: cannot lock /etc/group; try again later.
adduser: `/snap/landscape-client/x25/usr/sbin/groupadd -g 1001 test' returned error code 10. Exiting.

$ adduser test --debug
Adding user `test' ...
Selecting UID from range 1000 to 59999 ...
Selecting GID from range 1000 to 59999 ...
Adding new group `test' (1001) ...
/snap/landscape-client/x25/usr/sbin/groupadd -g 1001 test
groupadd: /etc/group.717005: Permission denied
groupadd: cannot lock /etc/group; try again later.
adduser: `/snap/landscape-client/x25/usr/sbin/groupadd -g 1001 test' returned error code 10. Exiting.

We also can't use patterns like /etc/group* with systems-files as they're not supported:

$ sudo snap install landscape-client_23.08_amd64.snap --dangerous
2024-02-28T18:27:33+03:00 INFO snap "landscape-client" has bad plugs or slots: landscape-client-user-management (cannot add system-files plug: "/etc/group*" contains a reserved apparmor char
from ?*[]{}^")
landscape-client 23.08 installed

So the fix here is to give read & write access to the entire /etc folder. But it still doesn't work because the folder structure is all messed up inside the snap since we're mounting /etc with system-files and also creating a virtual file system /etc with layout:

[...]
plugs:
  landscape-client-user-management:
    interface: system-files
    write:
      - /etc
[...]

layout:
  /etc/landscape-client.conf:
    bind-file: $SNAP_COMMON/etc/landscape-client.conf
[...]
$ df -h
[...]
tmpfs                      7.8G     0  7.8G   0% /etc
[...]

Which means that changes made to files like /etc/group do not appear on the host's file system. Getting rid of the /etc/landscape-client.conf layout fixes this.

4. Permission issues writing to /etc/shadow & /etc/gshadow

At this point we can write to /etc/group but can't write to /etc/gshadow which means that adding users isn't yet working. If we check the journalctl logs, we see:

group added to /etc/group: name=testing, GID=1002
SECCOMP auid=1000 uid=0 gid=0 ses=3 subj=snap.landscape-client.landscape-client pid=1090645 comm="groupadd" exe="/snap/landscape-client/x5/usr/sbin/groupadd" sig=0 arch=c000003e syscall=93 compat=0 ip=0x7f1fe2e94c4b code=0x50000
groupadd[1090645]: failed to add group testing to /etc/gshadowkernel: audit: type=1326 audit(1709209456.168:46723): auid=1000 uid=0 gid=0 ses=3 subj=snap.landscape-client.landscape-client pid=1090645 comm="groupadd" exe="/snap/landscape-client/x5/usr/sbin/groupadd" sig=0 arch=c000003e syscall=93 compat=0 ip=0x7f1fe2e94c4b code=0x50000
terra groupadd[1090645]: failed to add group testing

In the SECCOMP log, we find that we're attempting to do syscall 93 which is fchown which is being blocked by seccomp/AppArmor. We can confirm this by checking landscape client's AppArmor profile and see that the chown capability is not enabled/set:

$  cat /var/lib/snapd/apparmor/profiles/snap.landscape-client.landscape-client | grep chown
/{,usr/}bin/chown ixr,

Luckily, the account control interface grants us this capability:

# Capabilities needed by useradd
capability audit_write,
capability chown,
capability fsetid,

from snapd/interfaces/builtin/account_control.go#L99

Which also updates our seccomp profile (cat /var/lib/snapd/seccomp/bpf/snap.landscape-client.landscape-client.src):

# useradd requires chowning to 0:'42'
fchown - u:root 42
fchown32 - u:root 42

5. Can't create home directories for new users

Next, we realize that we can't create home directories for new users:

$ adduser testing
Adding user `testing' ...
Adding new group `testing' (1001) ...
Adding new user `testing' (1001) with group `testing' ...
Creating home directory `/home/testing' ...
Stopped: Couldn't create home directory `/home/testing': Permission denied.

Removing directory `/home/testing' ...
Removing user `testing' ...
Removing group `testing' ...
groupdel: group 'testing' does not exist
adduser: `groupdel testing' returned error code 6. Exiting.

Adding the home interface still leads to the same error. It seems like we don't have write access even though the folder is loaded as read-write?

$ ls -lah /home
total 16K
drwxr-xr-x  5 root    root    4.0K Feb 29 13:44 .
drwxr-xr-x 21 root    root     580 Feb 29 12:35 ..
[...]
drwxr-x---  2    1001    1001 4.0K Feb 29 13:44 testing
$ rm -rf /home/testing
rm: cannot remove '/home/testing': Permission denied
$ mkdir /home/new
mkdir: cannot create directory ‘/home/new’: Permission denied
$ cat /proc/mounts | grep home
/dev/mapper/vgubuntu-root /home ext4 rw,relatime,errors=remount-ro 0 0

If we add /home to system-files it still fails due to chown but we're able to create the user's home directory:

$ adduser testing
Adding user `testing' ...
Adding new group `testing' (1001) ...
Adding new user `testing' (1001) with group `testing' ...
Creating home directory `/home/testing' ...
Stopped: chown 1001:1001 /home/testing: Operation not permitted

Removing directory `/home/testing' ...
Removing user `testing' ...
Removing group `testing' ...
groupdel: group 'testing' does not exist
adduser: `groupdel testing' returned error code 6. Exiting.

@st3v3nmw st3v3nmw force-pushed the mount-etc branch 2 times, most recently from f8d0cc0 to e81d645 Compare February 29, 2024 11:09
@st3v3nmw
Copy link
Collaborator Author

st3v3nmw commented Mar 1, 2024

Looks like it's impossible to get around that seccomp violation. snappy-debug's only solution is to modify the code not to chown but that doesn't seem to be an option here:

= Seccomp =
Time: Mar  1 09:26:20
Log: auid=1000 uid=0 gid=0 ses=3 subj=snap.landscape-client.landscape-client pid=23471 comm="adduser" exe="/usr/bin/perl" sig=0 arch=c000003e 92(chown) compat=0 ip=0x7f31a69d1c1b code=0x50000
Syscall: chown
Suggestions:
* don't copy ownership of files (eg, use 'cp -r --preserve=mode' instead of 'cp -a')
* try the snapcraft preload plugin: https://github.com/sergiusens/snapcraft-preload
* adjust program to not use 'chown'
* ignore the denial if the program otherwise works correctly (unconditional chown is often just noise)

Way out is to use D-Bus & the org.freedesktop.Accounts interface.

Closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant