You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

500 lines
13 KiB

<?
$ssha=function($pw){
if (!in_array(strtolower(substr($pw, 0, 5)), array('{ssha', '{cryp', '{sha}',))){
$salt = substr(md5(uniqid(mt_rand(), true)), 0, 4);
return '{SSHA}'.base64_encode( sha1( $pw . $salt, true) . $salt );
}
return $pw;
};
class LdapAdapter{
function __construct($host, $port, $user, $pass){
$this->conn = ldap_connect($host,$port);
ldap_set_option($this->conn, LDAP_OPT_PROTOCOL_VERSION, 3);
$this->bind_status = ldap_bind($this->conn, $user, $pass);
}
function get_bind_status(){
return $this->bind_status;
}
function bind($host, $port, $user, $pass){
$conn = ldap_connect($host,$port);
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
return ldap_bind($conn, $user, $pass);
}
function get_ldap_attr($dn, $attr){
# $search = ldap_search($this->conn, $dn, "$attr=*", array($attr));
$dn_array=ldap_explode_dn($dn, 0);
$new_dn=array();
for ($i=1; $i<$dn_array['count']; $i++){
$new_dn[]=$dn_array[$i];
}
$search=ldap_search($this->conn, implode(',', $new_dn), $dn_array[0]);
if (ldap_count_entries($this->conn, $search)==0){
return Null;
}
$entry = ldap_first_entry($this->conn, $search);
return ldap_get_values ($this->conn, $entry, $attr);
}
function get_ldap_attr_max($dn, $attr){
$search = ldap_search($this->conn, $dn, "$attr=*", array($attr));
$entry = ldap_first_entry($this->conn, $search);
$max=0;
while( $entry){
$tmp=ldap_get_values ($this->conn, $entry, $attr)[0];
if ($tmp>$max){
$max=$tmp;
}
$entry = ldap_next_entry($this->conn, $search);
}
return $max;
}
function add_ldap_obj($dn, $obj){
return ldap_add($this->conn, $dn, $obj);
}
function exist_ldap_obj($dn){
$dn_array=ldap_explode_dn($dn, 0);
$new_dn=array();
for ($i=1; $i<$dn_array['count']; $i++){
$new_dn[]=$dn_array[$i];
}
$search=ldap_search($this->conn, implode(',', $new_dn), $dn_array[0]);
if (ldap_count_entries($this->conn, $search)==0){
return False;
}
return True;
}
function set_ldap_attr($dn, $attr, $value){
return ldap_modify($this->conn, $dn , array($attr=>$value));
}
}
abstract class Adapter{
function __construct($dn){
$this->dn = $dn;
$this->setters = array();
$this->getters = array();
}
function add_getter($attr, $fn = Null){
if (array_key_exists($attr, $this->getters)){
$this->getters[$attr][]= $fn;
}else{
$this->getters[$attr] = array($fn);
}
}
function add_setter($attr, $fn = Null){
if (array_key_exists($attr, $this->setters)){
$this->setters[$attr][]= $fn;
}else{
$this->setters[$attr] = array($fn);
}
}
function get_attr($la, $username, $attr){
if (array_key_exists($attr, $this->getters)){
foreach ($this->getters[$attr] as $getter){
$result=$la->get_ldap_attr(sprintf($this->dn, $username), $attr);
if ($getter != Null)
return $getter($result);
return $result;
}
}
return Null;
}
function set_attr($la, $username, $attr, $value){
$done=False;
if (array_key_exists($attr, $this->setters)){
$done=True;
foreach ($this->setters[$attr] as $setter){
if ($setter != Null)
$value=$setter($value);
$la->set_ldap_attr(sprintf($this->dn, $username), $attr, $value);
}
}
return $done;
}
function get_attributes(){
$attributes=array();
foreach ($this->setters as $setter => $value)
$attributes[]=$setter;
return $attributes;
}
function exist($la, $username){
if ($la->exist_ldap_obj(sprintf($this->dn, $username))){
return True;
}
return False;
}
function bind($username, $password){
global $HOST, $PORT, $LOGIN_DN;
return LdapAdapter::bind($HOST, $PORT, sprintf($this->dn,$username), $password);
}
}
class MailAdapter extends Adapter{
function __construct($dn){
global $ssha;
parent::__construct($dn);
$this->add_getter('mail', function($x){return $x[0];}); # function($x){return substr($x, strlen("@lilik.it")*-1);}
$this->add_setter('mail'); # function($x){return $x[0]."@lilik.it";}
$this->add_getter('cn', function($x){return $x[0];});
$this->add_setter('cn');
$this->add_getter('userPassword', function($x){return $x[0];});
$this->add_setter('userPassword', $ssha);
$this->add_getter('accountActive', function($x){return $x[0];});
$this->add_setter('accountActive');
}
function create($la, $id, $name, $surname, $password){
global $ssha;
$new_mail_obj=['cn'=> [sprintf('%s %s',$name,$surname)],
'accountActive'=> ['FALSE'],
'objectClass'=> ['top', 'VirtualMailAccount', 'Vacation', 'VirtualForward', 'amavisAccount'],
'smtpAuth'=> ['FALSE'],
'mailAutoreply'=> [sprintf('%s@lilik.it.autoreply',$id)],
'uid'=> [sprintf('%s.lilik.it',$id)],
'vacationEnd'=> ['200701010000'],
'userPassword'=> [$ssha($password)],
'amavisBypassSpamChecks'=> ['FALSE'],
'amavisSpamTagLevel'=> ['3.0'],
'otherTransport'=> ['phamm=>'],
'vacationInfo'=> ['vacation'],
'mail'=> [sprintf('%s@lilik.it',$id)],
'vacationStart'=> ['200701010000'],
'vacationActive'=> ['FALSE'],
'amavisSpamTag2Level'=> ['5.5'],
'vdHome'=> [sprintf('/home/mail_deliver/lilik.it/%s',$id)],
'quota'=> ['1024000'],
'mailbox'=> [sprintf('lilik.it/%s/',$id)],
'forwardActive'=> ['FALSE'],
'amavisBypassVirusChecks'=> ['FALSE'],
'sn'=> [sprintf('%s',$surname)],
'amavisSpamKillLevel'=> ['6.0'],
'givenName'=> [sprintf('%s',$name)],
'delete'=> ['FALSE'],
'lastChange'=> [sprintf('%d',time())]
];
return $la->add_ldap_obj(sprintf($this->dn,$id),$new_mail_obj);
}
}
class PosixAdapter extends Adapter{
function __construct($dn){
global $ssha;
parent::__construct($dn);
$this->add_getter('cn', function($x){return $x[0];});
$this->add_setter('cn');
$this->add_getter('host');
$this->add_setter('host');
$this->add_getter('userPassword', function($x){return $x[0];});
$this->add_setter('userPassword', $ssha);
$this->add_getter('memberOf');
$this->add_setter('memberOf');
}
function create($la, $id, $name, $surname, $password){
global $ssha;
$new_posix_obj=['uid'=> [sprintf('%s',$id)],
'objectClass'=> ['top', 'shadowAccount', 'posixAccount', 'account'],
'loginShell'=> ['/bin/bash'],
'userPassword'=> [$ssha($password)],
'uidNumber'=> [$la->get_ldap_attr_max('o=People,dc=lilik,dc=it', 'uidNumber')],
'host'=> ['*'],
'gidNumber'=> ['9000'], #stdusers
'homeDirectory'=> [sprintf('/home/%s',$id)],
'cn'=> [sprintf('%s %s',$name,$surname)],
];
return $la->add_ldap_obj(sprintf($this->dn,$id),$new_posix_obj);
}
}
class GroupAdapter extends Adapter{
function __construct($dn){
parent::__construct($dn);
$this->add_getter('member');
$this->add_setter('member');
$this->add_getter('memberUid');
$this->add_setter('memberUid');
}
}
abstract class pippo{
function __construct($id){
global $HOST, $PORT, $LOGIN_DN, $LOGIN_PASS;
$this->id=$id;
$this->la=new LdapAdapter($HOST, $PORT, $LOGIN_DN, $LOGIN_PASS);
}
function get_bind_status(){
return $this->la->get_bind_status();
}
function get_attr($attr){
foreach($this->adapters as $adapter){
$result=$adapter->get_attr($this->la, $this->id, $attr);
if ($result!=Null)
return $result;
}
return Null;
}
function set_attr($attr, $value){
$result=False;
foreach($this->adapters as $adapter){
if ($adapter->set_attr($this->la, $this->id, $attr, $value)){
$result=True;
}
}
return $result;
}
function add_in_list($attr, $value){
$tmp=$this->get_attr($attr);
if (in_array($value, $tmp)){
return True;
}
$tmp[]=$value;
unset($tmp['count']);
if ($this->set_attr($attr, $tmp)){
return True;
}
return False;
}
function del_in_list($attr, $value){
$tmp=$this->get_attr($attr);
if (!in_array($value, $tmp)){
return True;
}
if(($key = array_search($value, $tmp)) !== false) {
unset($tmp[$key]);
}
unset($tmp['count']);
$tmp=array_values($tmp);
if ($this->set_attr($attr, $tmp)){
return True;
}
return False;
}
function exist(){
foreach ($this->adapters as $adapter){
if ($adapter->exist($this->la, $this->id)){
return True;
}
}
return False;
}
function check_password($password){
foreach ($this->adapters as $adapter)
if ($adapter->bind($this->id, $password))
return True;
return False;
}
}
class LilikGroup extends pippo{
function __construct($id, $is_posix=False){
global $HOST, $PORT, $LOGIN_DN;
parent::__construct($id);
$this->adapters=[new GroupAdapter("cn=%s,o=Group,dc=lilik,dc=it")];
$this->is_posix=$is_posix;
if ($is_posix){
$this->member_attr="memberUid";
}else{
$this->member_attr="member";
}
}
function get_id($user){
if ($this->is_posix){
return $user->id;
}else{
return sprintf($user->adapters[1]->dn,$user->id);
}
}
function add_user($user){
return $this->add_in_list($this->member_attr, $this->get_id($user));
}
function del_user($user){
return $this->del_in_list($this->member_attr, $this->get_id($user));
}
function is_user($user){
if (in_array($this->get_id($user), $this->get_attr($this->member_attr))){
return True;
}
return False;
}
}
class LilikUser extends pippo{
function __construct($id){
parent::__construct($id);
$this->adapters=array(new MailAdapter("mail=%s@lilik.it,vd=lilik.it,o=hosting,dc=lilik,dc=it"),
new PosixAdapter("uid=%s,o=People,dc=lilik,dc=it"));
$this->_flag=array('mail'=>'accountActive');
$this->_host=array('ltsp'=>'ltsp',
'users'=>'users');
$this->_member=array('admin'=>'admin',
'wiki'=>'wiki',
'lilik.it'=>'lilik.it',
'cloud'=>'cloud',
'projects'=>'projects',
'teambox'=>'teambox',
'im'=>'im'
);
$this->_posix_member=array('users_sites'=>'users_sites');
if ($this->exist()){
$this->sanitize();
}
}
function is_admin(){
return $this->status('admin');
}
function is_binded(){
}
function enable($service){
if (array_key_exists($service, $this->_flag)){
return $this->set_attr($this->_flag[$service], 'TRUE');
}elseif (array_key_exists($service, $this->_host)){
return $this->add_in_list('host', $this->_host[$service]);
}elseif (array_key_exists($service, $this->_member)){
$l=new LilikGroup($this->_member[$service]);
return $l->add_user($this);
}elseif (array_key_exists($service, $this->_posix_member)){
$l=new LilikGroup($this->_posix_member[$service], True);
return $l->add_user($this);
}else{
throw new Exception("Service not found");
}
}
function disable($service){
if (array_key_exists($service, $this->_flag)){
return $this->set_attr($this->_flag[$service], 'FALSE');
}elseif (array_key_exists($service, $this->_host)){
return $this->del_in_list('host', $this->_host[$service]);
}elseif (array_key_exists($service, $this->_member)){
$l=new LilikGroup($this->_member[$service]);
return $l->del_user($this);
}elseif (array_key_exists($service, $this->_posix_member)){
$l=new LilikGroup($this->_posix_member[$service], True);
return $l->del_user($this);
}else{
throw new Exception("Service not found");
}
}
function status($service){
if (array_key_exists($service, $this->_flag)){
if ($this->get_attr($this->_flag[$service])=='TRUE'){
return True;
}
return False;
}elseif (array_key_exists($service, $this->_host)){
if (in_array($this->_host[$service], $this->get_attr("host"))){
return True;
}
return False;
}elseif (array_key_exists($service, $this->_member)){
$l=new LilikGroup($this->_member[$service]);
return $l->is_user($this);
}elseif (array_key_exists($service, $this->_posix_member)){
$l=new LilikGroup($this->_posix_member[$service], True);
return $l->is_user($this);
}else{
throw new Exception("Service not found");
}
}
function get_attributes(){
$attributes=array();
foreach ($this->adapters as $adapter)
$attributes+= $adapter->get_attributes();
return $attributes;
}
function get_services(){
$services=array();
foreach (array($this->_flag, $this->_host, $this->_member, $this->_posix_member) as $k)
foreach ($k as $x => $value)
$services[]= $x;
return $services;
}
function get_enabled_services(){
$enabled_services=array();
foreach ($this->get_services() as $service){
if ($this->status($service)){
$enabled_services[]=$service;
}
}
return $enabled_services;
}
function sanitize(){
$tmp=explode(' ', $this->get_attr('cn'), 2);
if (count($tmp) > 1){
$name=$tmp[0];
$surname=$tmp[1];
}else{
$name=$this->get_attr('cn');
$surname='';
}
return $this->create($name, $surname, $this->get_attr('userPassword'));
}
function create($name, $surname, $password){
$result=True;
foreach ($this->adapters as $adapter){
if (!$adapter->exist($this->la, $this->id)){
if (!$adapter->create($this->la, $this->id, $name, $surname, $password)){
$result=False;
}
}
}
return $result;
}
}