chmod - setting permissions

In the last module, we examined the permissions that may be set on a file. To set the desired permissions, use the command chmod

The general structure of the chmod is :

chmod permissions file_list

The "file_list" is a space delimited list of one or more filenames.

The filenames listed may be any file of any kind as long as you own them. However, if chmod is applied to a symbolic link, the command will follow the link and set the permissions on the linked original file.

The "permissions" argument is a single string (no spaces) designating the permissions to set. This argument may target all permission fields of a file or just a limited subset of permissions.

The normal permission flags (read, write, and execute for user, group, and others) are stored in a 9 bit flag in the file's inode. Each bit is either set to on (1) or off (0).

For example, we have a file with read, write, and execute permissions for the owner (user), read and execute only for the group members, and no permissions for all others. The flag settings would look like :

user    group   other
r w x   r w x   r w x
1 1 1   1 0 1   0 0 0
Obviously, working with permissions as a set of zeros and ones is not an ideal situation. However, binary values can also be represented as octal values if grouped into 3 bit sets. A 3 bit octal number can have a value of 0-7.

To check, here is a table of of all thee bit values :

binary  =   octal
0 0 0   =       0
0 0 1   =       1
0 1 0   =       2
0 1 1   =       3
1 0 0   =       4
1 0 1   =       5
1 1 0   =       6
1 1 1   -       7

We can convert a binary to an octal value by adding numbers by the power of 2. Recall that with decimal numbers, each digit is a value multiplied by the power of 10. So 273 is :

      2        7        3
*  10^2  +  10^1  +  10^0

  2*100  +  7*10  +   3*1  = 273

Similarly, each bit in a binary number is a power of 2. So a 3 bit number such as the group permission above, 101(binary), be represented as :

    1     0     1
* 2^2   2^1   2^0

  1*4   0*2   1*1 = 4 + 0 + 1 = 5

So our file permission example above becomes :

  user    group   other
  r w x   r w x   r w x
  1 1 1   1 0 1   0 0 0   binary
* 4 2 1   4 2 1   4 2 1
-----------------------
  4 2 1   4 0 1   0 0 0

  4+2+1=7 4+1=5     0=0

   750 decimal
To set the access permissions of a file to these, use the chmod with the desired permissions.

chmod 750 target_file

Although using decimal values is an improvement over working with binary, you must perform the numeric calculation and you must also set all bits at the same time.

chmod supports a symbolic representation for each type of user and permission field and the type of permission change to implement. The symbolic representation can be used to target all flag bits or just specific ones.a

Available symbolic representations :

u   user (owner)
g   group assigned to file
o   all other users
a   all three user types.

r   read access
w   write access
x   execute access

s   suid or sgid bit
t   sticky bit

+   turn on target bit[s]
-   turn off target bit[s]
=   set target bits to exact value

For our example above (u = read,write,execute, group = read,execute, other = none), here is the chmod using the symbolic representation :

chmod u=rwx,g=rx,o= target_file

First notice that the permissions argument is a single comma delimited string with no spaces. The order of the user type is not critical, but the practice is to match the arrangement of the permissions bits of the file.

The chmod above indicates that the read, write, and execute bits for the user permissions are all on, the read and execute bits for the group permissions are on but the write bit is off because the w was not specified, and all bits for other's permissions should be off because none were specified..

Using symbolic permissions also allow you to target only certain permission subsets. chmod a=r target_file will turn on permissions for user, group, and other, and turn off all other permissions.

You can also target more than one user types. chmod u=rx target_file will set the user's (owner) read and execute permissions and turn off the user's write permissions. However, because group and other were not stated as targets to change, they will not be affected. chmod&nbs;u=rx,g=rx target_file is the similar except it does target both the user and group permissions while ignoring others.

Because the = affects all three access fields (r,w,x), it still requires extra work if you are targeting one or two specific access fields. To make targeting specific flags easier, chmod uses + and - with the specific user and access flags to target. It will leave all untargeted flags in their current state.

chmod g-w,o-rwx target_file

In the above example, we have turned off the write bit for the group and all bits for others. The rwx bits for user were untouched, and neither were the read and execute bits for the group. We could have also used chmod g-w,o= target_file.

In the same way, the + will only turn on the bits targeted. So chmod a+x target_file will turn on execute permissions for user, group, and other without affecting in any other permission flags.

Additional flags. Besides the read, write, and execute bits (rwx), each file has the suid, guid, and sticky bits explained previously. These bits are also set with chmod.

Remember that we viewed permissions as 3 sets of 3 bit flags. The suid, guid, and sticky bit can be viewed as an additional set of bits preceding the regular set.

       user    group   other
s g t  r w x   r w x   r w x
0 0 0  1 1 1   1 0 1   0 0 0

s = suid
g = guid
t = sticky

To set the permissions of a file to have rwx for user, and rx for the group and others and turn on suid bit using the octal values, lay out the bits and convert to octal :

       user    group   other
s g t  r w x   r w x   r w x
1 0 0  1 1 1   1 0 1   1 0 1
4 0 0  4 2 1   4 0 1   4 0 1
    4      7       5       5

chmod 4755 suid_file

Luckily, chmod supports the symbolic notation for the suid, guid, and sticky bits. The same permissions can be specified as :

chmod u=rwxs,go=rx suid_file

If all you need to do is turn on the suid bit :

chmod u+s suid_file

And to turn on the suid bit :

chmod u-s suid_file

For guid, apply the change to the group permissions :

chmod g+s guid_file

For the sticky bit, apply the change to the other permissions AND use a t rather than an s :

chmod o+t sticky_file

When we use ls -l, we can see the representation for read, write, and execute permissions for user, group, and other. But there is no fields for the suid, guid, and sticky bits. To display the status of these bits, the execute permission for each type of user does double duty. If the suid bit is set, an s will appear in the x position for user, and if it is lower case, the execute bit is also on, if it is in caps, then the execute bit is off.

The same is true for the sgid bit. For the sticky bit, look for t lower or upper case in the other permission field. Lower case indicates that execute is set.

Below is the output of ls -l (comments in parenthesis are not part of the output)

-rwSrw-rw- 1 berezin work      0 2007-06-22 16:15 suid  (user execute off)
-rwsrwxrwx 1 berezin work      0 2007-06-22 16:15 suidx (user execute on)

-rw-rwSrw- 1 berezin work      0 2007-06-22 16:15 guid  (group execute off)
-rwxrwsrwx 1 berezin work      0 2007-06-22 16:15 guidx (group execute on)

-rw-rw-rwT 1 berezin work      0 2007-06-22 16:15 sticky (other execute off)
-rwxrwxrwt 1 berezin work      0 2007-06-22 16:15 stickyx (other execute on)

So far we discussed actively setting or changing the access permissions of a file. But what permissions are assigned to a file by default?

When a file is created, unless the user as indicated some restriction, it receives the maximum possible access. For most files this means that read and write are enabled for users, groups, and others. For files that are meant to be executable, such as a file built by the gcc compiler, the execute will also be on for each user category.

However, most users prefer a more restrictive permission by default. Most command shells provide a command to set a mask that restricts the default permissions assigned to a file when it is created. This command is umask.

To see the current setting of umask, run the command with no arguments at the prompt :

umask

On our Linux system, you will see a four digit octal value. The first digit represents the 3 bits for suid, guid, and the sticky bit, and the next three represent the read, write, and execute bits for user, group and other.

When you first look at the values displayed by umask, it may be unclear where the values come from. Because umask is a mask, it represents the bits you want off by default.

To see how the value is determined, first decide which permissions you will allow by default. Let's say you will allow the the suid, guid, and sticky bit to be set along with allow all permissions for the user, but only read and execute permissions for group and other. Lay out the bits as if you were setting them. However, because this is a mask, you will invert the :

       user    group   other
s g t  r w x   r w x   r w x
1 1 1  1 1 1   1 0 1   1 0 1   allowable permissions

0 0 0  0 0 0   0 1 0   0 1 0   inverted mask

0 0 0  0 0 0   0 2 0   0 2 0   powers of 2

    0      0       2       2   octal representation

To set the umask, run umask at the prompt with the desired mask.

umask 0022

Lets say we want to set the mask so that no permissions are granted to groups or others, but the other access will remain the same.

       user    group   other
s g t  r w x   r w x   r w x
1 1 1  1 1 1   0 0 0   0 0 0   allowable permissions

0 0 0  0 0 0   1 1 1   1 1 1   inverted mask

0 0 0  0 0 0   4 2 1   4 2 1   powers of 2

    0      0       7       7   octal representation

This is the preferred umask for this class as it adds extra protection against some else copying your assignments. The umask is usually set in one of the configuration files read when the user first logs in. We will look at these in some detail in a later module. For now, if you are planning on creating several files during a login session, run umask with the desired mask at the prompt. You need to run umask only once during a login session unless you want to change the mask.

Some other things to know about umask :

  • umask cannot make a command turn on permissions it doesn't turn on by default. It can only block the command from turning a permission on.

  • umask will not change the permission status of an existing file. You must run chmod to change a file's current status.

  • In most cases, when setting the permission mask with umask you do not need to specify the suid, sgid, and sticky bit digit. In the example above,

    umask 077

    would be sufficient to set the mask desired.