summaryrefslogtreecommitdiffstats
path: root/admin/WebConsole/includes/tftputils.php
blob: 5cf2da88db732a1b852afcabc40c52592913a7a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<?php
/**
 * @file      tftptools.php
 * @brief     Utilidades para menejar ficheros de arranque TFTP/PXE.
 * @version   1.0.5
 * @copyright GNU Public License v3+
 */


// Ficheros de inclusión.
include_once("../includes/ctrlacc.php");
include_once("../clases/AdoPhp.php");

// Directorio de ficheros PXE.
define("PXEDIR", "/opt/opengnsys/tftpboot/menu.lst");


/**
 * @brief    Sustituye espacio por "_" y quita acentos y tildes.
 * @param    cadena   Cadena a modificar.
 * @return   string   Cadena modificada.
 * @versión  1.0.5 - Primera versión, adaptada de NetBoot Avanzado.
 * @author   
 * @date     
*/
function cleanString ($cadena) {
	return strtr(trim($cadena), " áéíóúñçÁÉÍÓÚÑÇ", "_aeiouncAEIOUNC");
}


/**
 * Función que obtiene la versión del Kernel del cliente que se ejecuta durante el
 * proceso de arranque mediante TFTP/PXE.
 * @brief    Obtiene la versión del Kernel usada en arranque TFTP/PXE.
 * @return   float    Versión del Kernel (Versión.Revisión, con 2 decimales).
 * @versión  1.0.5 - Versión inicial.
 * @authors  Ramón Gómez - ETSII Universidad de Sevilla
 * @date     2013-04-11
 */
function clientKernelVersion () {
	$tftpDir = "/opt/opengnsys/tftpboot";		// Directorio TFTP.
	$kernelFile = "$tftpDir/ogclient/ogvmlinuz";	// Fichero del Kernel

	// Devolver versión del Kernel (Versión.Revisión, con 2 decimales).
	return exec ("file -bkr $kernelFile 2>/dev/null | awk '/Linux/ {for(i=1;i<=NF;i++) if(\$i~/version/) {v=\$(i+1); printf(\"%d\",v); sub(/[0-9]*\./,\"\",v); printf(\".%02d\",v)}}'");
}


/**
 *           createBootMode ($cmd, $bootopt, $hostid, $lang) 
 * @brief    Crea un fichero PXE para el ordenador basado en la plantilla indicada y usando
 *           los datos almacenados en la BD.
 * @param    {Object}  cmd       Objeto de conexión a la base de datos.
 * @param    {String}  bootopt   Plantilla de arranque PXE.
 * @param    {Number}  hostid    Id. del ordenador.
 * @param    {String}  lang      Idioma de arranque.
 * @version  1.0.5 - Primera versión, adaptada de NetBoot Avanzado (Antonio J. Doblas Viso - Universidad de Málaga)
 * @author  Ramón Gómez - ETSII Universidad de Sevilla
 * @date     2013-04-25
 * @version  1.1.0 - Se incluye la unidad organizativa como parametro del kernel: ogunit=directorio_unidad (ticket #678).
 * @author   Irina Gómez - ETSII Universidad de Sevilla
 * @date     2015-12-16
 * @version  1.1.0 - La segunda fase de carga del ogLive se define en el SERVER para evitar erores de sincronismo entre versiones (ticket #787).
 * @author   Antonio J. Doblas Viso - Universidad de Malaga
 * @date     2017-06-01
  * @version  1.1.0 - Se incluye el nombre del perfil hardware y se elimina el winboot (ticket #828).
 * @author   Antonio J. Doblas Viso - Universidad de Malaga
 * @date     2018-01-21 
 */
function createBootMode ($cmd, $bootopt, $hostid, $lang) {	

	// Plantilla con las opciones por defecto.
	if (empty ($bootopt))  $bootopt = "00unknown";

	// Actualizar opción de arranque para el equipo.
	$cmd->CreaParametro("@arranque",$bootopt,0);
	$cmd->CreaParametro("@idordenador",$hostid,1);
	$cmd->texto="UPDATE ordenadores SET arranque=@arranque WHERE idordenador=@idordenador";
	$cmd->Ejecutar();

	// Obtener información de la base de datos.
	$cmd->texto="SELECT ordenadores.nombreordenador AS hostname, ordenadores.ip AS ip,
			    ordenadores.mac AS mac, ordenadores.netiface AS netiface,
			    ordenadores.oglivedir AS oglivedir,
			    aulas.netmask AS netmask, aulas.router AS router,
			    aulas.ntp AS ntp, aulas.dns AS dns, aulas.proxy AS proxy,
			    aulas.nombreaula AS grupo, IFNULL(repositorios.ip, '') AS iprepo,
			    (SELECT ipserveradm FROM entornos LIMIT 1) AS ipserveradm,
			    menus.resolucion AS vga, perfileshard.descripcion AS hardprofile,
			    centros.directorio, entidades.ogunit
			FROM ordenadores 
			JOIN aulas USING (idaula)
			JOIN centros USING (idcentro)
			JOIN entidades USING (identidad)
			LEFT JOIN repositorios USING (idrepositorio)
			LEFT JOIN menus USING (idmenu)
			LEFT JOIN perfileshard USING (idperfilhard)
			WHERE ordenadores.idordenador='$hostid'";

	$rs=new Recordset; 
	$rs->Comando=&$cmd; 
	if (!$rs->Abrir())  return;
	$rs->Primero(); 
	$hostname=$rs->campos["hostname"];
	$ip=$rs->campos["ip"];
	$mac=$rs->campos["mac"];
	$netiface=$rs->campos["netiface"];
	$netmask=$rs->campos["netmask"];
	$router=$rs->campos["router"];
	$ntp=$rs->campos["ntp"];
	$dns=$rs->campos["dns"];
	$proxy=$rs->campos["proxy"];
	$group=cleanString($rs->campos["grupo"]);
	$repo=$rs->campos["iprepo"];
	$server=$rs->campos["ipserveradm"];
	$vga=$rs->campos["vga"];
	$hardprofile=cleanString($rs->campos["hardprofile"]);
	$oglivedir=$rs->campos["oglivedir"];
	$ogunit=$rs->campos["ogunit"];
	if ($ogunit == 0 or $rs->campos["directorio"] == null) {
		$directorio="" ;
	} else {
		$directorio=$rs->campos["directorio"];
	}

	$rs->Cerrar();

	// Componer código de idioma para el parámetro de arranque.
	switch ($lang) {
		case "eng":
			$lang="en_GB";
			break;
		case "esp":
			$lang="es_ES";
			break;
		case "cat":
			$lang="ca_ES";
			break;
	}

	// Componer parámetros del kernel.
	$infohost=" LANG=$lang".
		  " ip=$ip:$server:$router:$netmask:$hostname:$netiface:none" .
		  " group=$group" .
		  " ogrepo=$repo" .
		  " oglive=$server" .
		  " oglog=$server" .
		  " ogshare=$server";
	// Añadir parámetros opcionales.
	if (! empty ($ntp))	{ $infohost.=" ogntp=$ntp"; }
	if (! empty ($dns))	{ $infohost.=" ogdns=$dns"; }
	if (! empty ($proxy))	{ $infohost.=" ogproxy=$proxy"; }
	if (! empty ($hardprofile))	{ $infohost.=" hardprofile=$hardprofile"; }
	// Comprobar si se usa el parámetro "vga" (número de 3 cifras) o "video" (cadena).
	if (! empty ($vga)) {
		// UHU - Se sustituye la función is_int por is_numeric, ya que al ser un string no funciona bien con is_int
		if (is_numeric($vga) && strlen($vga) == 3) {
			$infohost.=" vga=$vga";
		} else {
			$infohost.=" video=$vga";
		}
	}
	if (! empty ($directorio)) { $infohost.=" ogunit=$directorio"; }
	
	$mac = substr($mac,0,2) . ":" . substr($mac,2,2) . ":" . substr($mac,4,2) . ":" . substr($mac,6,2) . ":" . substr($mac,8,2) . ":" . substr($mac,10,2);
	$macfile = PXEDIR . "/01-" . str_replace(":", "-", strtoupper($mac));	

	// Crear fichero de arranque a partir de la plantilla y los datos del cliente.
	// UHU - si el parametro vga no existe, no se quita.
	if (! empty ($vga)) {
		exec("sed -e 's|vga=...||g; s|INFOHOST|$infohost|g; s|set ISODIR=.*|set ISODIR=$oglivedir|g' " . PXEDIR . "/templates/$bootopt > $macfile");
	}
	else{
		exec("sed -e 's|INFOHOST|$infohost|g; s|set ISODIR=.*|set ISODIR=$oglivedir|g; s|set ISODIR=.*|set ISODIR=$oglivedir|g' " . PXEDIR . "/templates/$bootopt > $macfile");
	}
	chmod($macfile, 0777);
}


/**
 *           deleteBootFile ($mac)
 * @brief    Borra el fichero PXE del ordenador con la dirección MAC correspondiente.
 * @param    {String}  mac     Dirección MAC del ordenador (sin caracteres ":").
 * @versión  1.0.5 - Primera versión, adaptada de NetBoot Avanzado.
 * @authors  Ramón Gómez - ETSII Universidad de Sevilla
 * @date     2013-04-25
 */
function deleteBootFile ($mac) {	

	// Obtener nombre de fichero a partir de dirección MAC.
	$mac = strtoupper($mac);
	$macfile = PXEDIR . "/01-" . substr($mac, 0, 2) . "-" . substr($mac, 2, 2) . "-" . substr($mac, 4, 2) . "-" . substr($mac, 6, 2) . "-" . substr($mac, 8, 2) . "-" . substr($mac, 10, 2);
	// Eliminar el fichero.
	@unlink($macfile);
}

/**
 *           updateBootMode ($cmd, $idfield, $idvalue, $lang)
 * @brief    Ejecuta la función para componer fichero PXE para todos los clientes que cumplan
 *           con un determinado criterio de búsqueda basado en clave ejena.
 * @param    {Object}  cmd       Objeto de conexión con la base de datos.
 * @param    {String}  idfield   Campo identificador de la clave ajena para buscar ordenadores.
 * @param    {Number}  idvalue   Valor a buscar en el ídentificador de la clave ajena.
 * @param    {String}  lang      Idioma de arranque.
 * @versión  1.0.5 - Primera versión, adaptada de NetBoot Avanzado.
 * @authors  Ramón Gómez - ETSII Universidad de Sevilla
 * @date     2013-04-25
 */
function updateBootMode ($cmd, $idfield, $idvalue, $lang) {

	// Salir si los es nulo el campo de identificador y su valor de índice.
	if (empty ($idfield) or empty ($idvalue))
		return;
	// Control para evitar ataques XSS.
	$idfield = mysqli_real_escape_string ($cmd->Conexion->controlador, $idfield);
	$idvalue = mysqli_real_escape_string ($cmd->Conexion->controlador, $idvalue);

	// Obtener los ordenadores asociados al aula y sus plantillas de arranque.
	$cmd->texto = "SELECT idordenador AS hostid, arranque AS bootopt
			 FROM ordenadores
			WHERE $idfield=$idvalue";
	$rs = new Recordset;
	$rs->Comando=&$cmd;
	if ($rs->Abrir()) {
		$rs->Primero();
		while (! $rs->EOF) {
			$hostid=$rs->campos["hostid"];
			if (! empty ($hostid)) {
				$bootopt=$rs->campos["bootopt"];
				// Volver a crear el fichero de arranque.
				createBootMode ($cmd, $bootopt, $hostid, $lang);
			}
			$rs->Siguiente();
		}
		$rs->Cerrar();
	}
}

/**
 *           updateBootRepo ($cmd, $repoid)
 * @brief    Actualiza la IP del repositorio en los ficheros PXE de todos sus equipos asociados.
 * @param    {Object}  cmd      Objeto de conexión con la base de datos
 * @param    {Integer} repoid   Campo identificador del repositorio
 * @return   {Integer}          0, sin errores; -1, error acceso a BD; >0, ficheros no modificados
 * @versión  1.1.0 - Primera versión.
 * @authors  Ramón Gómez - ETSII Universidad de Sevilla
 * @date     2018-01-19
 */
function updateBootRepo ($cmd, $repoid) {
	$errors = 0;
	// Obtener todas las MAC de los ordenadores incluidos en el repositorio.
	$cmd->texto = "SELECT UPPER(ordenadores.mac) AS mac, repositorios.ip AS iprepo
			 FROM ordenadores
			 JOIN repositorios USING (idrepositorio)
			WHERE ordenadores.idrepositorio = '$repoid'";
	$rs = new Recordset;
	$rs->Comando=&$cmd;
	if ($rs->Abrir()) {
		$rs->Primero();
		while (! $rs->EOF) {
			$mac = $rs->campos["mac"];
			$repo = $rs->campos["iprepo"];
			// Obtener nombre de fichero PXE a partir de la MAC del ordenador cliente.
			$macfile = PXEDIR . "/01-" . substr($mac, 0, 2) . "-" . substr($mac, 2, 2) . "-" . substr($mac, 4, 2) . "-" . substr($mac, 6, 2) . "-" . substr($mac, 8, 2) . "-" . substr($mac, 10, 2);
			// Actualizar parámetro "ogrepo" en el fichero PXE.
			if ($pxecode = @file_get_contents($macfile)) {
				$pxecode = preg_replace("/ogrepo=[^ ]*/", "ogrepo=$repo", $pxecode);
				if (! @file_put_contents($macfile, $pxecode)) {
					$erros++;
				}
			}
			$rs->Siguiente();
		}
		$rs->Cerrar();
	} else {
		$errors = -1;
	}
	return($errors);
}