| 1 | <?php |
|---|
| 2 | /* |
|---|
| 3 | $Id: m_dom.php,v 1.27 2006/02/17 18:34:30 olivier Exp $ |
|---|
| 4 | ---------------------------------------------------------------------- |
|---|
| 5 | LICENSE |
|---|
| 6 | |
|---|
| 7 | This program is free software; you can redistribute it and/or |
|---|
| 8 | modify it under the terms of the GNU General Public License (GPL) |
|---|
| 9 | as published by the Free Software Foundation; either version 2 |
|---|
| 10 | of the License, or (at your option) any later version. |
|---|
| 11 | |
|---|
| 12 | This program is distributed in the hope that it will be useful, |
|---|
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | GNU General Public License for more details. |
|---|
| 16 | |
|---|
| 17 | To read the license please visit http://www.gnu.org/copyleft/gpl.html |
|---|
| 18 | ---------------------------------------------------------------------- |
|---|
| 19 | Original Author of file: Benjamin Sonntag |
|---|
| 20 | Purpose of file: PHP Class that manage domain names installed on the server |
|---|
| 21 | ---------------------------------------------------------------------- |
|---|
| 22 | */ |
|---|
| 23 | |
|---|
| 24 | define('SLAVE_FLAG', "/var/run/alternc/refresh_slave"); |
|---|
| 25 | |
|---|
| 26 | /** |
|---|
| 27 | * Classe de gestion des domaines de l'hébergé. |
|---|
| 28 | * |
|---|
| 29 | * Cette classe permet de gérer les domaines / sous-domaines, redirections |
|---|
| 30 | * dns et mx des domaines d'un membre hébergé.<br /> |
|---|
| 31 | * Copyleft {@link http://alternc.net/ AlternC Team} |
|---|
| 32 | * |
|---|
| 33 | * @copyright AlternC-Team 2002-11-01 http://alternc.net/ |
|---|
| 34 | * |
|---|
| 35 | */ |
|---|
| 36 | class m_dom { |
|---|
| 37 | |
|---|
| 38 | /** $domains : Cache des domaines du membre |
|---|
| 39 | * @access private |
|---|
| 40 | */ |
|---|
| 41 | var $domains; |
|---|
| 42 | |
|---|
| 43 | /** $dns : Liste des dns trouvés par la fonction whois |
|---|
| 44 | * @access private |
|---|
| 45 | */ |
|---|
| 46 | var $dns; |
|---|
| 47 | |
|---|
| 48 | /** Flag : a-t-on trouvé un sous-domaine Webmail pour ce domaine ? |
|---|
| 49 | * @access private |
|---|
| 50 | */ |
|---|
| 51 | var $webmail; |
|---|
| 52 | |
|---|
| 53 | /** |
|---|
| 54 | * Système de verrouillage du cron |
|---|
| 55 | * Ce fichier permet de verrouiller le cron en attendant la validation |
|---|
| 56 | * du domaine par update_domains.sh |
|---|
| 57 | * @access private |
|---|
| 58 | */ |
|---|
| 59 | var $fic_lock_cron="/var/run/alternc/cron.lock"; |
|---|
| 60 | |
|---|
| 61 | /** |
|---|
| 62 | * Le cron a-t-il été bloqué ? |
|---|
| 63 | * Il faut appeler les fonctions privées lock et unlock entre les |
|---|
| 64 | * appels aux domaines. |
|---|
| 65 | * @access private |
|---|
| 66 | */ |
|---|
| 67 | var $islocked=false; |
|---|
| 68 | |
|---|
| 69 | var $type_local = "VHOST"; |
|---|
| 70 | var $type_url = "URL"; |
|---|
| 71 | var $type_ip = "IP"; |
|---|
| 72 | var $type_webmail = "WEBMAIL"; |
|---|
| 73 | var $type_ipv6 = "IPV6"; |
|---|
| 74 | var $type_cname = "CNAME"; |
|---|
| 75 | var $type_txt = "TXT"; |
|---|
| 76 | var $type_defmx = "DEFMX"; |
|---|
| 77 | var $type_defmx2 = "DEFMX2"; |
|---|
| 78 | |
|---|
| 79 | var $action_insert = "0"; |
|---|
| 80 | var $action_update= "1"; |
|---|
| 81 | var $action_delete = "2"; |
|---|
| 82 | |
|---|
| 83 | /* ----------------------------------------------------------------- */ |
|---|
| 84 | /** |
|---|
| 85 | * Constructeur |
|---|
| 86 | */ |
|---|
| 87 | function m_dom() { |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | /* ----------------------------------------------------------------- */ |
|---|
| 91 | /** |
|---|
| 92 | * Quota name |
|---|
| 93 | */ |
|---|
| 94 | function alternc_quota_names() { |
|---|
| 95 | return "dom"; |
|---|
| 96 | } |
|---|
| 97 | /* ----------------------------------------------------------------- */ |
|---|
| 98 | /** |
|---|
| 99 | * Retourne un tableau contenant les types de domaines |
|---|
| 100 | * |
|---|
| 101 | * @return array retourne un tableau indexé contenant la liste types de domaines |
|---|
| 102 | * authorisé. Retourne FALSE si une erreur s'est produite. |
|---|
| 103 | */ |
|---|
| 104 | function domains_type_lst() { |
|---|
| 105 | global $db,$err,$cuid; |
|---|
| 106 | $err->log("dom","domains_type_lst"); |
|---|
| 107 | $db->query("select * from domaines_type order by advanced;"); |
|---|
| 108 | $this->domains_type_lst=false; |
|---|
| 109 | while ($db->next_record()) { |
|---|
| 110 | $this->domains_type_lst[strtolower($db->Record["name"])] = $db->Record; |
|---|
| 111 | } |
|---|
| 112 | return $this->domains_type_lst; |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | function domains_type_enable_values() { |
|---|
| 116 | global $db,$err,$cuid; |
|---|
| 117 | $err->log("dom","domains_type_target_values"); |
|---|
| 118 | $db->query("desc domaines_type;"); |
|---|
| 119 | $r = array(); |
|---|
| 120 | while ($db->next_record()) { |
|---|
| 121 | if ($db->f('Field') == 'enable') { |
|---|
| 122 | $tab = explode(",", substr($db->f('Type'), 5, -1)); |
|---|
| 123 | foreach($tab as $t) { $r[]=substr($t,1,-1); } |
|---|
| 124 | } |
|---|
| 125 | } |
|---|
| 126 | return $r; |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | function domains_type_target_values($type=null) { |
|---|
| 130 | global $db,$err,$cuid; |
|---|
| 131 | $err->log("dom","domains_type_target_values"); |
|---|
| 132 | if (is_null($type)) { |
|---|
| 133 | $db->query("desc domaines_type;"); |
|---|
| 134 | $r = array(); |
|---|
| 135 | while ($db->next_record()) { |
|---|
| 136 | if ($db->f('Field') == 'target') { |
|---|
| 137 | $tab = explode(",", substr($db->f('Type'), 5, -1)); |
|---|
| 138 | foreach($tab as $t) { $r[]=substr($t,1,-1); } |
|---|
| 139 | } |
|---|
| 140 | } |
|---|
| 141 | return $r; |
|---|
| 142 | } else { |
|---|
| 143 | $db->query("select target from domaines_type where name='$type';"); |
|---|
| 144 | if (! $db->next_record()) return false; |
|---|
| 145 | return $db->f('target'); |
|---|
| 146 | } |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | function domains_type_regenerate($name) { |
|---|
| 150 | global $db,$err,$cuid; |
|---|
| 151 | $name=mysql_real_escape_string($name); |
|---|
| 152 | $db->query("update sub_domaines set web_action='UPDATE' where lower(type) = lower('$name') ;"); |
|---|
| 153 | $db->query("update domaines d, sub_domaines sd set d.dns_action = 'UPDATE' where lower(sd.type)=lower('$name');"); |
|---|
| 154 | return true; |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | function domains_type_get($name) { |
|---|
| 158 | global $db,$err,$cuid; |
|---|
| 159 | $name=mysql_real_escape_string($name); |
|---|
| 160 | $db->query("select * from domaines_type where name='$name' ;"); |
|---|
| 161 | $db->next_record(); |
|---|
| 162 | return $db->Record; |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | function domains_type_del($name) { |
|---|
| 166 | global $db,$err,$cuid; |
|---|
| 167 | $name=mysql_real_escape_string($name); |
|---|
| 168 | $db->query("delete domaines_type where name='$name';"); |
|---|
| 169 | return true; |
|---|
| 170 | } |
|---|
| 171 | |
|---|
| 172 | function domains_type_disable($id) { |
|---|
| 173 | global $db,$err,$cuid; |
|---|
| 174 | $id=intval($id); |
|---|
| 175 | $db->query("update domaines_type set enable=false where id=$id;"); |
|---|
| 176 | return true; |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | function domains_type_enable($id) { |
|---|
| 180 | global $db,$err,$cuid; |
|---|
| 181 | $id=intval($id); |
|---|
| 182 | $db->query("update domaines_type set enable=true where id=$id;"); |
|---|
| 183 | return true; |
|---|
| 184 | } |
|---|
| 185 | |
|---|
| 186 | function domains_type_update($name, $description, $target, $entry, $compatibility, $enable, $only_dns, $need_dns,$advanced) { |
|---|
| 187 | global $err,$cuid,$db; |
|---|
| 188 | $id=intval($id); |
|---|
| 189 | $name=mysql_real_escape_string($name); |
|---|
| 190 | $description=mysql_real_escape_string($description); |
|---|
| 191 | $target=mysql_real_escape_string($target); |
|---|
| 192 | $entry=mysql_real_escape_string($entry); |
|---|
| 193 | $compatibility=mysql_real_escape_string($compatibility); |
|---|
| 194 | $enable=mysql_real_escape_string($enable); |
|---|
| 195 | $only_dns=intval($only_dns); |
|---|
| 196 | $need_dns=intval($need_dns); |
|---|
| 197 | $advanced=intval($advanced); |
|---|
| 198 | $db->query("UPDATE domaines_type SET description='$description', target='$target', entry='$entry', compatibility='$compatibility', enable='$enable', need_dns=$need_dns, only_dns=$only_dns, advanced='$advanced' where name='$name';"); |
|---|
| 199 | return true; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | function sub_domain_change_status($domain,$sub,$type,$value,$status) { |
|---|
| 203 | global $db,$err,$cuid; |
|---|
| 204 | $err->log("dom","sub_domain_change_status"); |
|---|
| 205 | $status=strtoupper($status); |
|---|
| 206 | if (! in_array($status,array('ENABLE', 'DISABLE'))) return false; |
|---|
| 207 | |
|---|
| 208 | $db->query("update sub_domaines set enable='$status' where domaine='$domain' and sub='$sub' and lower(type)=lower('$type') and valeur='$value'"); |
|---|
| 209 | |
|---|
| 210 | return true; |
|---|
| 211 | } |
|---|
| 212 | |
|---|
| 213 | /* ----------------------------------------------------------------- */ |
|---|
| 214 | /** |
|---|
| 215 | * Retourne un tableau contenant les domaines d'un membre. |
|---|
| 216 | * |
|---|
| 217 | * @return array retourne un tableau indexé contenant la liste des |
|---|
| 218 | * domaines hébergés sur le compte courant. Retourne FALSE si une |
|---|
| 219 | * erreur s'est produite. |
|---|
| 220 | */ |
|---|
| 221 | function enum_domains() { |
|---|
| 222 | global $db,$err,$cuid; |
|---|
| 223 | $err->log("dom","enum_domains"); |
|---|
| 224 | $db->query("select * from domaines where compte='$cuid' order by domaine asc;"); |
|---|
| 225 | $this->domains=array(); |
|---|
| 226 | if ($db->num_rows()>0) { |
|---|
| 227 | while ($db->next_record()) { |
|---|
| 228 | $this->domains[]=$db->f("domaine"); |
|---|
| 229 | } |
|---|
| 230 | } |
|---|
| 231 | return $this->domains; |
|---|
| 232 | } |
|---|
| 233 | |
|---|
| 234 | function del_domain_cancel($dom) { |
|---|
| 235 | global $db,$err,$classes,$cuid; |
|---|
| 236 | $err->log("dom","del_domaini_canl",$dom); |
|---|
| 237 | $dom=strtolower($dom); |
|---|
| 238 | $db->query("UPDATE sub_domaines SET web_action='UPDATE' WHERE domaine='$dom';"); |
|---|
| 239 | $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine='$dom';"); |
|---|
| 240 | |
|---|
| 241 | # TODO : some work with domain sensitive classes |
|---|
| 242 | |
|---|
| 243 | return true; |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | /* ----------------------------------------------------------------- */ |
|---|
| 247 | /** |
|---|
| 248 | * Efface un domaine du membre courant, et tous ses sous-domaines |
|---|
| 249 | * |
|---|
| 250 | * Cette fonction efface un domaine et tous ses sous-domaines, ainsi que |
|---|
| 251 | * les autres services attachés à celui-ci. Elle appelle donc les autres |
|---|
| 252 | * classe. Chaque classe peut déclarer une fonction del_dom qui sera |
|---|
| 253 | * appellée lors de la destruction d'un domaine. |
|---|
| 254 | * |
|---|
| 255 | * @param string $dom nom de domaine à effacer |
|---|
| 256 | * @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon. |
|---|
| 257 | */ |
|---|
| 258 | function del_domain($dom) { |
|---|
| 259 | global $db,$err,$classes,$cuid; |
|---|
| 260 | $err->log("dom","del_domain",$dom); |
|---|
| 261 | $dom=strtolower($dom); |
|---|
| 262 | $db->query("SELECT * FROM domaines WHERE domaine='$dom';"); |
|---|
| 263 | if ($db->num_rows()==0) { |
|---|
| 264 | $err->raise("dom",1,$dom); |
|---|
| 265 | return false; |
|---|
| 266 | } |
|---|
| 267 | $db->next_record(); |
|---|
| 268 | if ($db->f("compte")!=$cuid) { |
|---|
| 269 | $err->raise("dom",2,$dom); |
|---|
| 270 | return false; |
|---|
| 271 | } |
|---|
| 272 | $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine='$dom';"); |
|---|
| 273 | $db->query("UPDATE domaines SET dns_action='DELETE' WHERE domaine='$dom';"); |
|---|
| 274 | |
|---|
| 275 | // DEPENDANCE : |
|---|
| 276 | // Lancement de del_dom sur les classes domain_sensitive : |
|---|
| 277 | // Declenchons les autres classes. |
|---|
| 278 | foreach($classes as $c) { |
|---|
| 279 | if (method_exists($GLOBALS[$c],"alternc_del_domain")) { |
|---|
| 280 | $GLOBALS[$c]->alternc_del_domain($dom); |
|---|
| 281 | } |
|---|
| 282 | } |
|---|
| 283 | foreach($classes as $c) { |
|---|
| 284 | if (method_exists($GLOBALS[$c],"alternc_del_mx_domain")) { |
|---|
| 285 | $GLOBALS[$c]->alternc_del_mx_domain($dom); |
|---|
| 286 | } |
|---|
| 287 | } |
|---|
| 288 | return true; |
|---|
| 289 | } |
|---|
| 290 | |
|---|
| 291 | /* ----------------------------------------------------------------- */ |
|---|
| 292 | /** |
|---|
| 293 | * Installe un domaine sur le compte courant. |
|---|
| 294 | * |
|---|
| 295 | * <p>Si le domaine existe déjà ou est interdit, ou est celui du serveur, |
|---|
| 296 | * l'installation est refusée. Si l'hébergement DNS est demandé, la fonction |
|---|
| 297 | * checkhostallow vérifiera que le domaine peut être installé conformément |
|---|
| 298 | * aux demandes des super-admin. |
|---|
| 299 | * Si le dns n'est pas demandé, le domaine peut être installé s'il est en |
|---|
| 300 | * seconde main d'un tld (exemple : test.eu.org ou test.com, mais pas |
|---|
| 301 | * toto.test.org ou test.test.asso.fr)</p> |
|---|
| 302 | * <p>Chaque classe peut définir une fonction add_dom($dom) qui sera |
|---|
| 303 | * appellée lors de l'installation d'un nouveau domaine.</p> |
|---|
| 304 | * |
|---|
| 305 | * @param string $dom nom fqdn du domaine à installer |
|---|
| 306 | * @param integer $dns 1 ou 0 pour héberger le DNS du domaine ou pas. |
|---|
| 307 | * @param integer $noerase 1 ou 0 pour rendre le domaine inamovible ou non |
|---|
| 308 | * @param integer $force 1 ou 0, si 1, n'effectue pas les tests de DNS. |
|---|
| 309 | * force ne devrait être utilisé que par le super-admin. |
|---|
| 310 | $ @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon. |
|---|
| 311 | */ |
|---|
| 312 | function add_domain($domain,$dns,$noerase=0,$force=0,$isslave=0,$slavedom="") { |
|---|
| 313 | global $db,$err,$quota,$classes,$L_MX,$L_FQDN,$tld,$cuid,$bro; |
|---|
| 314 | $err->log("dom","add_domain",$domain); |
|---|
| 315 | |
|---|
| 316 | // Locked ? |
|---|
| 317 | if (!$this->islocked) { |
|---|
| 318 | $err->raise("dom",3); |
|---|
| 319 | return false; |
|---|
| 320 | } |
|---|
| 321 | // Verifie que le domaine est rfc-compliant |
|---|
| 322 | $domain=strtolower($domain); |
|---|
| 323 | $t=checkfqdn($domain); |
|---|
| 324 | if ($t) { |
|---|
| 325 | $err->raise("dom",3+$t); |
|---|
| 326 | return false; |
|---|
| 327 | } |
|---|
| 328 | // Interdit les domaines clés (table forbidden_domains) sauf en cas FORCE |
|---|
| 329 | $db->query("select domain from forbidden_domains where domain='$domain'"); |
|---|
| 330 | if ($db->num_rows() && !$force) { |
|---|
| 331 | $err->raise("dom",22); |
|---|
| 332 | return false; |
|---|
| 333 | } |
|---|
| 334 | if ($domain==$L_FQDN || $domain=="www.$L_FQDN") { |
|---|
| 335 | $err->raise("dom",18); |
|---|
| 336 | return false; |
|---|
| 337 | } |
|---|
| 338 | $db->query("SELECT compte FROM domaines WHERE domaine='$domain';"); |
|---|
| 339 | if ($db->num_rows()) { |
|---|
| 340 | $err->raise("dom",8); |
|---|
| 341 | return false; |
|---|
| 342 | } |
|---|
| 343 | $db->query("SELECT compte FROM `sub_domaines` WHERE sub != \"\" AND concat( sub, \".\", domaine )='$domain' OR domaine='$domain';"); |
|---|
| 344 | if ($db->num_rows()) { |
|---|
| 345 | $err->raise("dom",8); |
|---|
| 346 | return false; |
|---|
| 347 | } |
|---|
| 348 | $this->dns=$this->whois($domain); |
|---|
| 349 | if (!$force) { |
|---|
| 350 | $v=checkhostallow($domain,$this->dns); |
|---|
| 351 | if ($v==-1) { |
|---|
| 352 | $err->raise("dom",7); // TLD interdit |
|---|
| 353 | return false; |
|---|
| 354 | } |
|---|
| 355 | if ($dns && $v==-2) { |
|---|
| 356 | $err->raise("dom",12); // Domaine non trouvé dans le whois |
|---|
| 357 | return false; |
|---|
| 358 | } |
|---|
| 359 | if ($dns && $v==-3) { |
|---|
| 360 | $err->raise("dom",23); // Domaine non trouvé dans le whois |
|---|
| 361 | return false; |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | if ($dns) $dns="1"; else $dns="0"; |
|---|
| 365 | |
|---|
| 366 | // mode 5 : force DNS to NO. |
|---|
| 367 | if ($tld[$v]==5) $dns=0; |
|---|
| 368 | // It must be a real domain (no subdomain) |
|---|
| 369 | if (!$dns) { |
|---|
| 370 | $v=checkhostallow_nodns($domain); |
|---|
| 371 | if ($v) { |
|---|
| 372 | $err->raise("dom",22); |
|---|
| 373 | return false; |
|---|
| 374 | } |
|---|
| 375 | } |
|---|
| 376 | } |
|---|
| 377 | // Check the quota : |
|---|
| 378 | if (!$quota->cancreate("dom")) { |
|---|
| 379 | $err->raise("dom",10); |
|---|
| 380 | return false; |
|---|
| 381 | } |
|---|
| 382 | if ($noerase) $noerase="1"; else $noerase="0"; |
|---|
| 383 | $db->query("insert into domaines (compte,domaine,gesdns,gesmx,noerase,dns_action) values ('$cuid','$domain','$dns','1','$noerase','UPDATE');"); |
|---|
| 384 | |
|---|
| 385 | if ($isslave) { |
|---|
| 386 | $isslave=true; |
|---|
| 387 | $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$slavedom';"); |
|---|
| 388 | $db->next_record(); |
|---|
| 389 | if (!$db->Record["domaine"]) { |
|---|
| 390 | $err->raise("dom",1,$slavedom); |
|---|
| 391 | $isslave=false; |
|---|
| 392 | } |
|---|
| 393 | // Point to the master domain : |
|---|
| 394 | $this->set_sub_domain($domain, '', $this->type_url, 'http://www.'.$slavedom); |
|---|
| 395 | $this->set_sub_domain($domain, 'www', $this->type_url, 'http://www.'.$slavedom); |
|---|
| 396 | $this->set_sub_domain($domain, 'mail', $this->type_url, 'http://mail.'.$slavedom); |
|---|
| 397 | } |
|---|
| 398 | if (!$isslave) { |
|---|
| 399 | // Creation du repertoire dans www |
|---|
| 400 | $dest_root = $bro->get_userid_root($cuid); |
|---|
| 401 | $domshort=str_replace("-","",str_replace(".","",$domain)); |
|---|
| 402 | |
|---|
| 403 | if (! is_dir($dest_root . "/". $domshort)) { |
|---|
| 404 | mkdir($dest_root . "/". $domshort); |
|---|
| 405 | } |
|---|
| 406 | |
|---|
| 407 | // Creation des 3 sous-domaines par défaut : Vide, www et mail |
|---|
| 408 | $this->set_sub_domain($domain, '', $this->type_url, 'http://www.'.$domain); |
|---|
| 409 | $this->set_sub_domain($domain, 'www', $this->type_local, '/'. $domshort); |
|---|
| 410 | $this->set_sub_domain($domain, 'mail', $this->type_webmail, ''); |
|---|
| 411 | } |
|---|
| 412 | |
|---|
| 413 | // DEPENDANCE : |
|---|
| 414 | // Lancement de add_dom sur les classes domain_sensitive : |
|---|
| 415 | // Declenchons les autres classes. |
|---|
| 416 | foreach($classes as $c) { |
|---|
| 417 | if (method_exists($GLOBALS[$c],"alternc_add_domain")) { |
|---|
| 418 | $GLOBALS[$c]->alternc_add_domain($domain); |
|---|
| 419 | } |
|---|
| 420 | } |
|---|
| 421 | foreach($classes as $c) { |
|---|
| 422 | if (method_exists($GLOBALS[$c],"alternc_add_mx_domain")) { |
|---|
| 423 | $GLOBALS[$c]->alternc_add_mx_domain($domain); |
|---|
| 424 | } |
|---|
| 425 | } |
|---|
| 426 | if ($isslave) { |
|---|
| 427 | foreach($classes as $c) { |
|---|
| 428 | if (method_exists($GLOBALS[$c],"alternc_add_slave_domain")) { |
|---|
| 429 | $GLOBALS[$c]->alternc_add_slave_domain($domain,$slavedom); |
|---|
| 430 | } |
|---|
| 431 | } |
|---|
| 432 | } |
|---|
| 433 | return true; |
|---|
| 434 | } |
|---|
| 435 | |
|---|
| 436 | /* ----------------------------------------------------------------- */ |
|---|
| 437 | /** |
|---|
| 438 | * Retourne les entrées DNS du domaine $domain issues du WHOIS. |
|---|
| 439 | * |
|---|
| 440 | * Cette fonction effectue un appel WHOIS($domain) sur Internet, |
|---|
| 441 | * et extrait du whois les serveurs DNS du domaine demandé. En fonction |
|---|
| 442 | * du TLD, on sait (ou pas) faire le whois correspondant. |
|---|
| 443 | * Actuellement, les tld suivants sont supportés : |
|---|
| 444 | * .com .net .org .be .info .ca .cx .fr .biz .name |
|---|
| 445 | * |
|---|
| 446 | * @param string $domain Domaine fqdn dont on souhaite les serveurs DNS |
|---|
| 447 | * @return array Retourne un tableau indexé avec les NOMS fqdn des dns |
|---|
| 448 | * du domaine demandé. Retourne FALSE si une erreur s'est produite. |
|---|
| 449 | * |
|---|
| 450 | */ |
|---|
| 451 | function whois($domain) { |
|---|
| 452 | global $db,$err; |
|---|
| 453 | $err->log("dom","whois",$domain); |
|---|
| 454 | // pour ajouter un nouveau TLD, utiliser le code ci-dessous. |
|---|
| 455 | // echo "whois : $domain<br />"; |
|---|
| 456 | preg_match("#.*\.([^\.]*)#",$domain,$out); |
|---|
| 457 | $ext=$out[1]; |
|---|
| 458 | // pour ajouter un nouveau TLD, utiliser le code ci-dessous. |
|---|
| 459 | // echo "ext: $ext<br />"; |
|---|
| 460 | |
|---|
| 461 | if (($fp=@fsockopen("whois.iana.org", 43))>0) { |
|---|
| 462 | fputs($fp, "$domain\r\n"); |
|---|
| 463 | $found = false; |
|---|
| 464 | $state=0; |
|---|
| 465 | while (!feof($fp)) { |
|---|
| 466 | $ligne = fgets($fp,128); |
|---|
| 467 | if (preg_match('#^whois:#', $ligne)) { $serveur=preg_replace('/whois:\ */','',$ligne,1); } |
|---|
| 468 | } |
|---|
| 469 | } |
|---|
| 470 | $serveur=str_replace(array(" ","\n"),"",$serveur); |
|---|
| 471 | |
|---|
| 472 | $egal=""; |
|---|
| 473 | switch($ext) { |
|---|
| 474 | case "net": |
|---|
| 475 | $egal="="; |
|---|
| 476 | break; |
|---|
| 477 | case "name": |
|---|
| 478 | $egal="domain = "; |
|---|
| 479 | break; |
|---|
| 480 | } |
|---|
| 481 | // pour ajouter un nouveau TLD, utiliser le code ci-dessous. |
|---|
| 482 | // echo "serveur : $serveur <br />"; |
|---|
| 483 | if (($fp=@fsockopen($serveur, 43))>0) { |
|---|
| 484 | fputs($fp, "$egal$domain\r\n"); |
|---|
| 485 | $found = false; |
|---|
| 486 | $state=0; |
|---|
| 487 | while (!feof($fp)) { |
|---|
| 488 | $ligne = fgets($fp,128); |
|---|
| 489 | // pour ajouter un nouveau TLD, utiliser le code ci-dessous. |
|---|
| 490 | // echo "| $ligne<br />"; |
|---|
| 491 | switch($ext) { |
|---|
| 492 | case "org": |
|---|
| 493 | case "com": |
|---|
| 494 | case "net": |
|---|
| 495 | case "info": |
|---|
| 496 | case "biz": |
|---|
| 497 | case "name": |
|---|
| 498 | case "cc": |
|---|
| 499 | if (preg_match("#Name Server:#", $ligne)) { |
|---|
| 500 | $found = true; |
|---|
| 501 | $tmp=strtolower(str_replace(chr(10), "",str_replace(chr(13),"",str_replace(" ","", str_replace("Name Server:","", $ligne))))); |
|---|
| 502 | if ($tmp) |
|---|
| 503 | $server[]=$tmp; |
|---|
| 504 | } |
|---|
| 505 | break; |
|---|
| 506 | case "cx": |
|---|
| 507 | $ligne = str_replace(chr(10), "",str_replace(chr(13),"",str_replace(" ","", $ligne))); |
|---|
| 508 | if ($ligne=="" && $state==1) |
|---|
| 509 | $state=2; |
|---|
| 510 | if ($state==1) |
|---|
| 511 | $server[]=strtolower($ligne); |
|---|
| 512 | if ($ligne=="Nameservers:" && $state==0) { |
|---|
| 513 | $state=1; |
|---|
| 514 | $found = true; |
|---|
| 515 | } |
|---|
| 516 | break; |
|---|
| 517 | case "eu": |
|---|
| 518 | case "be": |
|---|
| 519 | $ligne=preg_replace("/^ *([^ ]*) \(.*\)$/","\\1",trim($ligne)); |
|---|
| 520 | if($found) |
|---|
| 521 | $tmp = trim($ligne); |
|---|
| 522 | if ($tmp) |
|---|
| 523 | $server[]=$tmp; |
|---|
| 524 | if ($ligne=="Nameservers:") { |
|---|
| 525 | $state=1; |
|---|
| 526 | $found=true; |
|---|
| 527 | } |
|---|
| 528 | break; |
|---|
| 529 | case "im": |
|---|
| 530 | if (preg_match('/Name Server:/', $ligne)) { |
|---|
| 531 | $found = true; |
|---|
| 532 | // weird regexp (trailing garbage after name server), but I could not make it work otherwise |
|---|
| 533 | $tmp = strtolower(preg_replace('/Name Server: ([^ ]+)\..$/',"\\1", $ligne)); |
|---|
| 534 | $tmp = preg_replace('/[^-_a-z0-9\.]/', '', $tmp); |
|---|
| 535 | if ($tmp) |
|---|
| 536 | $server[]=$tmp; |
|---|
| 537 | } |
|---|
| 538 | break; |
|---|
| 539 | case "it": |
|---|
| 540 | if (preg_match("#nserver:#", $ligne)) { |
|---|
| 541 | $found=true; |
|---|
| 542 | $tmp=strtolower(preg_replace("/nserver:\s*[^ ]*\s*([^\s]*)$/","\\1", $ligne)); |
|---|
| 543 | if ($tmp) |
|---|
| 544 | $server[]=$tmp; |
|---|
| 545 | } |
|---|
| 546 | break; |
|---|
| 547 | case "fr": |
|---|
| 548 | case "re": |
|---|
| 549 | if (preg_match("#nserver:#", $ligne)) { |
|---|
| 550 | $found=true; |
|---|
| 551 | $tmp=strtolower(preg_replace("#nserver:\s*([^\s]*)\s*.*$#","\\1", $ligne)); |
|---|
| 552 | if ($tmp) |
|---|
| 553 | $server[]=$tmp; |
|---|
| 554 | } |
|---|
| 555 | break; |
|---|
| 556 | case "ca": |
|---|
| 557 | case "ws"; |
|---|
| 558 | if (preg_match('#Name servers#', $ligne)) { |
|---|
| 559 | // found the server |
|---|
| 560 | $state = 1; |
|---|
| 561 | } elseif ($state) { |
|---|
| 562 | if (preg_match('#^[^%]#', $ligne) && $ligne = preg_replace('#[[:space:]]#', "", $ligne)) { |
|---|
| 563 | // first non-whitespace line is considered to be the nameservers themselves |
|---|
| 564 | $found = true; |
|---|
| 565 | $server[] = $ligne; |
|---|
| 566 | } |
|---|
| 567 | } |
|---|
| 568 | break; |
|---|
| 569 | case "coop": |
|---|
| 570 | if (preg_match('#Host Name:\s*([^\s]+)#', $ligne, $matches)) { |
|---|
| 571 | $found = true; |
|---|
| 572 | $server[] = $matches[1]; |
|---|
| 573 | } |
|---|
| 574 | } // switch |
|---|
| 575 | } // while |
|---|
| 576 | fclose($fp); |
|---|
| 577 | } else { |
|---|
| 578 | $err->raise("dom",11); |
|---|
| 579 | return false; |
|---|
| 580 | } |
|---|
| 581 | |
|---|
| 582 | if ($found) { |
|---|
| 583 | return $server; |
|---|
| 584 | } else { |
|---|
| 585 | $err->raise("dom",12); |
|---|
| 586 | return false; |
|---|
| 587 | } |
|---|
| 588 | } // whois |
|---|
| 589 | |
|---|
| 590 | /* ----------------------------------------------------------------- */ |
|---|
| 591 | /** |
|---|
| 592 | * vérifie la presence d'un champs mx valide sur un serveur DNS |
|---|
| 593 | * |
|---|
| 594 | */ |
|---|
| 595 | |
|---|
| 596 | function checkmx($domaine,$mx) { |
|---|
| 597 | //initialise variables |
|---|
| 598 | $mxhosts = array(); |
|---|
| 599 | |
|---|
| 600 | //récupére les champs mx |
|---|
| 601 | if (!getmxrr($domaine,$mxhosts)) { |
|---|
| 602 | //aucune hôte mx spécifié |
|---|
| 603 | return 1; |
|---|
| 604 | } |
|---|
| 605 | else { |
|---|
| 606 | //vérifie qu'un des hôtes est bien sur alternc |
|---|
| 607 | $bolmx = 0; |
|---|
| 608 | //décompose les différents champ MX coté alternc |
|---|
| 609 | $arrlocalmx = split(",",$mx); |
|---|
| 610 | //parcours les différents champ MX retournés |
|---|
| 611 | foreach($mxhosts as $mxhost) { |
|---|
| 612 | foreach($arrlocalmx as $localmx) { |
|---|
| 613 | if ($mxhost==$localmx) { |
|---|
| 614 | $bolmx = 1; |
|---|
| 615 | } |
|---|
| 616 | } |
|---|
| 617 | } |
|---|
| 618 | //définition de l'erreur selon reponse du parcours de mxhosts |
|---|
| 619 | if ($bolmx == 0) { |
|---|
| 620 | //aucun des champs MX ne correspond au serveur |
|---|
| 621 | return 2; |
|---|
| 622 | } |
|---|
| 623 | else { |
|---|
| 624 | //un champ mx correct a été trouvé |
|---|
| 625 | return 0; |
|---|
| 626 | } |
|---|
| 627 | } |
|---|
| 628 | } //checkmx |
|---|
| 629 | |
|---|
| 630 | |
|---|
| 631 | /* ----------------------------------------------------------------- */ |
|---|
| 632 | /** |
|---|
| 633 | * retourne TOUTES les infos d'un domaine |
|---|
| 634 | * |
|---|
| 635 | * @param string $dom Domaine dont on souhaite les informations |
|---|
| 636 | * @return array Retourne toutes les infos du domaine sous la forme d'un |
|---|
| 637 | * tableau associatif comme suit :<br /><pre> |
|---|
| 638 | * $r["name"] = Nom fqdn |
|---|
| 639 | * $r["dns"] = Gestion du dns ou pas ? |
|---|
| 640 | * $r["mx"] = Valeur du champs MX si "dns"=true |
|---|
| 641 | * $r["mail"] = Heberge-t-on le mail ou pas ? (si "dns"=false) |
|---|
| 642 | * $r["nsub"] = Nombre de sous-domaines |
|---|
| 643 | * $r["sub"] = tableau associatif des sous-domaines |
|---|
| 644 | * $r["sub"][0-(nsub-1)]["name"] = nom du sous-domaine (NON-complet) |
|---|
| 645 | * $r["sub"][0-(nsub-1)]["dest"] = Destination (url, ip, local ...) |
|---|
| 646 | * $r["sub"][0-(nsub-1)]["type"] = Type (0-n) de la redirection. |
|---|
| 647 | * </pre> |
|---|
| 648 | * Retourne FALSE si une erreur s'est produite. |
|---|
| 649 | * |
|---|
| 650 | */ |
|---|
| 651 | function get_domain_all($dom) { |
|---|
| 652 | global $db,$err,$cuid; |
|---|
| 653 | $err->log("dom","get_domain_all",$dom); |
|---|
| 654 | // Locked ? |
|---|
| 655 | if (!$this->islocked) { |
|---|
| 656 | $err->raise("dom",3); |
|---|
| 657 | return false; |
|---|
| 658 | } |
|---|
| 659 | $t=checkfqdn($dom); |
|---|
| 660 | if ($t) { |
|---|
| 661 | $err->raise("dom",3+$t); |
|---|
| 662 | return false; |
|---|
| 663 | } |
|---|
| 664 | $r["name"]=$dom; |
|---|
| 665 | $db->query("select * from domaines where compte='$cuid' and domaine='$dom'"); |
|---|
| 666 | if ($db->num_rows()==0) { |
|---|
| 667 | $err->raise("dom",1,$dom); |
|---|
| 668 | return false; |
|---|
| 669 | } |
|---|
| 670 | $db->next_record(); |
|---|
| 671 | $r["dns"]=$db->Record["gesdns"]; |
|---|
| 672 | $r["dns_action"]=$db->Record["dns_action"]; |
|---|
| 673 | $r["dns_result"]=$db->Record["dns_result"]; |
|---|
| 674 | $r["mail"]=$db->Record["gesmx"]; |
|---|
| 675 | $r["mx"]=$db->Record["mx"]; |
|---|
| 676 | $r['noerase']=$db->Record['noerase']; |
|---|
| 677 | $db->free(); |
|---|
| 678 | $db->query("select count(*) as cnt from sub_domaines where compte='$cuid' and domaine='$dom'"); |
|---|
| 679 | $db->next_record(); |
|---|
| 680 | $r["nsub"]=$db->Record["cnt"]; |
|---|
| 681 | $db->free(); |
|---|
| 682 | $db->query("select sd.*, dt.description as type_desc, dt.only_dns from sub_domaines sd, domaines_type dt where compte='$cuid' and domaine='$dom' and upper(dt.name)=upper(sd.type) order by sd.sub,sd.type"); |
|---|
| 683 | // Pas de webmail, on le cochera si on le trouve. |
|---|
| 684 | $this->webmail=0; |
|---|
| 685 | for($i=0;$i<$r["nsub"];$i++) { |
|---|
| 686 | $db->next_record(); |
|---|
| 687 | $r["sub"][$i]=array(); |
|---|
| 688 | $r["sub"][$i]["name"]=$db->Record["sub"]; |
|---|
| 689 | $r["sub"][$i]["dest"]=$db->Record["valeur"]; |
|---|
| 690 | $r["sub"][$i]["type"]=$db->Record["type"]; |
|---|
| 691 | $r["sub"][$i]["enable"]=$db->Record["enable"]; |
|---|
| 692 | $r["sub"][$i]["type_desc"]=$db->Record["type_desc"]; |
|---|
| 693 | $r["sub"][$i]["only_dns"]=$db->Record["only_dns"]; |
|---|
| 694 | $r["sub"][$i]["web_action"]=$db->Record["web_action"]; |
|---|
| 695 | /* |
|---|
| 696 | if ($db->Record["type"]==3) { // Webmail |
|---|
| 697 | $this->webmail=1; |
|---|
| 698 | $r["sub"][$i]["dest"]=_("Webmail access"); |
|---|
| 699 | } |
|---|
| 700 | */ |
|---|
| 701 | } |
|---|
| 702 | $db->free(); |
|---|
| 703 | return $r; |
|---|
| 704 | } // get_domain_all |
|---|
| 705 | |
|---|
| 706 | |
|---|
| 707 | /* ----------------------------------------------------------------- */ |
|---|
| 708 | /** |
|---|
| 709 | * Retourne TOUTES les infos d'un sous domaine du compte courant. |
|---|
| 710 | * |
|---|
| 711 | * @param string $dom Domaine fqdn concerné |
|---|
| 712 | * @param string $sub Sous-domaine dont on souhaite les informations |
|---|
| 713 | * @return arrray Retourne un tableau associatif contenant les |
|---|
| 714 | * informations du sous-domaine demandé.<pre> |
|---|
| 715 | * $r["name"]= nom du sous-domaine (NON-complet) |
|---|
| 716 | * $r["dest"]= Destination (url, ip, local ...) |
|---|
| 717 | * </pre> |
|---|
| 718 | * $r["type"]= Type (0-n) de la redirection. |
|---|
| 719 | * Retourne FALSE si une erreur s'est produite. |
|---|
| 720 | */ |
|---|
| 721 | function get_sub_domain_all($dom,$sub, $type="", $value='') { |
|---|
| 722 | global $db,$err,$cuid; |
|---|
| 723 | $err->log("dom","get_sub_domain_all",$dom."/".$sub); |
|---|
| 724 | // Locked ? |
|---|
| 725 | if (!$this->islocked) { |
|---|
| 726 | $err->raise("dom",3); |
|---|
| 727 | return false; |
|---|
| 728 | } |
|---|
| 729 | $t=checkfqdn($dom); |
|---|
| 730 | if ($t) { |
|---|
| 731 | $err->raise("dom",3+$t); |
|---|
| 732 | return false; |
|---|
| 733 | } |
|---|
| 734 | /* |
|---|
| 735 | if ( ! empty($value)) { |
|---|
| 736 | $type = " and valeur=\"".mysql_real_escape_string($value)."\""; |
|---|
| 737 | } |
|---|
| 738 | if ( ! empty($type)) { |
|---|
| 739 | $type = " and type=\"".mysql_real_escape_string($type)."\""; |
|---|
| 740 | } |
|---|
| 741 | */ |
|---|
| 742 | $db->query("select sd.*, dt.description as type_desc, dt.only_dns from sub_domaines sd, domaines_type dt where compte='$cuid' and domaine='$dom' and sub='$sub' and ( length('$type')=0 or type='$type') and (length('$value')=0 or '$value'=valeur) and upper(dt.name)=upper(sd.type);"); |
|---|
| 743 | if ($db->num_rows()==0) { |
|---|
| 744 | $err->raise("dom",14); |
|---|
| 745 | return false; |
|---|
| 746 | } |
|---|
| 747 | $db->next_record(); |
|---|
| 748 | $r=array(); |
|---|
| 749 | $r["name"]=$db->Record["sub"]; |
|---|
| 750 | $r["dest"]=$db->Record["valeur"]; |
|---|
| 751 | $r["enable"]=$db->Record["enable"]; |
|---|
| 752 | $r["type_desc"]=$db->Record["type_desc"]; |
|---|
| 753 | $r["only_dns"]=$db->Record["only_dns"]; |
|---|
| 754 | $r["web_action"]=$db->Record["web_action"]; |
|---|
| 755 | $db->free(); |
|---|
| 756 | return $r; |
|---|
| 757 | } // get_sub_domain_all |
|---|
| 758 | |
|---|
| 759 | |
|---|
| 760 | function check_type_value($type, $value) { |
|---|
| 761 | global $db,$err,$cuid; |
|---|
| 762 | |
|---|
| 763 | // check the type we can have in domaines_type.target |
|---|
| 764 | |
|---|
| 765 | switch ($this->domains_type_target_values($type)) { |
|---|
| 766 | case 'NONE': |
|---|
| 767 | if (empty($value) or is_null($value)) {return true;} |
|---|
| 768 | break; |
|---|
| 769 | case 'URL': |
|---|
| 770 | if ( $value == strval($value)) {return true;} |
|---|
| 771 | break; |
|---|
| 772 | case 'DIRECTORY': |
|---|
| 773 | if (substr($value,0,1)!="/") { |
|---|
| 774 | $value="/".$value; |
|---|
| 775 | } |
|---|
| 776 | if (!checkuserpath($value)) { |
|---|
| 777 | $err->raise("dom",21); |
|---|
| 778 | return false; |
|---|
| 779 | } |
|---|
| 780 | return true; |
|---|
| 781 | break; |
|---|
| 782 | case 'IP': |
|---|
| 783 | if (checkip($value)) {return true;} |
|---|
| 784 | break; |
|---|
| 785 | case 'IPV6': |
|---|
| 786 | if (checkipv6($value)) {return true;} |
|---|
| 787 | break; |
|---|
| 788 | case 'DOMAIN': |
|---|
| 789 | if (checkcname($value)) {return true;} |
|---|
| 790 | break; |
|---|
| 791 | case 'TXT': |
|---|
| 792 | if ( $value == strval($value)) {return true;} |
|---|
| 793 | break; |
|---|
| 794 | default: |
|---|
| 795 | return false; |
|---|
| 796 | break; |
|---|
| 797 | } |
|---|
| 798 | return false; |
|---|
| 799 | } //check_type_value |
|---|
| 800 | |
|---|
| 801 | |
|---|
| 802 | function can_create_subdomain($dom,$sub,$type,$type_old='', $value_old='') { |
|---|
| 803 | global $db,$err,$cuid; |
|---|
| 804 | $err->log("dom","can_create_subdomain",$dom."/".$sub); |
|---|
| 805 | |
|---|
| 806 | # Get the compatibility list for this domain type |
|---|
| 807 | $db->query("select upper(compatibility) as compatibility from domaines_type where upper(name)=upper('$type');"); |
|---|
| 808 | if (!$db->next_record()) return false; |
|---|
| 809 | $compatibility_lst = explode(",",$db->f('compatibility')); |
|---|
| 810 | |
|---|
| 811 | # Get the list of type of subdomains already here who have the same name |
|---|
| 812 | $db->query("select * from sub_domaines where sub='$sub' and domaine='$dom' and not (type='$type_old' and valeur='$value_old') and web_action != 'DELETE'"); |
|---|
| 813 | #$db->query("select * from sub_domaines where sub='$sub' and domaine='$dom';"); |
|---|
| 814 | while ($db->next_record()) { |
|---|
| 815 | # And if there is a domain with a incompatible type, return false |
|---|
| 816 | if (! in_array(strtoupper($db->f('type')),$compatibility_lst)) return false; |
|---|
| 817 | } |
|---|
| 818 | |
|---|
| 819 | # All is right, go ! Create ur domain ! |
|---|
| 820 | return true; |
|---|
| 821 | } |
|---|
| 822 | |
|---|
| 823 | // /* ----------------------------------------------------------------- */ |
|---|
| 824 | /** |
|---|
| 825 | * Modifier les information du sous-domaine demandé. |
|---|
| 826 | * |
|---|
| 827 | * <b>Note</b> : si le sous-domaine $sub.$dom n'existe pas, il est créé.<br /> |
|---|
| 828 | * <b>Note : TODO</b> : vérification de concordance de $dest<br /> |
|---|
| 829 | * |
|---|
| 830 | * @param string $dom Domaine dont on souhaite modifier/ajouter un sous domaine |
|---|
| 831 | * @param string $subk Sous domaine à modifier / créer |
|---|
| 832 | * @param integer $type Type de sous-domaine (local, ip, url ...) |
|---|
| 833 | * @param string $action Action : vaut "add" ou "edit" selon que l'on |
|---|
| 834 | * Crée (add) ou Modifie (edit) le sous-domaine |
|---|
| 835 | * @param string $dest Destination du sous-domaine, dépend de la valeur |
|---|
| 836 | * de $type (url, ip, dossier...) |
|---|
| 837 | * @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon. |
|---|
| 838 | */ |
|---|
| 839 | // TODO : j'ai viré le type action, valider que plus personne ne l'utilise (quatrieme argument) |
|---|
| 840 | function set_sub_domain($dom,$sub,$type,$dest, $type_old=null,$sub_old=null,$value_old=null) { |
|---|
| 841 | global $db,$err,$cuid; |
|---|
| 842 | $err->log("dom","set_sub_domain",$dom."/".$sub."/".$type."/".$dest); |
|---|
| 843 | // Locked ? |
|---|
| 844 | if (!$this->islocked) { |
|---|
| 845 | $err->raise("dom",3); |
|---|
| 846 | return false; |
|---|
| 847 | } |
|---|
| 848 | $dest=trim($dest); |
|---|
| 849 | $sub=trim(trim($sub),"."); |
|---|
| 850 | $dom=strtolower($dom); |
|---|
| 851 | $sub=strtolower($sub); |
|---|
| 852 | |
|---|
| 853 | // if (!(($sub == '*') || ($sub=="") || (preg_match('/([a-z0-9][\.\-a-z0-9]*)?[a-z0-9]/', $sub)))) { |
|---|
| 854 | $fqdn=checkfqdn($sub); |
|---|
| 855 | // Special cases : * (all subdomains at once) and '' empty subdomain are allowed. |
|---|
| 856 | if (($sub != '*' && $sub!='') && !($fqdn==0 || $fqdn==4)) { |
|---|
| 857 | $err->raise("dom",24); |
|---|
| 858 | return false; |
|---|
| 859 | } |
|---|
| 860 | |
|---|
| 861 | if (! $this->check_type_value($type,$dest)) { |
|---|
| 862 | # TODO have a real err code |
|---|
| 863 | $err->raise("dom",667); |
|---|
| 864 | return false; |
|---|
| 865 | } |
|---|
| 866 | |
|---|
| 867 | // On a épuré $dir des problèmes eventuels ... On est en DESSOUS du dossier de l'utilisateur. |
|---|
| 868 | if ($t=checkfqdn($dom)) { |
|---|
| 869 | $err->raise("dom",3+$t); |
|---|
| 870 | return false; |
|---|
| 871 | } |
|---|
| 872 | |
|---|
| 873 | if (! $this->can_create_subdomain($dom,$sub,$type,$type_old,$value_old)) { |
|---|
| 874 | # TODO have a real error code |
|---|
| 875 | $err->raise("dom", 654); |
|---|
| 876 | return false; |
|---|
| 877 | } |
|---|
| 878 | |
|---|
| 879 | if (! is_null($type_old )) { // It's not a creation, it's an edit. Delete the old one |
|---|
| 880 | $db->query("update sub_domaines set web_action='DELETE' where domaine='$dom' and sub='$sub' and upper(type)=upper('$type_old') and valeur='$value_old';"); |
|---|
| 881 | } |
|---|
| 882 | |
|---|
| 883 | // Re-create the one we want |
|---|
| 884 | if (! $db->query("insert into sub_domaines (compte,domaine,sub,valeur,type,web_action) values ('$cuid','$dom','$sub','$dest','$type','UPDATE');") ) { |
|---|
| 885 | echo "query failed: ".$db->Error; |
|---|
| 886 | return false; |
|---|
| 887 | } |
|---|
| 888 | |
|---|
| 889 | // Tell to update the DNS file |
|---|
| 890 | $db->query("update domaines set dns_action='UPDATE' where domaine='$dom';"); |
|---|
| 891 | |
|---|
| 892 | return true; |
|---|
| 893 | } // set_sub_domain |
|---|
| 894 | |
|---|
| 895 | |
|---|
| 896 | /* ----------------------------------------------------------------- */ |
|---|
| 897 | /** |
|---|
| 898 | * Supprime le sous-domaine demandé |
|---|
| 899 | * |
|---|
| 900 | * @param string $dom Domaine dont on souhaite supprimer un sous-domaine |
|---|
| 901 | * @param string $sub Sous-domaine que l'on souhaite supprimer |
|---|
| 902 | * @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon. |
|---|
| 903 | * |
|---|
| 904 | */ |
|---|
| 905 | function del_sub_domain($dom,$sub,$type,$value='') { |
|---|
| 906 | global $db,$err,$cuid; |
|---|
| 907 | $err->log("dom","del_sub_domain",$dom."/".$sub); |
|---|
| 908 | // Locked ? |
|---|
| 909 | if (!$this->islocked) { |
|---|
| 910 | $err->raise("dom",3); |
|---|
| 911 | return false; |
|---|
| 912 | } |
|---|
| 913 | $t=checkfqdn($dom); |
|---|
| 914 | if ($t) { |
|---|
| 915 | $err->raise("dom",3+$t); |
|---|
| 916 | return false; |
|---|
| 917 | } |
|---|
| 918 | if (!$r=$this->get_sub_domain_all($dom,$sub,$type)) { |
|---|
| 919 | // Le sous-domaine n'existe pas, erreur |
|---|
| 920 | $err->raise("dom",14); |
|---|
| 921 | return false; |
|---|
| 922 | } else { |
|---|
| 923 | // OK, on valide : |
|---|
| 924 | $db->query("update sub_domaines set web_action='DELETE' where domaine='$dom' and sub='$sub' and type='$type' and ( length('$value')=0 or valeur='$value') "); |
|---|
| 925 | $db->query("update domaines set dns_action='UPDATE' where domaine='$dom';"); |
|---|
| 926 | } |
|---|
| 927 | return true; |
|---|
| 928 | } // del_sub_domain |
|---|
| 929 | |
|---|
| 930 | /* ----------------------------------------------------------------- */ |
|---|
| 931 | /** |
|---|
| 932 | * Modifie les information du domaine précisé. |
|---|
| 933 | * |
|---|
| 934 | * @param string $dom Domaine du compte courant que l'on souhaite modifier |
|---|
| 935 | * @param integer $dns Vaut 1 ou 0 pour héberger ou pas le DNS du domaine |
|---|
| 936 | * @param integer $gesmx Héberge-t-on le emails du domaines sur ce serveur ? |
|---|
| 937 | * @param boolean $force Faut-il passer les checks DNS ou MX ? (admin only) |
|---|
| 938 | * @return boolean appelle $mail->add_dom ou $ma->del_dom si besoin, en |
|---|
| 939 | * fonction du champs MX. Retourne FALSE si une erreur s'est produite, |
|---|
| 940 | * TRUE sinon. |
|---|
| 941 | * |
|---|
| 942 | */ |
|---|
| 943 | function edit_domain($dom,$dns,$gesmx,$force=0) { |
|---|
| 944 | global $db,$err,$L_MX,$classes,$cuid; |
|---|
| 945 | $err->log("dom","edit_domain",$dom."/".$dns."/".$gesmx); |
|---|
| 946 | // Locked ? |
|---|
| 947 | if (!$this->islocked && !$force) { |
|---|
| 948 | $err->raise("dom",3); |
|---|
| 949 | return false; |
|---|
| 950 | } |
|---|
| 951 | if ($dns == 1 && !$force) { |
|---|
| 952 | $this->dns=$this->whois($dom); |
|---|
| 953 | $v=checkhostallow($dom,$this->dns); |
|---|
| 954 | if ($v==-1) { |
|---|
| 955 | $err->raise("dom",7); // TLD interdit |
|---|
| 956 | return false; |
|---|
| 957 | } |
|---|
| 958 | if ($dns && $v==-2) { |
|---|
| 959 | $err->raise("dom",12); // Domaine non trouvé dans le whois |
|---|
| 960 | return false; |
|---|
| 961 | } |
|---|
| 962 | if ($dns && $v==-3) { |
|---|
| 963 | $err->raise("dom",23); // Domaine non trouvé dans le whois |
|---|
| 964 | return false; |
|---|
| 965 | } |
|---|
| 966 | } |
|---|
| 967 | $t=checkfqdn($dom); |
|---|
| 968 | if ($t) { |
|---|
| 969 | $err->raise("dom",3+$t); |
|---|
| 970 | return false; |
|---|
| 971 | } |
|---|
| 972 | if (!$r=$this->get_domain_all($dom)) { |
|---|
| 973 | // Le domaine n'existe pas, Failure |
|---|
| 974 | $err->raise("dom",4,$dom); |
|---|
| 975 | return false; |
|---|
| 976 | } |
|---|
| 977 | if ($dns!="1") $dns="0"; |
|---|
| 978 | // On vérifie que des modifications ont bien eu lieu :) |
|---|
| 979 | if ($r["dns"]==$dns && $r["mail"]==$gesmx) { |
|---|
| 980 | $err->raise("dom",15); |
|---|
| 981 | return false; |
|---|
| 982 | } |
|---|
| 983 | |
|---|
| 984 | //si gestion mx uniquement, vérification du dns externe |
|---|
| 985 | if ($dns=="0" && $gesmx=="1" && !$force) { |
|---|
| 986 | $vmx = $this->checkmx($dom,$mx); |
|---|
| 987 | if ($vmx == 1) { |
|---|
| 988 | // Aucun champ mx de spécifié sur le dns |
|---|
| 989 | $err->raise("dom",25); |
|---|
| 990 | return false; |
|---|
| 991 | } |
|---|
| 992 | |
|---|
| 993 | if ($vmx == 2) { |
|---|
| 994 | // Serveur non spécifié parmi les champx mx |
|---|
| 995 | $err->raise("dom",25); |
|---|
| 996 | return false; |
|---|
| 997 | } |
|---|
| 998 | } |
|---|
| 999 | |
|---|
| 1000 | // OK, des modifs ont été faites, on valide : |
|---|
| 1001 | // DEPENDANCE : |
|---|
| 1002 | if ($gesmx && !$r["mail"]) { // on a associé le MX : on cree donc l'entree dans MySQL |
|---|
| 1003 | // Lancement de add_dom sur les classes domain_sensitive : |
|---|
| 1004 | foreach($classes as $c) { |
|---|
| 1005 | if (method_exists($GLOBALS[$c],"alternc_add_mx_domain")) { |
|---|
| 1006 | $GLOBALS[$c]->alternc_add_mx_domain($dom); |
|---|
| 1007 | } |
|---|
| 1008 | } |
|---|
| 1009 | } |
|---|
| 1010 | |
|---|
| 1011 | if (!$gesmx && $r["mail"]) { // on a dissocié le MX : on détruit donc l'entree dans LDAP |
|---|
| 1012 | // Lancement de del_dom sur les classes domain_sensitive : |
|---|
| 1013 | foreach($classes as $c) { |
|---|
| 1014 | if (method_exists($GLOBALS[$c],"alternc_del_mx_domain")) { |
|---|
| 1015 | $GLOBALS[$c]->alternc_del_mx_domain($dom); |
|---|
| 1016 | } |
|---|
| 1017 | } |
|---|
| 1018 | } |
|---|
| 1019 | |
|---|
| 1020 | $db->query("UPDATE domaines SET gesdns='$dns', gesmx='$gesmx' WHERE domaine='$dom'"); |
|---|
| 1021 | $db->query("UPDATE domaines set dns_action='UPDATE' where domaine='$dom';"); |
|---|
| 1022 | |
|---|
| 1023 | return true; |
|---|
| 1024 | } // edit_domain |
|---|
| 1025 | |
|---|
| 1026 | |
|---|
| 1027 | |
|---|
| 1028 | /****************************/ |
|---|
| 1029 | /* Slave dns ip managment */ |
|---|
| 1030 | /****************************/ |
|---|
| 1031 | /* ----------------------------------------------------------------- */ |
|---|
| 1032 | /** |
|---|
| 1033 | * Return the list of ip addresses and classes that are allowed access to domain list |
|---|
| 1034 | * through AXFR Transfers from the bind server. |
|---|
| 1035 | */ |
|---|
| 1036 | function enum_slave_ip() { |
|---|
| 1037 | global $db,$err; |
|---|
| 1038 | $db->query("SELECT * FROM slaveip;"); |
|---|
| 1039 | if (!$db->next_record()) { |
|---|
| 1040 | return false; |
|---|
| 1041 | } |
|---|
| 1042 | do { |
|---|
| 1043 | $res[]=$db->Record; |
|---|
| 1044 | } while ($db->next_record()); |
|---|
| 1045 | return $res; |
|---|
| 1046 | } |
|---|
| 1047 | |
|---|
| 1048 | /* ----------------------------------------------------------------- */ |
|---|
| 1049 | /** |
|---|
| 1050 | * Add an ip address (or a ip class) to the list of allowed slave ip access list. |
|---|
| 1051 | */ |
|---|
| 1052 | function add_slave_ip($ip,$class="32") { |
|---|
| 1053 | global $db,$err; |
|---|
| 1054 | if (!checkip($ip)) { |
|---|
| 1055 | $err->raise("dom",19); |
|---|
| 1056 | return false; |
|---|
| 1057 | } |
|---|
| 1058 | $class=intval($class); |
|---|
| 1059 | if ($class<8 || $class>32) $class=32; |
|---|
| 1060 | $db->query("SELECT * FROM slaveip WHERE ip='$ip' AND class='$class';"); |
|---|
| 1061 | if ($db->next_record()) { |
|---|
| 1062 | $err->raise("err",22); |
|---|
| 1063 | return false; |
|---|
| 1064 | } |
|---|
| 1065 | $db->query("INSERT INTO slaveip (ip,class) VALUES ('$ip','$class');"); |
|---|
| 1066 | $f=fopen(SLAVE_FLAG,"w"); |
|---|
| 1067 | fputs($f,"yopla"); |
|---|
| 1068 | fclose($f); |
|---|
| 1069 | return true; |
|---|
| 1070 | } |
|---|
| 1071 | |
|---|
| 1072 | /* ----------------------------------------------------------------- */ |
|---|
| 1073 | /** |
|---|
| 1074 | * Remove an ip address (or a ip class) from the list of allowed slave ip access list. |
|---|
| 1075 | */ |
|---|
| 1076 | function del_slave_ip($ip) { |
|---|
| 1077 | global $db,$err; |
|---|
| 1078 | if (!checkip($ip)) { |
|---|
| 1079 | $err->raise("dom",19); |
|---|
| 1080 | return false; |
|---|
| 1081 | } |
|---|
| 1082 | $db->query("DELETE FROM slaveip WHERE ip='$ip'"); |
|---|
| 1083 | $f=fopen(SLAVE_FLAG,"w"); |
|---|
| 1084 | fputs($f,"yopla"); |
|---|
| 1085 | fclose($f); |
|---|
| 1086 | return true; |
|---|
| 1087 | } |
|---|
| 1088 | |
|---|
| 1089 | |
|---|
| 1090 | |
|---|
| 1091 | /* ----------------------------------------------------------------- */ |
|---|
| 1092 | /** |
|---|
| 1093 | * Check for a slave account |
|---|
| 1094 | */ |
|---|
| 1095 | function check_slave_account($login,$pass) { |
|---|
| 1096 | global $db,$err; |
|---|
| 1097 | $db->query("SELECT * FROM slaveaccount WHERE login='$login' AND pass='$pass';"); |
|---|
| 1098 | if ($db->next_record()) { |
|---|
| 1099 | return true; |
|---|
| 1100 | } |
|---|
| 1101 | return false; |
|---|
| 1102 | } |
|---|
| 1103 | |
|---|
| 1104 | /* ----------------------------------------------------------------- */ |
|---|
| 1105 | /** |
|---|
| 1106 | * Out (echo) the complete hosted domain list : |
|---|
| 1107 | */ |
|---|
| 1108 | function echo_domain_list() { |
|---|
| 1109 | global $db,$err; |
|---|
| 1110 | $db->query("SELECT domaine FROM domaines WHERE gesdns=1 ORDER BY domaine"); |
|---|
| 1111 | while ($db->next_record()) { |
|---|
| 1112 | echo $db->f("domaine")."\n"; |
|---|
| 1113 | } |
|---|
| 1114 | return true; |
|---|
| 1115 | } |
|---|
| 1116 | |
|---|
| 1117 | |
|---|
| 1118 | /* ----------------------------------------------------------------- */ |
|---|
| 1119 | /** |
|---|
| 1120 | * Returns the complete hosted domain list : |
|---|
| 1121 | */ |
|---|
| 1122 | function get_domain_list($uid=-1) { |
|---|
| 1123 | global $db,$err; |
|---|
| 1124 | $uid=intval($uid); |
|---|
| 1125 | $res=array(); |
|---|
| 1126 | if ($uid!=-1) { |
|---|
| 1127 | $sql=" AND compte='$uid' "; |
|---|
| 1128 | } |
|---|
| 1129 | $db->query("SELECT domaine FROM domaines WHERE gesdns=1 $sql ORDER BY domaine"); |
|---|
| 1130 | while ($db->next_record()) { |
|---|
| 1131 | $res[]=$db->f("domaine"); |
|---|
| 1132 | } |
|---|
| 1133 | return $res; |
|---|
| 1134 | } |
|---|
| 1135 | |
|---|
| 1136 | |
|---|
| 1137 | /* ----------------------------------------------------------------- */ |
|---|
| 1138 | /** |
|---|
| 1139 | * Return the list of allowed slave accounts |
|---|
| 1140 | */ |
|---|
| 1141 | function enum_slave_account() { |
|---|
| 1142 | global $db,$err; |
|---|
| 1143 | $db->query("SELECT * FROM slaveaccount;"); |
|---|
| 1144 | $res=array(); |
|---|
| 1145 | while ($db->next_record()) { |
|---|
| 1146 | $res[]=$db->Record; |
|---|
| 1147 | } |
|---|
| 1148 | if (!count($res)) return false; |
|---|
| 1149 | return $res; |
|---|
| 1150 | } |
|---|
| 1151 | |
|---|
| 1152 | /* ----------------------------------------------------------------- */ |
|---|
| 1153 | /** |
|---|
| 1154 | * Add a slave account that will be allowed to access the domain list |
|---|
| 1155 | */ |
|---|
| 1156 | function add_slave_account($login,$pass) { |
|---|
| 1157 | global $db,$err; |
|---|
| 1158 | $db->query("SELECT * FROM slaveaccount WHERE login='$login'"); |
|---|
| 1159 | if ($db->next_record()) { |
|---|
| 1160 | $err->raise("err",23); |
|---|
| 1161 | return false; |
|---|
| 1162 | } |
|---|
| 1163 | $db->query("INSERT INTO slaveaccount (login,pass) VALUES ('$login','$pass')"); |
|---|
| 1164 | return true; |
|---|
| 1165 | } |
|---|
| 1166 | |
|---|
| 1167 | /* ----------------------------------------------------------------- */ |
|---|
| 1168 | /** |
|---|
| 1169 | * Remove a slave account |
|---|
| 1170 | */ |
|---|
| 1171 | function del_slave_account($login) { |
|---|
| 1172 | global $db,$err; |
|---|
| 1173 | $db->query("DELETE FROM slaveaccount WHERE login='$login'"); |
|---|
| 1174 | return true; |
|---|
| 1175 | } |
|---|
| 1176 | |
|---|
| 1177 | /*************/ |
|---|
| 1178 | /* Private */ |
|---|
| 1179 | /*************/ |
|---|
| 1180 | |
|---|
| 1181 | |
|---|
| 1182 | /* ----------------------------------------------------------------- */ |
|---|
| 1183 | /** |
|---|
| 1184 | * Lock tente de verrouiller le fichier lock du cron. Si tout va bien (toujours?) |
|---|
| 1185 | * retourne True, sinon retourne False |
|---|
| 1186 | * NOTE : le systeme de lock est asymétrique, si on a un fichier CRONLOCK, on |
|---|
| 1187 | * attends (que le cron ait fini son execution). |
|---|
| 1188 | * @access private |
|---|
| 1189 | */ |
|---|
| 1190 | function lock() { |
|---|
| 1191 | global $db,$err; |
|---|
| 1192 | $err->log("dom","lock"); |
|---|
| 1193 | if ($this->islocked) { |
|---|
| 1194 | $err->raise("dom",17); |
|---|
| 1195 | } |
|---|
| 1196 | while (file_exists($this->fic_lock_cron)) { |
|---|
| 1197 | sleep(2); |
|---|
| 1198 | } |
|---|
| 1199 | $this->islocked=true; |
|---|
| 1200 | return true; |
|---|
| 1201 | } |
|---|
| 1202 | |
|---|
| 1203 | /* ----------------------------------------------------------------- */ |
|---|
| 1204 | /** |
|---|
| 1205 | * unlock déverrouille le fichier lock du cron. Si tout va bien (toujours?) |
|---|
| 1206 | * retourne True, sinon retourne False |
|---|
| 1207 | * NOTE : actuellement, vu le système de lock asymetrique, on ne fait rien ;) |
|---|
| 1208 | * @access private |
|---|
| 1209 | */ |
|---|
| 1210 | function unlock() { |
|---|
| 1211 | global $db,$err; |
|---|
| 1212 | $err->log("dom","unlock"); |
|---|
| 1213 | if (!$this->islocked) { |
|---|
| 1214 | $err->raise("dom",3); |
|---|
| 1215 | } |
|---|
| 1216 | $this->islocked=false; |
|---|
| 1217 | return true; |
|---|
| 1218 | } |
|---|
| 1219 | |
|---|
| 1220 | |
|---|
| 1221 | /* ----------------------------------------------------------------- */ |
|---|
| 1222 | /** |
|---|
| 1223 | * Declare that a domain's emails are hosted in this server : |
|---|
| 1224 | * This adds 2 MX entries in this domain (if required) |
|---|
| 1225 | */ |
|---|
| 1226 | function alternc_add_mx_domain($domain) { |
|---|
| 1227 | global $err; |
|---|
| 1228 | $err->log("dom","alternc_add_mx_domain"); |
|---|
| 1229 | $this->set_sub_domain($domain, '', $this->type_defmx, ''); |
|---|
| 1230 | if (! empty($GLOBALS['L_DEFAULT_SECONDARY_MX'])) { |
|---|
| 1231 | $this->set_sub_domain($domain, '', $this->type_defmx2, ''); |
|---|
| 1232 | } |
|---|
| 1233 | return true; |
|---|
| 1234 | } |
|---|
| 1235 | |
|---|
| 1236 | |
|---|
| 1237 | /* ----------------------------------------------------------------- */ |
|---|
| 1238 | /** |
|---|
| 1239 | * Efface un compte (tous ses domaines) |
|---|
| 1240 | */ |
|---|
| 1241 | function alternc_del_member() { |
|---|
| 1242 | global $err; |
|---|
| 1243 | $err->log("dom","alternc_del_member"); |
|---|
| 1244 | $li=$this->enum_domains(); |
|---|
| 1245 | foreach($li as $dom) { |
|---|
| 1246 | $this->del_domain($dom); |
|---|
| 1247 | } |
|---|
| 1248 | return true; |
|---|
| 1249 | } |
|---|
| 1250 | |
|---|
| 1251 | |
|---|
| 1252 | /* ----------------------------------------------------------------- */ |
|---|
| 1253 | /** |
|---|
| 1254 | * Returns the used quota for the $name service for the current user. |
|---|
| 1255 | * @param $name string name of the quota |
|---|
| 1256 | * @return integer the number of service used or false if an error occured |
|---|
| 1257 | * @access private |
|---|
| 1258 | */ |
|---|
| 1259 | function alternc_get_quota($name) { |
|---|
| 1260 | global $db,$err,$cuid; |
|---|
| 1261 | if ($name=="dom") { |
|---|
| 1262 | $err->log("dom","get_quota"); |
|---|
| 1263 | $db->query("SELECT COUNT(*) AS cnt FROM domaines WHERE compte='$cuid'"); |
|---|
| 1264 | $db->next_record(); |
|---|
| 1265 | return $db->f("cnt"); |
|---|
| 1266 | } else return false; |
|---|
| 1267 | } |
|---|
| 1268 | |
|---|
| 1269 | |
|---|
| 1270 | /* ----------------------------------------------------------------- */ |
|---|
| 1271 | /** |
|---|
| 1272 | * Exporte toutes les informations domaine du compte. |
|---|
| 1273 | * @access private |
|---|
| 1274 | * EXPERIMENTAL 'sid' function ;) |
|---|
| 1275 | */ |
|---|
| 1276 | function alternc_export() { |
|---|
| 1277 | global $db,$err; |
|---|
| 1278 | $err->log("dom","export"); |
|---|
| 1279 | $this->enum_domains(); |
|---|
| 1280 | $str="<dom>\n"; |
|---|
| 1281 | foreach ($this->domains as $d) { |
|---|
| 1282 | $str.=" <domain>\n <name>".xml_entities($d)."</name>\n"; |
|---|
| 1283 | $s=$this->get_domain_all($d); |
|---|
| 1284 | $str.=" <hasdns>".xml_entities($s[dns])."</hasdns>\n"; |
|---|
| 1285 | $str.=" <hasmx>".xml_entities($s[mx])."</hasmx>\n"; |
|---|
| 1286 | $str.=" <mx>".xml_entities($s[mail])."</mx>\n"; |
|---|
| 1287 | if (is_array($s[sub])) { |
|---|
| 1288 | foreach ($s[sub] as $sub) { |
|---|
| 1289 | $str.=" <subdomain>"; |
|---|
| 1290 | $str.="<name>".xml_entities($sub[name])."</name>"; |
|---|
| 1291 | $str.="<dest>".xml_entities($sub[dest])."</dest>"; |
|---|
| 1292 | $str.="<type>".xml_entities($sub[type])."</type>"; |
|---|
| 1293 | $str.="</subdomain>\n"; |
|---|
| 1294 | } |
|---|
| 1295 | } |
|---|
| 1296 | $str.=" </domain>\n"; |
|---|
| 1297 | } |
|---|
| 1298 | $str.="</dom>\n"; |
|---|
| 1299 | return $str; |
|---|
| 1300 | } |
|---|
| 1301 | |
|---|
| 1302 | |
|---|
| 1303 | } /* Class m_domains */ |
|---|
| 1304 | |
|---|
| 1305 | ?> |
|---|