How I solved my file permissions problems (kinda)

  • My use case is file sharing between mostly Linux clients, but still supporting the occational Windows client.


    I wanted anyone with the correct credentials to be able to mount the share with all files either read-only or read/write, depending on Privileges settings on the OMV server.


    Locally on the Linux clients, the files in the mounted shares should look just like any other files the user owns, and file permissions should look the same as any regular file (mostly files=0644, dirs=0755) - but a user with write access should be able to set the permissions any way he/she wants.


    I think this is a very common use case, and what most people expect out-of-the-box.



    Unfortunately, this is quite far from how things actually work, which leads to lots of confusion regarding file ownership and permissions. So... what can be done?


    Some background (Use Samba/CIFS and skip ahead to "So, how do we fix this?" below if you're not interested in the gritty details):


    A Unix user name or group name maps to a user ID number (UID) or a group ID number (GID), respectively, and all file permission checks are actually done against these numbers, rather that the user name. The mapping between a user name and its UID is done in /etc/passwd (take a look for yourself: 'cat /etc/passwd').


    The key point here is that the mapping is local to a certain machine. There's no guarantee at all that a certain user name maps to the same UID on different machines. (It is possible to set up such a mapping e.g. using an LDAP server, but come on, who does that?) That means that using Unix UIDs to enforce file permissions on network shares is simply broken, IMO.


    This also disqualifies NFS from the start, since it uses direct "passthrough" of the UID and GID of users and files. (In ancient times when NFS was created, people used something called yp - yellow pages - to sync UIDs/GIDs between machines on the network. This is completely insecure - anyone who has root access on any computer on the network can easily spoof any other user by simply creating a local user with the other user's yp-assigned UID. It does prevent modification of other users' files by mistake, though.)


    Ok, so something is needed that doesn't just map UIDs and GIDs straight through between server and client. Maybe Samba/CIFS could work? Well, yes, but it took some tweaking. By OMV default settings, new files are created with owner equal to the connected user, and a group of 'users' (the group ownership is forced by the SGID bit being set in the permissions of the shared directories). File permissions are forced to "at least" group read (and for directories group execute and SGID) by settings in the Samba config file. Another user who logs in won't be able to modify the files created by the first user, since the file is owned by the first user, and the write bit is not set for group. Also, the file permissions are pretty much set in stone by OMV's Samba settings.


    So, how do we fix this?


    Well, there are ways to make Samba "convert" file ownership as seen by the server and the client, respectively. First, add


    Code
    force user = nobody
    force group = users


    to the [global] section in /etc/samba/smb.conf on the server. This forces all files and directories created by samba clients in the future to be owned by the server user and group of 'nobody:users'.


    Also change the properties of any already existing files (in my case, mounted by OMV under /media/e8bc6d21.../):


    CAUTION, this might cause problems if you use other access methods like RSYNC, NFS, FTP, etc.!


    Code
    ### Recursively change owner and user:
    root@omv# chown -R nobody:users /media/e8bc6d21.../
    
    
    ### Recursively remove write access for "others", the SGID bit, and the
    ### write access to members of the file's group (this is just to make
    ### the file permissions look sane later when mounted on the clients -
    ### feel free to use any modes you prefer, or even skip this step):
    root@omv# chmod -R o-w,g-s,g-w /media/e8bc6d21.../


    Now all shared files are owned by the user 'nobody' and the group 'users', with only 'nobody' having write access - from the server's point of view, that is.


    You may also want to comment out the lines


    Code
    create mask = 0755
    force create mode = 0644
    directory mask = 0755
    force directory mode = 0755


    under each share, to allow the connected users to modify file permissions as they see fit.


    That's all for the server.



    On the client, mount the shares like this:


    Code
    user@client$ sudo mount -t cifs //<server-name>/<share-name> <local-folder> -o username=<server-samba-user>,rw,iocharset=utf8,uid=<local-user>,gid=<local-group>,forceuid,forcegid


    Where <server-samba-user> is a user set up under OMV's Access Rights Management -> Shared Folders -> Privileges tab to have at least read access to <share-name>, and <local-user>:<local-group> is the user and group on the client who should have access to the shared files.


    This connects you to the server as <server-samba-user>, but makes all files in the mount look like they are owned by <local-user>:<local-group>, with all file permissions working as they normally would.


    For another user mounting the same share, the files will look like they are owned by that user instead, regardless of who created the files.


    For users with read-only access, the fact that they don't have write access will not be reflected in the file permissions. The files will look writable, but the user will still be denied access for writing ("Read-only file system").



    Now, how do I make the changes to smb.conf stick? As soon as I modify e.g. user privileges in OMV, the file is oerwritten and my changes are lost...

    • Offizieller Beitrag

    Put some of that stuff in extra options on the main samba tab and on share extra options.

    omv 7.0-32 sandworm | 64 bit | 6.5 proxmox kernel

    plugins :: omvextrasorg 7.0 | kvm 7.0.9 | compose 7.0.9 | cputemp 7.0 | mergerfs 7.0.3


    omv-extras.org plugins source code and issue tracker - github


    Please try ctrl-shift-R and read this before posting a question.

    Please put your OMV system details in your signature.
    Please don't PM for support... Too many PMs!

  • Thanks, that seems to work.


    I added

    Code
    force user = nobody
    force group = users

    as extra options in the main samba tab, and

    Code
    create mask = 0777
    force create mode = 0600
    directory mask = 0777
    force directory mode = 0700

    as extra options to each share. A bit tedious maybe, but I guess once the shares are in place, I won't be adding more of them very often.


    This scheme actually works real nice for me: I have a bittorrent client (deluge) and a usenet client (nzbget) running on another server. On this server, I mount a "download" share twice, once in the deluge home folder (using uid=deluge,gid=deluge,forceuid,forcegid), and once in the nzbget home folder (using uid=nzbget,gid=nzbget,forceuid,forcegid). I can then also mount the same share on my client, and are thus able to administer the files myself (i.e. move completed downloads to a more protected share for movies etc.).



    Edit: I think I just found an easier way to change the default share options. The smb.conf is generated by scripts in /usr/share/openmediavault/mkconf/samba.d/; the script named 20shares is responsible for the "create mask" options. This file in turn sources the file /etc/default/openmediavault - if no default values are set there, 20shares assigns its own defaults.


    So I added

    Code
    OMV_SAMBA_SHARE_CREATEMASK="0777"
    OMV_SAMBA_SHARE_FORCECREATEMODE="0600"
    OMV_SAMBA_SHARE_DIRECTORYMASK="0777"
    OMV_SAMBA_SHARE_FORCEDIRECTORYMODE="0700"


    to /etc/default/openmediavault, and these values are now automatically applied as defaults to all Samba shares!

  • This is really interesting but...



    I quoted this because I posted this somewhere else first but maybe I'll get a faster/better answer here... Hopefully :)


    ~
    I still don't quite understand how they work but after testing a
    little bit more I found that the following actually worked for what I
    wanted:


    Code
    create mask = 0664
    force create mode = 0664
    directory mask = 0775
    force directory mode = 0775


    I'll us this for now... Let me know if you have an alternative that makes more sense.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!