jueves, 22 de enero de 2015

Copias de Seguridad en OpenLDAP

En este artículo os voy a mostrar como exportar e importar datos. De esta manera nos aseguramos de tener un backup o copia de seguridad de nuestro directorio activo.

EXPORTAR LDAP

Asumiendo una sesión de terminal Linux, como usuario root, introduciremos el siguiente comando:

slapcat -l ruta/archivo_backup.ldif

Si deseamos exportar también la configuración de la base de datos de LDAP, utilizaremos la siguiente sintaxis:

slapcat -l ruta/archivo_backup.ldif -f ruta/archivo_config.conf

IMPORTAR LDAP

La importación de los datos es un poco más compleja, ya que requiere que se elimine la base de datos para añadir todos los datos del fichero ldif que se exportaron en el paso anterior.

Para ello, desde la terminal Linux, y como usuario root, Seguiremos los siguientes pasos:

1) Detenemos el servicio de LDAP:

/etc/init.d/slapd stop

2) Eliminamos los ficheros de la base de datos de LDAP:

rm -Rf /var/lib/ldap/*

3) Importamos los datos del backup de LDAP:

slapadd -v -c -l ruta/archivo_backup.ldif

Si deseamos recuperar también el fichero de configuración de LDAP:

slapadd -v -c -l ruta/archivo_backup.ldif -f /etc/ldap/slapd.conf

4) Reconstruimos los índices de la base de datos de LDAP:

slapindex -v

5) Otorgamos los ficheros de base de datos al usuario LDAP:

chown -Rf openldap.openldap /var/lib/ldap/*

6) Arrancamos el servicio de LDAP:

/etc/init.d/slapd start

Librería de encriptación en Python

En esta entrada quisiera compartir con vosotros una librería en Python que he desarrollado para encriptar y desencriptar vuestros datos, pudiéndola adaptar a vuestras necesidades. Esta librería la podéis descargar desde el siguiente enlace: https://drive.google.com/file/d/0B1-JQdWrVRabY1FDTEdvcG5CSWM/view?usp=sharing

Al final del código tenéis comentados diferentes bloques de código para poder probar la librería.

A continuación os explico, en términos generales, para qué sirve cada parte del código.

CODEBASE (Código base)

El código base contiene un juego de 140 caracteres (sin repetir). Este juego de caracteres debe ser el mismo utilizado en los textos que se desean encriptar. El juego que he preparado contiene la inmensa mayoría de caracteres utilizados en el idioma español.

MATRIX (Matriz de códigos)

La matriz es un array de códigos, mediante el cual se realiza la trasposición de caracteres para la encriptación y desencriptación de las datos.

Esta librería ya viene con una matriz predeterminada, pero se puede generar una nueva matriz mediante la función create_random_matrix().

La matriz contiene tantos elementos o filas como número de caracteres tiene el código base. Cada uno de estos elementos o filas es una cadena de texto con los mismos caracteres que el código base, pero dispuestos de forma aleatoria. Para obtener una de estas filas, create_random_matrix() utiliza internamente la función get_random_line().

ENCRIPTAR

Para encriptar un dato, se utiliza la función encrypt(), a la cual se le pasan dos parámetros de tipo string: la cadena de texto a encriptar, y la clave utilizada para encriptar.

Internamente, el proceso de encriptar posee dos pasos que realiza automáticamente la función encrypt(): encriptar (filtro 1) y codificar (filtro 2).

El proceso de encriptar lo lleva a cabo la función code(), la cual realiza la trasposición de caracteres de la cadena de texto a través de la clave, y utilizando la matriz de códigos. El resultado es un galimatías que utiliza los caracteres del código base.

El proceso de codificar lo lleva a cabo la función code_hex(), la cual transforma la cadena encriptada en una secuencia hexadecimal.

El resultado final de la encriptación es una cadena en hexadecimal que contiene, exactamente, el doble de caracteres que la cadena original.

DESENCRIPTAR

Para desencriptar el dato encriptado, se utiliza la función decrypt(), a la cual se le pasan dos parámetros de tipo string: la cadena de texto encriptada, y la clave utilizada para encriptar.

El proceso de desencriptar posee dos pasos que realiza automáticamente la función decrypt: decodificar (filtro 1) y desencriptar (filtro 2).

El paso de decodificar lo lleva a cabo la función decode_hex(), la cual transforma la cadena en hexadecimal en una cadena de texto encriptada, la cual es un galimatías que utiliza los caracteres del código base.

El paso de desencriptar lo lleva a cabo la función decode(), la cual transforma la cadena de texto encriptada en el texto original. Esto lo realiza mediante la clave y la matriz de códigos, realizando el proceso de trasposición inverso al que se utilizó para la encriptación.

El resultado final de la desencriptación será la cadena de texto original, la cual contiene, exactamente, la mitad de caracteres que la cadena encriptada.

Librería de encriptación en PHP

En esta entrada quisiera compartir con vosotros una librería en PHP que he desarrollado para encriptar y desencriptar vuestros datos, pudiéndola adaptar a vuestras necesidades. Esta librería la podéis descargar desde el siguiente enlace: https://drive.google.com/file/d/0B1-JQdWrVRabNVpsTHNpb3JCaXM/view?usp=sharing

Al final del código tenéis comentados diferentes bloques de código para poder probar la librería.

A continuación os explico, en términos generales, para qué sirve cada parte del código.

CODEBASE (Código base)

El código base contiene un juego de 140 caracteres (sin repetir). Este juego de caracteres debe ser el mismo utilizado en los textos que se desean encriptar. El juego que he preparado contiene la inmensa mayoría de caracteres utilizados en el idioma español.

MATRIX (Matriz de códigos)

La matriz es un array de códigos, mediante el cual se realiza la trasposición de caracteres para la encriptación y desencriptación de las datos.

Esta librería ya viene con una matriz predeterminada, pero se puede generar una nueva matriz mediante la función create_random_matrix().

La matriz contiene tantos elementos o filas como número de caracteres tiene el código base. Cada uno de estos elementos o filas es una cadena de texto con los mismos caracteres que el código base, pero dispuestos de forma aleatoria. Para obtener una de estas filas, create_random_matrix() utiliza internamente la función get_random_line().

ENCRIPTAR

Para encriptar un dato, se utiliza la función encrypt(), a la cual se le pasan dos parámetros de tipo string: la cadena de texto a encriptar, y la clave utilizada para encriptar.

Internamente, el proceso de encriptar posee dos pasos que realiza automáticamente la función encrypt(): encriptar (filtro 1) y codificar (filtro 2).

El proceso de encriptar lo lleva a cabo la función code(), la cual realiza la trasposición de caracteres de la cadena de texto a través de la clave, y utilizando la matriz de códigos. El resultado es un galimatías que utiliza los caracteres del código base.

El proceso de codificar lo lleva a cabo la función code_hex(), la cual transforma la cadena encriptada en una secuencia hexadecimal.

El resultado final de la encriptación es una cadena en hexadecimal que contiene, exactamente, el doble de caracteres que la cadena original.

DESENCRIPTAR

Para desencriptar el dato encriptado, se utiliza la función decrypt(), a la cual se le pasan dos parámetros de tipo string: la cadena de texto encriptada, y la clave utilizada para encriptar.

El proceso de desencriptar posee dos pasos que realiza automáticamente la función decrypt: decodificar (filtro 1) y desencriptar (filtro 2).

El paso de decodificar lo lleva a cabo la función decode_hex(), la cual transforma la cadena en hexadecimal en una cadena de texto encriptada, la cual es un galimatías que utiliza los caracteres del código base.

El paso de desencriptar lo lleva a cabo la función decode(), la cual transforma la cadena de texto encriptada en el texto original. Esto lo realiza mediante la clave y la matriz de códigos, realizando el proceso de trasposición inverso al que se utilizó para la encriptación.

El resultado final de la desencriptación será la cadena de texto original, la cual contiene, exactamente, la mitad de caracteres que la cadena encriptada.

martes, 20 de enero de 2015

Sentencia SELECT y procedimientos almacenados en MySQL

Los procedimientos almacenados son un recurso muy útil y socorrido, pues permiten realizar complejas operaciones sobre las bases de datos sin necesidad de que intervenga el código de las aplicaciones. Por otra parte, permiten realizar ETLs simples dentro de la base de datos, es decir, recopilar información de diferentes consultas y generar un resultado resumido, producto de filtrados y operaciones matemáticas y de información.

A veces, necesitamos obtener el resultado de un procedimiento almacenado en una consulta SELECT. Un ejemplo de ello puede ser en herramientas como Pentaho, donde el diseñador de informes utiliza una consulta para genera el informe.

La forma más sencilla es cuando el resultado es un único valor (un campo y un registro). Para ello, en lugar de un procedimiento almacenado se define una función, que retorne un único valor. En tal caso, para hacer la SELECT, simplemente definimos un campo como resultado de la llamada a dicha función:

SELECT nombre_funcion([parametros]);

Sin embargo, si deseamos obtener más valores, ya sea en un único registro o en varios, obtendremos un error por parte de MySQL, ya que esta sintaxis de SELECT se refiere a un único valor.

Una posibilidad es utilizar un procedimiento almacenado, y obtener los diferentes valores a través de parámetros de tipo OUT. Esto funciona bien, pero el problema radica en que aplicaciones como Pentaho, requieren obtener los datos en una única y simple consulta SELECT. En este caso, necesitamos dos pasos: la llamada al procedimiento (para obtenerlos valores en los parámetros OUT) y la SELECT que obtiene dichos valores:

CALL nombre_procedimiento(@param1, @param2...);
SELECT @param1, param2...;

No se puede obtener de otra manera. Si utilizamos una expresión como la siguiente retornará un error:

SELECT @param1, param2... FROM (CALL nombre_procedimiento(@param1, param2...));

¿Cómo solucionar este problema?

Voy a plantear una propuesta que a mi me ha servido y funciona bien. Se trata de utilizar una función que retorna un valor (físico) que contenga todos los valores (lógicos). Es decir, retornamos una cadena de texto que contiene todos los valores separados por un token. Posteriormente, cuando se recupere con el SELECT, se procederá a extraer todos los valores contenidos, como si fueran diferentes campos de una consulta.

En mi caso, necesitaba extraer diferentes valores que eran el resultado de diferentes operaciones matemáticas, y que resumían, de forma ejecutiva, una serie de ventas clasificadas por diferentes criterios. Todos los datos eran numéricos, y el tamaño máximo era de 10 cifras (sin decimales). Por tanto, monté una cadena de texto en la que concatené diferentes cadenas de 10 caracteres, que eran los números alineados a la derecha y rellenos con espacios por la izquierda. Entre valor y valor añadí un carácter a modo de token (un pipe o un punto y coma, por ejemplo). Por tanto, el valor devuelto por la función MySQL sería algo como esto:

     34550|    340575

A la hora de hacer el SELECT, podemos extraer cada uno de los valores como campos independientes, con el tipo de dato correspondiente (en este caso, numérico entero sin signo):

SELECT
CAST(SUBSTRING(funcion() FROM 1 FOR 10) AS SIGNED) AS campo1,
CAST(SUBSTRING(funcion() FROM 12 FOR 10) AS SIGNED) AS campo2;