Compartir directorios con Samba

Publicado en Linux, Windows el 8 de June, 2009 por Fran. (3 comentarios)

En el anterior post explicaba cómo compartir impresoras con Samba. Como sé que os gustó, hoy os explico cómo compartir directorios con Samba.

Instrucciones

Voy a partir de qué tenemos la siguiente estructura de directorios que se quiere compartir:

drwxr-x--- user group dir01
drwxr-x--- user group dir02
drwxr-x--- user group dir03

Como se puede ver, a estos directorios sólo puede acceder el usuario user y los usuarios del grupo group, aunque estos últimos sólo con permisos de lectura sobre los directorios.

Lo primero que se debe hacer es añadir el usuario (o los usuarios) que podrán acceder a nuestros datos compartidos. Para ello se ejecuta:

# smbpasswd -a user

Nos pedirá una contraseña, ésta puede ser distinta a la que tenga el usuario para acceder a la máquina.

Una vez añadido el usuario (o los usuarios), se podrá configurar Samba para que comparta los directorios. Para ello se modifica el archivo /etc/samba/smb.conf y se añade un elemento del siguiente tipo por cada directorio a compartir:

[nombre_directorio_a_compartir]
  comment = Comentario del directorio compartido
  path = /ruta/al/directorio
  read only = yes # Indica si el acceso será sólo lectura
  write list = user # Usuarios/grupos que tendrán acceso de escritura
  create mask = 0640 # Máscara de los permisos al crear archivos
  directory mask = 0750 # Máscara de los permisos al crear directorios
  guest ok = no # Acceso sin autenticación

De este modo, para el ejemplo que he puesto se tendrían que añadir tres elementos de este tipo, quedando el archivo similar a este:

[global]
  display charset = UTF-8
  server string = NOMBRE-DE-LA-MAQUINA
  workgroup = GRUPO-DE-TRABAJO
  netbios name = NOMBRE-NETBIOS-MAQUINA
  invalid users = root # Para que no se pueda acceder como root

[dir01]
  comment = Directorio 01
  path = /home/user/dir01
  read only = yes
  write list = user
  create mask = 0640
  directory mask = 0750
  guest ok = no

[dir02]
  comment = Directorio 02
  path = /home/user/dir02
  read only = yes
  write list = user
  create mask = 0640
  directory mask = 0750
  guest ok = no

[dir03]
  comment = Directorio 03
  path = /home/user/dir03
  read only = yes
  write list = user
  create mask = 0640
  directory mask = 0750
  guest ok = no

Después de esto sólo hay que reiniciar Samba y listo, ya se podrá acceder a dichos directorios compartidos utilizando el usuario user.

# /etc/init.d/samba restart

Basado en Compartir directorios con Samba del blog de Iván López.

Compartir impresoras con Samba

Publicado en Linux, Windows el 26 de May, 2009 por Fran. (6 comentarios)

Estos días en el trabajo me ha tocado lidiar con la configuración de un servidor que tenemos para almacenamiento e impresión, con sus directorios compartidos e impresora compartida.

Hasta hace poco este servidor utilizaba Windows 2003, hasta que un día decidió morir en extrañas circunstancias, así que como los que nos encargamos de dicho servidor nos manejamos mejor en Linux decidimos instalar Debian Lenny y utilizar Samba para los directorios compartidos y la impresora compartida, ya que en nuestra red tenemos variedad de Windows y Linux.

Instrucciones

Hay que tener instalado CUPS. Una vez instalado, realizar los siguientes pasos para configurar CUPS:

  1. Añadir la siguiente línea al archivo /etc/cups/cupsd.conf, suponiendo que nuestra red sea 192.168.0.0/255.255.255.0:
    Allow From 192.168.0.*
  2. Descomentar la siguiente línea del archivo /etc/cups/mime.convs:
    application/octet-stream application/vnd.cups-raw  0 - 

De este modo, CUPS permitirá compartir remotamente la impresora. Ahora hay que configurar Samba para que las máquinas con Windows puedan usar la impresora, así que a seguir los siguientes pasos:

Editar el archivo /etc/samba/smb.conf de modo que quede similar a este que muestro:

[global]
  workgroup = GRUPO-DE-TRABAJO
  netbios name = NOMBRE-NETBIOS-MAQUINA

  #this section is only to share the printer
  printcap name = cups
  disable spoolss = yes
  show add printer wizard = no
  printing = cups

[printers]
  comment = Printer in Linux
  path = /var/spool/samba
  create mode = 0700
  guest ok = yes
  print ok = yes
  use client driver = yes
  browseable = yes
  public = yes

El directorio /var/spool/samba se debe crear si no existe y tener permisos 0777.

Con esta configuración se comparte la impresora sin necesidad de autenticarse, ya que el nivel de seguridad lo permite (security = share) y se permite autenticarse como invitado (guest ok = yes). El elemento printers permite que samba comparta automáticamente todas las impresoras conectadas con las propiedades que se le indiquen en dicho elemento.

Si se quisiera obligar a autenticarse para poder usar la impresora, habría que añadir un usuario a samba ejecutando:

# smbpasswd -a usuario

Además, habría que cambiar el nivel de seguridad (con quitar la propiedad security valdría) y no permitir la autenticación como invitado (guest ok = no).

Para finalizar, sólo habría que reiniciar CUPS y Samba:

# /etc/init.d/cups restart
# /etc/init.d/samba restart

Basado en Sharing a printer to XP clients with Samba and Cups de Debian Administration (en inglés).

Manejar las señales de control de la consola de Windows

Publicado en C/C++, Windows el 15 de April, 2009 por Fran. (2 comentarios)

En Windows existen cinco señales de la consola que se emiten cuando se producen varios eventos, todos relacionados con el fin de la aplicación (Ctrl+C o Ctrl+Break), con el cierre de la consola (más llanamente, es el cierre de la ventana del cmd.exe) o con el fin de la sesión en Windows (el cierre de una sesión de usuario o el apagado del sistema).

Windows emite estas señales a las aplicaciones correspondientes para que puedan manejarlas y terminar de una forma adecuada, por ejemplo: realizando las operaciones necesarias para no dejar archivos en algún estado catastrófico perdiendo la información de estos.

Manejando las señales

Para manejar estas señales las aplicaciones disponen de una lista de manejadores, en la que en principio sólo hay una función que termina la ejecución del proceso. Para añadir/borrar un manejador a la lista se dispone de la función SetConsoleCtrlHandler:

BOOL WINAPI SetConsoleCtrlHandler (PHANDLER_ROUTINE HandlerRoutine, BOOL Add);

Donde los parámetros son:

  • HandlerRoutine: Es un puntero a la función que manejará las señales recibidas. Tendrá la forma:
    BOOL WINAPI CtrlHandler (DWORD CtrlType)
  • Add: Si su valor es TRUE indica que la función se añadirá a la lista de manejadores de las señales, en cambio si es FALSE indica que la función se borrará de la lista de manejadores.

Leer el resto »

Tuberías en Windows

Publicado en C/C++, Windows el 22 de June, 2008 por Fran. (2 comentarios)

Las tuberías (o pipes, en inglés) son un recurso utilizado para comunicar varios procesos, podríamos decir que es un sistema muy básico de mensajería entre procesos, se trata de un archivo en el que un proceso escribe y otro lee.

Gracias a las tuberías podemos redirigir la entrada estándar, la salida estándar y/o la salida de error de un programa que ejecutemos dentro de nuestro programa, de modo que podamos obtener dicha salida para posteriormente procesarla como queramos.

A continuación, os muestro cómo se redirige la salida estándar y la salida de error, en Windows, de un proceso que ejecutemos dentro de nuestro programa.

Leer el resto »

Accediendo al registro de Windows

Publicado en C/C++, Windows el 23 de February, 2008 por Fran. (2 comentarios)

Desde hace ya unos años no tocaba Windows para nada, y de programar pues ni hablemos, desde la universidad en que programaba en PASCAL programas para la consola, no había vuelto a tocar nada relacionado con Windows, y menos programar en C sobre Windows (¡herejía!).

Pero por razones sobrenaturales (trabajo), he tenido que programar en C sobre Windows. Al principio me dieron el Visual Studio 2005 (o algo así), y nada más ver que era bastante lioso para lo que quería hacer, me decidí a usar DevCpp que es libre, usa MinGW y puedo programar para Windows usando la API Win32.

Después de este rollo que os he soltado, viene lo que pretendía contaros, y es cómo acceder al registro de Windows usando el lenguaje C. Puede parecer difícil, pero la verdad es que los señores de Microsoft tienen una buena cosa llamada msdn, en la que encuentras cualquier cosa siempre que sepas más o menos donde buscar. Para este caso podemos encontrar toda la información relacionada con el registro aquí.

Pero no os voy a dejar a la buena de dios, así que os voy a poner un pequeño ejemplo de cómo acceder a una clave del registro, para que podáis saber más o menos cómo funciona.

#include <windows.h>

const char *ruta_reg = "Ruta\\del\\registro";

char *get_clave (char *clave) {

    DWORD BufferSize = 2048;
    DWORD cbData;
    DWORD dwRet;
    DWORD regType;
    HKEY hkey;

    if (RegOpenKeyEx (HKEY_CURRENT_USER, TEXT (ruta_reg), 0,
                      KEY_READ, &hkey) == ERROR_SUCCESS)
    {

        PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc (BufferSize);
        if (PerfData == NULL) {
            printf ("Error\n");
            return NULL;
        }

        cbData = BufferSize;
        dwRet = RegQueryValueEx (hkey, TEXT (type), NULL, &regType,
                                 (LPBYTE) PerfData, &cbData);

        /* Get a buffer that is big enough. */
        while (dwRet == ERROR_MORE_DATA) {
            BufferSize *= 2;
            PerfData = (PPERF_DATA_BLOCK) realloc (PerfData, BufferSize);
            if (PerfData == NULL) {
                printf ("Error\n");
                return NULL;
            }

            cbData = BufferSize;

            /* Conseguimos el valor de la clave */
            dwRet = RegQueryValueEx (hkey, TEXT (clave), NULL, &regType,
                                     (LPBYTE) PerfData, &cbData);
        }

        /* Error */
        if (dwRet != ERROR_SUCCESS) {
            printf ("Error\n");
            return NULL;
        }

        printf ("%s\n", (char *) PerfData);

        return (char *) PerfData;
    }

    return NULL;
}

Sólo tenéis que cambiar la constante ruta_reg por una válida (que esté en HKEY_CURRENT_USER, ya que creo que si no eres administrador no puedes acceder a otra) y pasar como parámetro clave el nombre de la clave de la que queremos conocer su valor.