Permisos de archivos, sus dueños y grupos

Para entender mejor el concepto de permisos se tendrá que tener en cuenta que cada usuario puede pertenecer a uno o más grupos. Cada usuario pertenece por lo menos a un grupo, que es establecido en el momento en que el usuario se crea. El administrador del sistema puede agregar al usuario a otros grupos. Estos grupos son necesarios para poder establecer una política de acceso más organizada dado que en cualquier momento se podría dar a un archivo el acceso a personas de un grupo determinado. Lo único que se tendría que hacer es agregar a los usuarios que se quieran dar permisos a ese grupo.

Para cada objeto (archivo) que se encuentre en el sistema, GNU/Linux guarda información administrativa en la tabla de inodos, tema que abarcaremos en mayor detalle más adelante. Entre los datos que se guardan en esta tabla se encuentran la fecha de creación del archivo, modificación del archivo y la fecha en que se cambio el inodo. Pero además contiene los datos en los que se centra toda la seguridad en Un*x. Estos son

En este tramo nos centraremos en primer medida en entender los permisos y en establecer la forma en que pueden trabajar con ellos.

Conceptos

Al ser Un*x y GNU/Linux sistemas operativos multiusuario, para que se puedan proteger los archivos se estableció un mecanismo por el cual se otorgan permisos a un determinado usuario y/o grupo. Esto permite, por ejemplo, que si existe un archivo creado por un usuario en particular, este será propiedad del usuario y también tendrá el grupo del usuario. Se permite que los archivos sean compartidos entre usuarios y grupos de usuarios. Por ejemplo si shrek quisiera puede prohibir los accesos a un archivo determinado que le pertenezca a todos los usuarios que no pertenezcan a su grupo de usuarios.

Los permisos están divididos en tres tipos: lectura, escritura y ejecución (rwx). Estos permisos pueden estar fijados para tres clases de usuario: el propietario del archivo, el grupo al que pertenece el archivo y para todo el resto de los usuarios. El permiso de lectura permite a un usuario leer el contenido del archivo o en el caso de que el archivo sea un directorio, la posibilidad de ver el contenido del mismo. El permiso de escritura permite al usuario modificar y escribir el archivo. En el caso de un directorio permite la crear nuevos archivos en él o borrar archivos existentes. El permiso de ejecución permite al usuario ejecutar el archivo, si tiene algo para ejecutarse. Para los directorios permite al usuario cambiarse a él con el comando cd.

Como se interpretan los permisos

Para poder interpretar los permisos de archivos nada mejor que utilizar el comando ls -la. Con esto vemos un listado largo de un directorio.

[shrek@pantano:~]$ ls -la
total 13
drwxr-sr-x   2 shrek    user        1024 May  2 09:04 .
drwxrwsr-x   4 root     staff       1024 Apr 17 21:08 ..
-rw-------   1 shrek    user        2541 May  2 22:04 .bash_history
-rw-r--r--   1 shrek    user         164 Apr 23 14:57 .bash_profile
-rw-r--r--   1 shrek    user          55 Apr 23 14:44 .bashrc
-rwxrwxr-x   1 shrek    user           0 Apr 14 19:29 a.out
-rwxrwxr-x   1 shrek    user          40 Apr 30 12:14 hello.pl
-r--------   1 shrek    user          64 Apr 29 14:04 hola
-rwxrw-r--   1 shrek    user         337 Apr 29 13:57 lista
-rw-rw-r--   1 shrek    user         40  Apr 30 12:31 listador
-rw-rw-r--   1 shrek    user           0 May  2 09:04 null
-rwxrwxr-x   1 shrek    user         175 Apr 30 12:30 prue.pl
-rwxrwxr-x   1 shrek    user          56 Apr 23 15:08 que.sh

Como se puede apreciar en este listado, también están el directorio actual, representado por un punto . y el directorio padre representado por dos puntos .. . Ellos también poseen permisos y atributos que son mostrados. Para ir entendiendo un poco más vamos a explicar que significan los primeros 10 dígitos. Tomemos como ejemplo el siguiente archivo

-rw-r--r--   1 shrek    user         337 Apr 29 13:57 lista

Para esclarecer un poco mas que significa cada uno de estos caracteres al inicio, utilizaremos unas tablas. Primero veamos aquellos caracteres que podrían aparecer en el primer lugar, que en el ejemplo anterior es un solo guión. Esto nos indica que es un archivo común. La tabla siguiente explica el significado del primer símbolo de acuerdo al tipo de archivo.

Tabla 1. Tipos de archivo

Contenido

Significado

-

Archivo común

d

Directorio

c

Dispositivo de caracteres (tty o impresora)

b

Dispositivo de Bloque (usualmente disco rígido o CD-ROM)

l

Enlace simbólico

s

Socket

p

Pipe

Los siguientes 9 símbolos se toman en grupos de tres y cada grupo pertenece a una clase de permisos, y se muestran a continuación

Tabla 2. Tipos de permisos

Permiso

Significado

r

Permiso de lectura

w

Permiso de escritura

x

Permiso de ejecución

Tabla 3. Grupos de permisos

Columnas

Se aplica a

Significado

2,3,4

owner

Establece los permisos para el dueño del archivo

5,6,7

group

Establece los permisos para el grupo del archivo

8,9,10

other

Establece los permisos para los usuarios que no entran en las categorías anteriores

De esta forma podremos interpretar el listado generado a partir de ls -la de mejor manera. Como ya dijimos, el primer símbolo nos esta indicando que el archivo es un archivo común. El primer grupo de tres símbolos representa los permisos para el dueño del archivo (owner) que en este caso posee permisos de lectura, escritura y ejecución. El segundo grupo de tres símbolos representa los permisos para el grupo al cual pertenece el archivo (group), que en este caso tienen permisos de lectura y escritura. El tercer grupo de tres símbolos representa los permisos para todo el resto de los usuarios (other) en este caso es solo de lectura.

El número que sigue (1) representa el número de nombres que el archivo posee. Esto indica la cantidad de enlaces que existen a este archivo y lo veremos más adelante cuando tratemos el tema de enlaces simbólicos y duros.

A continuación esta el nombre del dueño del archivo y del grupo al cual pertenece el archivo.

El "337" representa el tamaño del archivo expresado en bytes.

Lo siguiente es la fecha y hora de modificación del archivo e inmediatamente después esta el nombre del mismo.

Dependencias

Los permisos de los archivos también dependen del directorio donde estén guardados. En un ejemplo común podríamos dar el caso de un archivo que posea todos los permisos, tanto para el usuario, grupo y otros pero no se podrá acceder a él si no se cuenta con permisos de lectura y ejecución en el directorio que los contiene.

Esto funciona en el caso que se quiera restringir el acceso a un directorio determinado y a todos los archivos que este contiene. En lugar de cambiar los permisos uno por uno solo tenemos que sacarle los permisos necesarios para que se prohíba el acceso mismo al directorio y con esto no podrán ingresar para usarlos. Esto también esta dado para toda la ruta del archivo. Es decir que no solo el último directorio, el cual lo contiene, tiene que tener los permisos necesarios, sino que todos los directorios que lo preceden también.

Cambiando permisos

En el el capítulo de nombre Empezando con GNU/Linux vimos la utilización del comando chmod, pero en este entraremos a explicar en mejor forma su utilización. Además trataremos el tema de otro forma de representar los permisos posibles, la representación octal, que es extremadamente útil a la hora de establecer nuevos permisos.

El comando chmod se emplea utilizando símbolos como a,u,g,o que representan a todos (a "all"), al usuario (u), al grupo (g) y a todos los demás (o). Existen símbolos para agregar (+) quitar (-) o dejar invariantes los permisos (=). Además tendrán que usarse los símbolos característicos para cada tipo de permiso. Para el permiso de lectura (r), para el permiso de escritura (w) y para el permiso de ejecución (x). Solo el dueño del archivo puede cambiarlo con él; excepción del root que también lo puede hacer. Para ejemplificar un cambio de permisos usaremos el archivo lista.

[shrek@pantano:~]$ ls -l lista
total 1
-rwxrw-r--   1 shrek    user         337 Apr 29 13:57 lista
[shrek@pantano:~]$ chmod a-r lista
[shrek@pantano:~]$ ls -l lista
total 1
--wx-w----   1 shrek    user         337 Apr 29 13:57 lista

De esta forma se le ha sacado a todos los grupos y usuarios los permisos de lectura. Algunos ejemplos más

[shrek@pantano:~]$ chmod u+r lista
[shrek@pantano:~]$ ls -l lista
total 1
-rwx-w----   1 shrek    user         337 Apr 29 13:57 lista
[shrek@pantano:~]$ chmod o+w lista
[shrek@pantano:~]$ ls -l lista
total 1
-rwx-w-w--   1 shrek    user         337 Apr 29 13:57 lista
[shrek@pantano:~]$ chmod og-w lista
[shrek@pantano:~]$ ls -l lista
total 1
-rwx------   1 shrek    user         337 Apr 29 13:57 lista

Ahora bien, esta es la forma simbólica. Pero existe una forma un poco más sistemática que es la forma de representación octal. El comando chmod permite establecer los permisos de un archivo por medio de un número octal. Comúnmente nosotros usamos para contar una representación decimal (0,1,2,3,4,5,6,7,8,9) pero en una representación octal solo se usan 8 números (0,1,2,3,4,5,6,7). Para establecer el permiso habrá que sumar los dígitos octales de acuerdo a una tabla que se dará a continuación. Dado que no se realiza acarreo, la suma será trivial.

Tabla 4. Permisos en notación octal

Número octal

Permiso

4000

Establece el número de identificación de usuario al ejecutarse SUID [a]

2000

Establece el número de identificación de grupo al ejecutarse SGID[a]

1000

Establece el bit adhesivo[a]

0400

Lectura por parte del dueño

0200

Escritura por parte del dueño

0100

Ejecución por parte del dueño

0040

Lectura por parte del grupo

0020

Escritura por parte del grupo

0010

Ejecución por parte del grupo

0004

Lectura por parte de los otros

0002

Escritura por parte de los otros

0001

Ejecución por parte de los otros
Notas:
a. Se verá al finalizar el tema

Para dar un ejemplo de la suma que se tendrá que realizar, tomemos un archivo con los permisos expresados en forma simbólica y realicemos la conversión. Para representar -rwxr-x---

  0400      Lectura por parte del dueño
+ 0200      Escritura por parte del dueño
+ 0100      Ejecución por parte del dueño
+ 0040      Lectura por parte del grupo
+ 0010      Ejecución por parte del grupo
-----------------------------------------
  0750      Resultado

De esta forma si lo que quisiéramos es cambiar los permisos de un archivo, solo se tendría que efectuar la suma necesaria y establecerlo con el comando chmod. Si quisiéramos cambiar los permisos para que el dueño tenga permisos de lectura y escritura y que el grupo y otros solo tengan permisos de lectura, la sintaxis es

[shrek@pantano:~]$ chmod 0644 lista
[shrek@pantano:~]$ ls -l lista
total 1
-rw-r--r--   1 shrek    user         337 Apr 29 13:57 lista

Con la práctica se sabrán cuales son las sumas mas utilizadas y podrán ver que es mucho más sencillo el establecer de esta forma los permisos de archivos.

Cambiando grupos y usuarios

Lo que nos queda por ver es el caso en que se quisiera cambiar el usuario o el grupo del archivo. Para esto se usa el comando chown y su sintaxis es similar a la de chmod pero con la variante que se dan los nombres del usuario y del grupo. Si quisiéramos cambiar el nombre de usuario del archivo lista tendremos

[root@pantano:/home/shrek]# ls -l lista
total 1
-rw-r--r--   1 shrek    user         337 Apr 29 13:57 lista
[root@pantano:/home/shrek]# chown fiona lista
[root@pantano:/home/shrek]# ls -l lista
total 1
-rw-r--r--   1 fiona    user         337 Apr 29 13:57 lista

Si se quisiera cambiar también el nombre del grupo, se tendría que poner un punto entre el nombre de usuario y el grupo

[root@pantano]# ls -l lista
total 1
-rw-r--r--   1 shrek    user         337 Apr 29 13:57 lista
[root@pantano]# chown fiona.ventas lista
[root@pantano]# ls -l lista
total 1
-rw-r--r--   1 fiona    ventas         337 Apr 29 13:57 lista

Por supuesto que tanto el usuario como el grupo al que se hacen referencia tendrán que existir en el sistema, sino se producirá un error. En el caso que solo se quiera cambiar el grupo y no el usuario, se tendrá que poner un punto delante del nombre del grupo, omitiendo poner el nombre del algún usuario. O si se quiere, se podrá poner el nombre de usuario que estaba anteriormente.

[root@pantano]# ls -l lista
total 1
-rw-r--r--   1 shrek    user         337 Apr 29 13:57 lista
[root@pantano]# chown .ventas lista
[root@pantano]# ls -l lista
total 1
-rw-r--r--   1 shrek    ventas         337 Apr 29 13:57 lista

Puntos adicionales

Explicaremos algunos puntos sobre permisos que son de gran utilidad para la seguridad de nuestro sistema.

umask

Esta es la abreviatura de user file-creation mode mask o máscara del modo de creación de archivos de usuario y es un número octal de cuatro dígitos que se utilizan para fijar los permisos de los archivos recién creados. Esto puede ocasionar confusión pero en realidad es una utilidad que permite el uso del sistema por múltiples usuarios sin que peligre la privacidad. En la mayoría de los Un*x los archivos que son creados por el usuario, poseen permisos 0666 que dan permiso de lectura y escritura a cualquier usuario. En relación con los programas, estos se crean con 0777 donde cualquier usuario puede leer, escribir y ejecutar el programa. Normalmente el administrador del sistema aplica una máscara al usuario en el archivo .bash_profile y esta es usada para la creación de archivos haciendo una operación simple "AND" bit por bit con el complemento del valor umask bit por bit. La función umask esta integrada al intérprete de comandos. Para ejemplificar el proceso tomemos un archivo creado por el usuario.

  0666      Modo predeterminado de creación de archivos
- 0022      Umask
-------------------------------------------------------
  0644      Modo resultante

El modo resultante es que el dueño tiene permisos de lectura y escritura y los demás y el grupo solo de lectura.

  0666      Modo predeterminado de creación de archivos
- 0077      Umask
-------------------------------------------------------
  0600      Modo resultante

El modo resultante es que el dueño tiene permisos de lectura y escritura y los demás y el grupo no tienen ningún permiso. Una forma de darse cuenta de la forma en que funciona el umask es tener en cuenta que el valor 2 inhabilita el permiso de escritura mientras que el valor 7 inhabilita los permisos de lectura escritura y ejecución. A continuación daremos una tabla con los valores comúnmente usados para el umask.

Tabla 5. Valores usuales de la variable umask

Umask

Accesos del usuario

Accesos del grupo

Accesos de los otros

0000

Todos

Todos

Todos

0002

Todos

Todos

Lectura y ejecución

0007

Todos

Todos

Ninguno

0022

Todos

Lectura y ejecución

Lectura y ejecución

0027

Todos

Lectura y ejecución

Ninguno

0077

Todos

Ninguno

Ninguno

SUID y SGID

Existen ocasiones que los usuarios necesitan ejecutar algún programa que requiere de privilegios. Un ejemplo de esto es el uso del programa passwd para cambiar la contraseña. Sería un error darle a los usuarios los privilegios necesarios para que puedan ejecutar esta clase de programas ya que el usuario podría cambiarse de grupo o crear una cuenta con privilegios de root. Para que esto no suceda, se implemento en Un*x, un sistema por el cual un programa que cuente con SUID o SGID puede ser ejecutado con los privilegios del dueño y/o grupo del programa. Para que quede más claro se tiene que saber que cada usuario esta identificado por el sistema con un número de identificación tanto para él, como para el grupo. Este número se denomina UID (user ID) para el caso de los usuarios y GID para el caso de los grupos. Por ejemplo, un usuario podría tener un UID 100 y un GID 500. En el caso del root, este tiene UID 0 y GID 0. Más adelante sé verá esto en mayor detalle. Lo que se efectúa con el sistema SUID es una adquisición temporal de un UID o GID distinto al propio cuando se está ejecutando el programa. Cuando un programa cambia de UID se denomina SUID (set-UID: se establece UID) y cuando cambia de GID se denomina SGID (set-GID: se establece GID) Un programa puede ser SUID y SGID al mismo tiempo. Para darse cuenta si un programa es SUID o SGID basta con hacer un listado largo con el comando ls -l y se verá que donde tendría que estar una x, que asigna permisos de ejecución, va a estar una letra s.

[shrek@pantano:~]$ ls -l /usr/bin/passwd
-rwsr-sr--    1 root  bin     36068 2003-06-23 20:40 /usr/bin/passwd*
/usr/bin/passwd

Bit adhesivo

En los antiguos sistemas Un*x, la memoria era algo esencial y escasa dado su costo. Para poder aprovechar más esta, se empleo una tecnología que mantenía parte de programas esenciales en el área swap de memoria para que pudieran ser usados más rápidamente dado que si se tendrían que ir a buscar al disco se adhesivo o sticky bit y estos archivos así marcados eran los que valía la pena mantener ya que esas partes del programa que se guardaban en memoria también podían ser usadas por otros.