Linux: Files membership and modes

Linux: Files membership and modes

Everything in Linux is a file, even your video card is a file, and you need a way to control the user access to those files.

Files ownership

A file is owned, by default, by a user and a group. Beside that, there is another concept, called "other", which means everyone else.
When you are creating a file, the owner of the file is your user and your default group. Let's create a file called "myfile":

$ touch myfile
$ ls -l myfile
-rw-r-xr--    1 smocanu  smocanu         0 Jul 14 05:50 myfile
In my case, the user who owns this file is "smocanu" and the group is "smocanu".

You can change any of this at any point, using chown/chgrp tools. For example, to change the user that owns this file you need run, as root or with sudo:
$ sudo chown nginx myfile
$ ls -l myfile
-rw-rw-r-- 1 nginx smocanu 0 Jul 14 05:54 myfile

You can also change both user and group with the same command:
$ sudo chown smocanu:nginx myfile
$ ls -l myfile
-rw-rw-r-- 1 smocanu nginx 0 Jul 14 05:54 myfile

Or just the group, using ":group" as argument for chown command, or chgrp command:
$ sudo chown :smocanu myfile
$ sudo chgrp nginx myfile
$ ls -l myfile
-rw-rw-r-- 1 smocanu nginx 0 Jul 14 05:54 myfile

Files and file modes, or own rights

The owner of the file has some access to the file that he owns it. In our case, we are seeing the "-rw-rw-r--" string, in front of the listed file.
This is the file mode(you'll see here the file type and rights). The first bit("-") is file type, we'll get into it later.
The rest of the mode is a pair of rights, split into tree parts( user, group and other, each of them with 3 type of righs rwx ).
rwx    r-x     r-x
user   group  other
The r meas read and it has a octal value of 4, the w is write and it has a octal value of 2, while x stands for execute and it has an octal value of 1.
An "-" here means that this bit is not set, so a r-x means that you can read it and execute it, but you cannot write to it. You can also address it in octal, r+x=(4+1)=5.
So the rwxr-xr-x mode could also be represented as 755.

As said before, everything in Linux is a file and we need a way to differentiate those files. Here comes into the picture the file type. We saw, in previous examples, that the fist character of the mode of the file was -, which means regular file. Besides that, there are other file types:

- = Regular File 

 $ ls -l myfile
-rw-r--r-- 1 silviu silviu 0 Jul 14 11:52 myfile

d = Directory 

$ mkdir mydir
$ ls -ld mydir/
drwxr-xr-x 2 silviu silviu 4096 Jul 14 11:53 mydir/

l = Symbolic Link 

$ ln -s myfile mysymlink
$ ls -l mysymlink
lrwxrwxrwx 1 silviu silviu 6 Jul 14 11:53 mysymlink -> myfile

b = Block Special Device

$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 Dec  3  2014 /dev/sda

c = Character Device 

$ ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5 Dec  3  2014 /dev/zero

 s = Unix Socket


$ ls -l /var/run/mysqld/mysqld.sock
srwxrwxrwx 1 mysql mysql 0 Dec  3  2014 /var/run/mysqld/mysqld.sock



p = Named Pipe

$ mkfifo pipe
$ ls -l pipe
prw-r--r-- 1 silviu silviu 0 Jul 14 13:19 pipe

Special file modes


There are also special modse, represented by the first bit. Those mode are:

  • sticky bit, represented by octal 1, or letter t
  • setGid, represented by octal 2, or letter s 
  • setUid, represented by octal 4, or letter s
Sticky bit is used on /tmp directory of every Linux distribution and it will ensure that only the owner of the file will be able to write to a file, even if other users should be able, because of group or other right configured on that file.
$ ls -l / | grep tmp
drwxrwxrwt   5 root root  4096 Jul 14 06:44 tmp


SetGid is used to make a file to be executed as the group owner of the file, even if you're not member of that group. Also, it is used on directory, to make sure that files created there will inherit the group ownership of the directory, even if the user that is creating files doesn't have that group as his primary group.
$ chmod 2775 mydir/
$ ls -ld mydir/
drwxrwsr-x 2 silviu silviu 4096 Jul 14 11:53 mydir/
SetUid is used to make a file to be executed as file's user id, ignoring the user id of the user that is running that file. Example of that file is passwd and ping commands.
$ ls -l $(which passwd )
-rwsr-xr-x 1 root root 47032 Feb 17  2014 /usr/bin/passwd

Direcories (drwxr-xr-x)

On directories, the execute bit has another meaning, as you cannot execute a directory. The execute(x) is granting the idea of traversal, which means that you can access ( cd ) it.


Working with files modes

The ways that you can see the modes of a file are "ls" and "stat". We saw the ls command and we'll try also the stat command:
$ stat myfile
  File: ‘myfile’
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 902h/2306d      Inode: 658235      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ smocanu)   Gid: (  119/   nginx)
Access: 2015-07-14 05:54:37.056354110 +0200
Modify: 2015-07-14 05:54:37.056354110 +0200
Change: 2015-07-14 06:00:38.188353118 +0200
 Birth: -

This will provide you information about the file mode, both string and octal representation and also info about file ownership.

Changing files modes

To change the mode of a file using string representation, you have to use: u, for user, g, for group, o, for other and a, for all of them. To assign rights, you can use [ugoa]=| -|+[rwx].

$ chmod u=rwx,g=r-x,o=r-x myfile
$ chmod g+w my myfile
$ chmod 0755 myfile

Umask, the default mode

The mode for a new created file is the difference between the maximum right(rwx/7) of a file and user umask value.

$ umask 077
$ touch myfile
$ ls -l myfile
-rw------- 1 smocanu smocanu 0 Jul 14 07:08 myfile
$ mkdir mydir
$ ls -ld mydir
drwx------ 2 smocanu smocanu 4096 Jul 14 07:08 mydir

Real life examples

I have a webserver which needs to serve a lot of content. In the same time, the web developer needs to be able to read and write files on the DR.
To make this happen, I'm setting the owner( user and group ) of the file to the web developer user/group and for the web server user I'm letting the "other" rights.

$ find /var/www/ -type f -exec chown 0775 {} \;
$ find /var/www/ -type d -exec choen 2775 {} \;

Extended ACL

Fist of all, you need to make sure that you have installed the extended acl support for you OS. In my case, Ubuntu, I'm installing the acl package:
$ sudo apt-get install acl
[sudo] password for smocanu:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
  libossp-uuid16
Use 'apt-get autoremove' to remove it.
The following NEW packages will be installed
  acl
0 to upgrade, 1 to newly install, 0 to remove and 34 not to upgrade.
Need to get 43.8 kB of archives.
After this operation, 197 kB of additional disk space will be used.
Get:1 http://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu/ trusty/main acl amd64 2.2.52-1 [43.8 kB]
Fetched 43.8 kB in 0s (455 kB/s)
Selecting previously unselected package acl.
(Reading database ... 76947 files and directories currently installed.)
Preparing to unpack .../acl_2.2.52-1_amd64.deb ...
Unpacking acl (2.2.52-1) ...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Setting up acl (2.2.52-1) ...

After that, you should check if your fs is mounted with the acl option, in my case "/"( add acl option to /etc/fstab to make this change permanent) :
$ sudo mount -o remount,acl /
Let's add full rigts to nginx user on directory mydir:
$ ls -ld mydir/
drwx------ 2 smocanu smocanu 4096 Jul 14 07:08 mydir/
$ getfacl mydir/
# file: mydir/
# owner: smocanu
# group: smocanu
user::rwx
group::---
other::---

$ setfacl -m  u:nginx:rwx mydir/
$ getfacl mydir/
# file: mydir/
# owner: smocanu
# group: smocanu
user::rwx
user:nginx:rwx
group::---
mask::rwx
other::---
$ touch mydir/myfile
$ getfacl mydir/myfile
# file: mydir/myfile
# owner: smocanu
# group: smocanu
user::rw-
group::---
other::---
If you need the newly created files on that directory to inherit parent directory rights, you have to use -d ( default ) switch for the setfacl command:

$ setfacl -d -m  u:nginx:rwx mydir/
$ touch mydir/myfile2
$ getfacl mydir/myfile2
# file: mydir/myfile2
# owner: smocanu
# group: smocanu
user::rw-
user:nginx:rwx                  #effective:rw-
group::---
mask::rw-
other::---


Comments

Popular posts from this blog

JunOS - mount USB stick

SSH: Generating and using SSH keys

JunOS - loging on secondary node of a cluster and copying file between nodes