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

podman unshare chown doesn't work with externally mounted drives #9646

Closed
imperialguy opened this issue Mar 7, 2021 · 10 comments
Closed

podman unshare chown doesn't work with externally mounted drives #9646

imperialguy opened this issue Mar 7, 2021 · 10 comments
Labels
kind/bug Categorizes issue or PR as related to a bug. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.

Comments

@imperialguy
Copy link

imperialguy commented Mar 7, 2021

Is this a BUG REPORT or FEATURE REQUEST? (leave only one on its own line)

/kind bug

Description

The following command doesn't change the ownership to a desired uid (other than default root UID 0) inside the container

podman unshare chown uid:uid <path/to/externally/mounted/directory/owned/by/rootless/user>

I would like the externally mounted network drives (owned by rootless user) on host machine to be owned by a specific user ID (other than the obvious root UID 0) inside the container after they are volume mounted

Steps to reproduce the issue:

  1. On your host machine, mount an external drive onto a directory inside your rootless user's home directory. For e.g., I mounted a samba share like below
sudo mount -t cifs //samba_server_ip/samba_share_name /home/testuser/mysamba_share_dir -o credentials=/path/to/samba/credentials,uid=1000,gid=1000,dir_mode=0777,file_mode=0777
  1. Spin up a container (from any image of your choice) from within your rootless user's namespace and map some dir that resides inside the externally mounted dir onto some location inside the container.

  2. For e.g. let's say, we volume mounted /home/testuser/mysamba_share_dir/test onto /tmp/test directory inside the container

  3. Create a separate user inside the container (say) uid is 32

  4. Back on the host machine run the following command from your rootless user's shell:

podman unshare chown -R 32:32 /home/testuser/mysamba_share_dir/test

Describe the results you received:

This is what I see when I do an ls -l on the externally mounted directory

[testuser@localhost] ls -l /home/testuser/mysamba_share_dir
drwxrwxrwx 1   testuser   testuser    38 Mar  6 23:22 test

So, it's still showing testuser i.e., the rootless user as the owner.

Describe the results you expected:

At this point I expect to see something like this when I do an ls -l on the mounted directory:

[testuser@localhost] ls -l /home/testuser/mysamba_share_dir
drwxrwxrwx 1   10031   10031    38 Mar  6 23:22 test

Additional information you deem important (e.g. issue happens only occasionally):

Of course, this problem doesn't occur if I map a local directory on the host onto the container.

For e.g. if I map /home/testuser/docs/sample_dir onto /tmp/test inside the container.

And then when I run podman unshare chown -R 32:32 /home/testuser/docs/sample_dir, this will definitely produce the expected result, like below:

[testuser@localhost] ls -l /home/testuser/docs
drwxrwxrwx 1   10031   10031    38 Mar  6 23:22 sample_dir

The problem only happens when I try to do the unshare & chown on an externally mounted directory.

Is this a podman design limitation? Or is it a cifs mount limitation? Or should I be doing the cifs mounting in a different way in the first place? I don't know.

But, I sure have use cases where I would like externally mounted network drives to be owned by specific desired user IDs (other than UID 0) inside the container.

Alternative 1: To do a cifs mount using the subuids on the host

Something like this

sudo mount -t cifs //samba_server_ip/samba_share_name /home/testuser/mysamba_share_dir -o credentials=/path/to/samba/credentials,uid=10031,gid=10031,dir_mode=0777,file_mode=0777

And then volume mount it onto the container. But, now the entire samba share will owned by UID 32 inside the container. Which is not what I want. There's only a certain directory within the samba share that I would like to be owned by the UID 32, not the entire samba share.

Alternative 2: Create a new samba share on the samba server that points to a sub-directory of the first samba share and mount both shares separately using UID 1000 and UID 10031

Something like this

sudo mount -t cifs //samba_server_ip/samba_share_name /home/testuser/mysamba_share_dir -o credentials=/path/to/samba/credentials,uid=1000,gid=1000,dir_mode=0777,file_mode=0777

sudo mount -t cifs //samba_server_ip/samba_share_name /home/testuser/my_second_samba_share_dir -o credentials=/path/to/samba/credentials,uid=10031,gid=10031,dir_mode=0777,file_mode=0777

This alternative means to create a new samba share that only has the specific directory that I intend to be owned by UID 32. And, this gets even more complicated because now I will have two samba shares - one being a subset of the other. One mounted as the rootless user i.e., UID 1000 and the other (which points to a subdirectory within the first samba share) mounted as subuid 10031.

Not sure how feasible this strategy is. Moreover, this would also mean I am demanding the creation of a new samba share on the remote samba server. Something that is not always easy to convince.

Output of podman version:

[testuser@localhost ~]$ podman version
Version:      3.0.1
API Version:  3.0.0
Go Version:   go1.14.12
Built:        Mon Feb 22 09:36:53 2021
OS/Arch:      linux/amd64

Output of podman info --debug:

[testuser@localhost ~]$ podman info --debug
host:
  arch: amd64
  buildahVersion: 1.19.4
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    package: conmon-2.0.26-3.el8.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.0.26, commit: c35ce4989f35168ff023617f1ea36554ae56d952'
  cpus: 4
  distribution:
    distribution: '"centos"'
    version: "8"
  eventLogger: journald
  hostname: localhost.localdomain
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 4.18.0-240.10.1.el8_3.x86_64
  linkmode: dynamic
  memFree: 3533475840
  memTotal: 8040083456
  ociRuntime:
    name: crun
    package: crun-0.18-2.el8.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 0.18
      commit: 808420efe3dc2b44d6db9f1a3fac8361dde42a95
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +YAJL
  os: linux
  remoteSocket:
    exists: true
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    selinuxEnabled: true
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.1.4-2.module_el8.3.0+475+c50ce30b.x86_64
    version: |-
      slirp4netns version 1.1.4
      commit: b66ffa8e262507e37fca689822d23430f3357fe8
      libslirp: 4.3.1
      SLIRP_CONFIG_VERSION_MAX: 3
  swapFree: 1320378368
  swapTotal: 2613047296
  uptime: 214h 52m 27.38s (Approximately 8.92 days)
registries:
  search:
  - registry.gitlab.com
  - registry.fedoraproject.org
  - registry.access.redhat.com
  - registry.centos.org
  - docker.io
store:
  configFile: /home/testuser/.config/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    overlay.mount_program:
      Executable: /usr/bin/fuse-overlayfs
      Package: fuse-overlayfs-1.1.2-3.module_el8.3.0+507+aa0970ae.x86_64
      Version: |-
        fuse-overlayfs: version 1.1.0
        FUSE library version 3.2.1
        using FUSE kernel interface version 7.26
  graphRoot: /home/testuser/.local/share/containers/storage
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "false"
  imageStore:
    number: 8
  runRoot: /run/user/1000/containers
  volumePath: /home/testuser/.local/share/containers/storage/volumes
version:
  APIVersion: 3.0.0
  Built: 1614004613
  BuiltTime: Mon Feb 22 09:36:53 2021
  GitCommit: ""
  GoVersion: go1.14.12
  OsArch: linux/amd64
  Version: 3.0.1

Package info (e.g. output of rpm -q podman or apt list podman):

[testuser@localhost ~]$ rpm -q podman
podman-3.0.1-1.el8.x86_64

Have you tested with the latest version of Podman and have you checked the Podman Troubleshooting Guide?

Yes

Additional environment details (AWS, VirtualBox, physical, etc.):
Cent OS 8 VM or archlinux

@openshift-ci-robot openshift-ci-robot added the kind/bug Categorizes issue or PR as related to a bug. label Mar 7, 2021
@mheon
Copy link
Member

mheon commented Mar 7, 2021

@giuseppe @rhatdan This looks very similar to the NFS issue, so I'm guessing it's the same?

@rhatdan
Copy link
Member

rhatdan commented Mar 8, 2021

I think this is an issue with samba.

$ podman unshare
# chown -R 32:32 /home/testuser/mysamba_share_dir/test
# ls -l /home/testuser/mysamba_share_dir/test
# ^d
 ls -l /home/testuser/mysamba_share_dir/test

If the chown command above does not fail, and yet the directory value is not chowned, then something is happening in the samba protocol that I don't know or understand, and you would be better off asking on a samba board. As far as Podman is concerned, this is not a podman issue, but a file system issue.

@rhatdan
Copy link
Member

rhatdan commented Mar 8, 2021

BTW On NFS you would get permission denied above because the NFS Server would see this as the testuser attempting to chown files to 100031, which would not be allowed since the NFS server knows nothing about User Namespace.

@imperialguy
Copy link
Author

imperialguy commented Mar 8, 2021

samba mounting already provides a way to specify different UIDs as I described in the alternatives. But, how can someone on samba board understand a podman unshare && chown scenario?

They may understand a normal straightforward chown, but that's not what's happening here. First, podman unshare is creating some sort of a modified user namespace and then within that new namespace, a chown is being run.

Not sure how someone on the samba side would understand this kinda logic without linking it to podman in some way.

@giuseppe
Copy link
Member

giuseppe commented Mar 9, 2021

They may understand a normal straightforward chown, but that's not what's happening here. First, podman unshare is creating some sort of a modified user namespace and then within that new namespace, a chown is being run.

I don't think the uid,gid options you can specify at the mount can help when there are multiple users available in the user namespace.

chown to root happening from the podman unshare is ultimately converted to chown to your UID by the kernel, so the samba mount will just see that.

The issue exists when you try to chown to an user that is not root in the user namespace.

Have you tried what @rhatdan suggested here #9646 (comment)?

@imperialguy
Copy link
Author

imperialguy commented Mar 9, 2021

I don't think the uid,gid options you can specify at the mount can help when there are multiple users available in the user namespace.

Well, that's the point I was making as part of the alternatives explanation. That they are not good enough.

Have you tried what @rhatdan suggested here #9646 (comment)?

Not sure what you mean? If you read my initial post, that's exactly what I was trying to explain. That the command doesn't fail, but neither does it change the ownership. What am I missing here?

According to @rhatdan the problem lies with samba. But, I don't think samba folks can understand this problem without understanding about podman and podman unshare aspects first. So, perhaps podman and samba teams could communicate with each other to resolve such issues.

@rhatdan
Copy link
Member

rhatdan commented Mar 9, 2021

That is a Samba question, And has nothing to do with us. The Chown is happening within a user namespace and samba is ignoring it and returning success to the chown command. I would open up an issue with Samba on this, and cc us if you want.

@Neustradamus
Copy link

To follow this ticket

@abbra
Copy link

abbra commented Mar 13, 2021

I don't think it is Samba's problem as the namespacing is done on the client side prior to sending a request to the server. SMB protocol does not operate on UID/GIDs, it uses SIDs and translation back and forth between IDs and SIDs happens at a client side.

Manual page for mount.cifs says the following:

FILE AND DIRECTORY OWNERSHIP AND PERMISSIONS
       The core CIFS protocol does not provide unix ownership information or mode for files and directories. 
       Because of this, files and directories will generally appear to be owned by whatever values the uid= 
       or gid= options  are  set,  and  will have permissions set to the default file_mode and dir_mode for
       the mount. Attempting to change these values via chmod/chown will return success but have no effect.

       When the client and server negotiate unix extensions, files and directories will be assigned the uid, 
       gid, and mode provided by the server. Because CIFS mounts are generally single-user, and the same
       credentials are used no matter what user accesses the mount, newly created files and directories will 
       generally be given ownership corresponding to whatever credentials were used to mount the share.

       If the uid's and gid's being used do not match on the client and server, the forceuid and forcegid
       options may be helpful. Note however, that there is no corresponding option to override  the  mode.
       Permissions assigned  to  a  file  when forceuid or forcegid are in effect may not reflect the the 
       real permissions.

       When unix extensions are not negotiated, it's also possible to emulate them locally on the server using
       the dynperm mount option. When this mount option is in effect, newly created files and directories will
       receive what appear to be proper permissions. These permissions are not stored on the server however
       and can disappear at any time in the future (subject to the whims of the kernel flushing out the inode 
       cache). In general, this mount option is discouraged.

       It's also possible to override permission checking on the client altogether via the noperm option.
       Server-side permission checks cannot be overridden. The permission checks done by the server 
       will always correspond to the  credentials  used to mount the share, and not necessarily to the user 
       who is accessing the share.

Since kernel 4.13, cifs.ko defaults to SMB2+ dialects. Currently only SMB1 protocol has support for unix extensions. There is ongoing work to add POSIX extensions to SMB3.1 but it is not yet even pushed to Samba upstream trees, so even though cifs.ko has support for the upcoming SMB3.1 POSIX extensions, they are not available on Samba in any distribution in practice.

@rhatdan
Copy link
Member

rhatdan commented Mar 15, 2021

It looks like from my reading that this is not something Podman can solve and is between the kernel and the samba client. So I am going to close.

@rhatdan rhatdan closed this as completed Mar 15, 2021
@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 22, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/bug Categorizes issue or PR as related to a bug. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

No branches or pull requests

7 participants