"FTP accounts"); } // Return the values needed to activate security access. See get_auth_class() // in authip for more informations function authip_class() { $c = Array(); $c['name']="FTP"; $c['protocol']="ftp"; $c['values']=Array(); $tt = $this->get_list(); if (empty($tt) || !is_array($tt)) return $c; foreach ($this->get_list() as $v ) { $c['values'][$v['id']]=$v['login']; } return $c; } /* ----------------------------------------------------------------- */ /** Retourne la liste des comptes FTP du compte hébergé * Retourne la liste des comptes FTP sous forme de tableau indexé de * tableaus associatifs comme suit : * $a["id"]= ID du compte ftp * $a["login"]= Nom de login du compte * $a["pass"]= Mot de passe du compte * $a["dir"]= Dossier relatif à la racine du compte de l'utilisateur * @return array Retourne le tableau des comptes ou FALSE si une erreur s'est produite. */ function get_list() { global $db,$err,$cuid; $err->log("ftp","get_list"); $r=array(); $db->query("SELECT id, name, homedir FROM ftpusers WHERE uid='$cuid' ORDER BY homedir;"); if ($db->num_rows()) { while ($db->next_record()) { // On passe /var/alternc/html/u/user // FIXME: utiliser getuserpath() $tr=preg_match("/^\/var\/alternc\/html\/.\/[^\/]*\/(.*)$/", $db->f("homedir"),$match); /* " */ $r[]=array( "id"=>$db->f("id"), "login"=>$db->f("name"), //"dir"=>$match[1] "dir"=>$db->f("homedir") ); } return $r; } else { $err->raise("ftp",_("No FTP account found")); return false; } } function hook_admin_add_member() { global $mem,$err; $err->log("ftp","hook_admin_add_member"); return $this->add_ftp($mem->user['login'],"",$mem->user['pass'],"/"); } /* ----------------------------------------------------------------- */ /** Retourne les détails d'un compte FTP (voir get_list) * Le tableau est celui du compte d'id spécifié * @param integer $id Numéro du compte dont on souhaite obtenir les détails * @return array Tableau associatif contenant les infos du comptes ftp */ function get_ftp_details($id) { global $db,$err,$cuid; $err->log("ftp","get_ftp_details",$id); $r=array(); $db->query("SELECT id, name, homedir FROM ftpusers WHERE uid='$cuid' AND id='$id';"); if ($db->num_rows()) { $db->next_record(); // FIXME: utiliser getuserpath $tr=preg_match("/^\/var\/alternc\/html\/.\/[^\/]*\/(.*)$/", $db->f("homedir"),$match); $lg=explode("_",$db->f("name")); if ((!is_array($lg)) || (count($lg)!=2)) { $lg[0]=$db->f("name"); $lg[1]=""; } $r[]=array( "id"=>$db->f("id"), "prefixe"=> $lg[0], "login"=>$lg[1], "dir"=>$match[1] ); return $r; } else { $err->raise("ftp",_("This FTP account does not exist")); return false; } } /* ----------------------------------------------------------------- */ /** Retourne la liste des prefixes utilisables par le compte courant * @return array tableau contenant la liste des prefixes (domaines + login) * du compte actuel. */ function prefix_list() { global $db,$mem,$cuid; $r=array(); $r[]=$mem->user["login"]; $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' ORDER BY domaine;"); while ($db->next_record()) { $r[]=$db->f("domaine"); } return $r; } /* ----------------------------------------------------------------- */ /** Affiche (ECHO) la liste des prefixes disponibles sous forme de champs d'option * Les champs sont affichés sous la forme ... * La valeur $current se voit affublée de la balise SELECTED. * @param string $current Prefixe sélectionné par défaut * @return boolean TRUE. */ function select_prefix_list($current) { $r=$this->prefix_list(); reset($r); while (list($key,$val)=each($r)) { if ($current==$val) $c=" selected=\"selected\""; else $c=""; echo "$val"; } return true; } /* ----------------------------------------------------------------- */ /** Modifie les paramètres du comptes FTP $id. * @param integer $id Numéro du compte dont on veut modifier les paramètres * @param string $prefixe Prefixe du compte FTP * @param string $login login ajouté au préfixe ($prefixe_$login) * @param string $pass mot de passe * @param string $dir Répertoire racine du compte * @return boolean TRUE si le compte a été modifié, FALSE si une erreur est survenue. */ function put_ftp_details($id,$prefixe,$login,$pass,$dir) { global $mem,$db,$err,$bro,$cuid,$admin; $err->log("ftp","put_ftp_details",$id); $db->query("SELECT count(*) AS cnt FROM ftpusers WHERE id='$id' and uid='$cuid';"); $db->next_record(); if (!$db->f("cnt")) { $err->raise("ftp",_("This FTP account does not exist")); return false; } $dir=$bro->convertabsolute($dir); if (substr($dir,0,1)=="/") { $dir=substr($dir,1); } $r=$this->prefix_list(); if (!in_array($prefixe,$r)) { $err->raise("ftp",_("The chosen prefix is not allowed")); return false; } $lo=$mem->user["login"]; $l=substr($lo,0,1); if ($login) $login="_".$login; $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE id!='$id' AND name='$prefixe$login';"); $db->next_record(); if ($db->f("cnt")) { $err->raise("ftp",_("This FTP account already exists")); return false; } $absolute=getuserpath()."/$dir"; if (!file_exists($absolute)) { system("/bin/mkdir -p $absolute"); } if (!is_dir($absolute)) { $err->raise("ftp",_("The directory cannot be created")); return false; } if (trim($pass)) { // Check this password against the password policy using common API : if (is_callable(array($admin,"checkPolicy"))) { if (!$admin->checkPolicy("ftp",$prefixe.$login,$pass)) { return false; // The error has been raised by checkPolicy() } } $encrypted_password = crypt($pass,strrev(microtime(true))); $db->query("UPDATE ftpusers SET name='".$prefixe.$login."', password='', encrypted_password='$encrypted_password', homedir='$absolute', uid='$cuid' WHERE id='$id';"); } else { $db->query("UPDATE ftpusers SET name='".$prefixe.$login."', homedir='$absolute', uid='$cuid' WHERE id='$id';"); } return true; } /* ----------------------------------------------------------------- */ /** Efface le compte ftp spécifié. * @param integer $id Numéro du compte FTP à supprimer. * @return boolean TRUE si le compte a été effacé, FALSE sinon. */ function delete_ftp($id) { global $db,$err,$cuid; $err->log("ftp","delete_ftp",$id); $db->query("SELECT name FROM ftpusers WHERE id='$id' and uid='$cuid';"); $db->next_record(); $name=$db->f("name"); if (!$name) { $err->raise("ftp",_("This FTP account does not exist")); return false; } $db->query("DELETE FROM ftpusers WHERE id='$id'"); return $name; } /* ----------------------------------------------------------------- */ /** Crée un nouveau compte FTP. * @param string $prefixe Prefixe au login * @param string $login Login ftp (login=prefixe_login) * @param string $pass Mot de passe FTP * @param string $dir Répertoire racine du compte relatif à la racine du membre * @return boolean TRUE si le compte a été créé, FALSE sinon. * */ function add_ftp($prefixe,$login,$pass,$dir) { global $mem,$db,$err,$quota,$bro,$cuid,$admin; $err->log("ftp","add_ftp",$prefixe."_".$login); $dir=$bro->convertabsolute($dir); if (substr($dir,0,1)=="/") { $dir=substr($dir,1); } $r=$this->prefix_list(); if (!in_array($prefixe,$r) || $prefixe=="") { $err->raise("ftp",_("The chosen prefix is not allowed")); return false; } if ($login) $login="_".$login; $db->query("SELECT count(*) AS cnt FROM ftpusers WHERE name='".$prefixe.$login."'"); $db->next_record(); if ($db->f("cnt")) { $err->raise("ftp",_("This FTP account already exists")); return false; } $db->query("SELECT login FROM membres WHERE uid='$cuid';"); $db->next_record(); $lo=$db->f("login"); $l=substr($lo,0,1); $absolute=getuserpath()."/$dir"; if (!file_exists($absolute)) { system("/bin/mkdir -p $absolute"); } if (!is_dir($absolute)) { $err->raise("ftp",_("The directory cannot be created")); return false; } // Check this password against the password policy using common API : if (is_callable(array($admin,"checkPolicy"))) { if (!$admin->checkPolicy("ftp",$prefixe.$login,$pass)) { return false; // The error has been raised by checkPolicy() } } if ($quota->cancreate("ftp")) { $encrypted_password = crypt($pass,strrev(microtime(true))); $db->query("INSERT INTO ftpusers (name,password, encrypted_password,homedir,uid) VALUES ('".$prefixe.$login."', '', '$encrypted_password', '$absolute', '$cuid')"); return true; } else { $err->raise("ftp",_("Your FTP account quota is over. You cannot create more ftp accounts")); return false; } } /* ----------------------------------------------------------------- */ /** Retourne TRUE si $dir possède un compte FTP * @param string $dir Dossier à tester, relatif à la racine du compte courant * @return boolean retourne TRUE si $dir à un compte FTP, FALSE sinon. */ function is_ftp($dir) { global $mem,$db,$err; $err->log("ftp","is_ftp",$dir); $lo=$mem->user["login"]; $l=substr($lo,0,1); if (substr($dir,0,1)=="/") $dir=substr($dir,1); $db->query("SELECT id FROM ftpusers WHERE homedir='".getuserpath()."/$dir';"); if ($db->num_rows()) { $db->next_record(); return $db->f("id"); } else { return false; } } /* ----------------------------------------------------------------- */ /** Fonction appellée par domains quand un deomaine est supprimé pour le membre * @param string $dom Domaine à détruire. * @access private */ function alternc_del_domain($dom) { global $db,$err,$cuid; $err->log("ftp","del_dom",$dom); $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE uid='$cuid' AND name LIKE '$dom%'"); $db->next_record(); $cnt=$db->Record["cnt"]; $db->query("DELETE FROM ftpusers WHERE uid='$cuid' AND name LIKE '$dom%'"); return true; } /* ----------------------------------------------------------------- */ /** Fonction appellée par membres quand un membre est effacé. * @param integer $uid Numéro de membre effacé. * @access private */ function alternc_del_member() { global $db,$err,$cuid; $err->log("ftp","del_member"); $db->query("DELETE FROM ftpusers WHERE uid='$cuid'"); return true; } /* ----------------------------------------------------------------- */ /** * Returns the used quota for the $name service for the current user. * @param $name string name of the quota * @return integer the number of service used or false if an error occured * @access private */ function hook_quota_get() { global $db,$err,$cuid; $err->log("ftp","getquota"); $q=Array("name"=>"ftp", "description"=>_("FTP accounts"), "used"=>0); $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE uid='$cuid'"); if ($db->next_record()) { $q['used']=$db->f("cnt"); } return $q; } /* ----------------------------------------------------------------- */ /** * Exporte toutes les informations ftp du compte AlternC * @access private * EXPERIMENTAL 'sid' function ;) */ function alternc_export_conf() { global $db,$err; $err->log("ftp","export"); $f=$this->get_list(); $str=" "; foreach ($f as $d=>$v) { $str.=" ".($v["login"])."\n"; $str.=" ".($v["encrypted_password"])."\n"; $str.=" ".($v["dir"])."\n"; } $str.=" \n"; return $str; } /* ----------------------------------------------------------------- */ /** hook function called by AlternC-upnp to know which open * tcp or udp ports this class requires or suggests * @return array a key => value list of port protocol name mandatory values * @access private */ function hook_upnp_list() { return array( "ftp" => array("port" => 21, "protocol" => "tcp", "mandatory" => 1), ); } } /* Class m_ftp */