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

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. <?
  2. $ssha=function($pw){
  3. if (!in_array(strtolower(substr($pw, 0, 5)), array('{ssha', '{cryp', '{sha}',))){
  4. $salt = substr(md5(uniqid(mt_rand(), true)), 0, 4);
  5. return '{SSHA}'.base64_encode( sha1( $pw . $salt, true) . $salt );
  6. }
  7. return $pw;
  8. };
  9. class LdapAdapter{
  10. function __construct($host, $port, $user, $pass){
  11. $this->conn = ldap_connect($host,$port);
  12. ldap_set_option($this->conn, LDAP_OPT_PROTOCOL_VERSION, 3);
  13. $this->bind_status = ldap_bind($this->conn, $user, $pass);
  14. }
  15. function get_bind_status(){
  16. return $this->bind_status;
  17. }
  18. function bind($host, $port, $user, $pass){
  19. $conn = ldap_connect($host,$port);
  20. ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
  21. return ldap_bind($conn, $user, $pass);
  22. }
  23. function get_ldap_attr($dn, $attr){
  24. # $search = ldap_search($this->conn, $dn, "$attr=*", array($attr));
  25. $dn_array=ldap_explode_dn($dn, 0);
  26. $new_dn=array();
  27. for ($i=1; $i<$dn_array['count']; $i++){
  28. $new_dn[]=$dn_array[$i];
  29. }
  30. $search=ldap_search($this->conn, implode(',', $new_dn), $dn_array[0]);
  31. if (ldap_count_entries($this->conn, $search)==0){
  32. return Null;
  33. }
  34. $entry = ldap_first_entry($this->conn, $search);
  35. return ldap_get_values ($this->conn, $entry, $attr);
  36. }
  37. function get_ldap_attr_max($dn, $attr){
  38. $search = ldap_search($this->conn, $dn, "$attr=*", array($attr));
  39. $entry = ldap_first_entry($this->conn, $search);
  40. $max=0;
  41. while( $entry){
  42. $tmp=ldap_get_values ($this->conn, $entry, $attr)[0];
  43. if ($tmp>$max){
  44. $max=$tmp;
  45. }
  46. $entry = ldap_next_entry($this->conn, $search);
  47. }
  48. return $max;
  49. }
  50. function add_ldap_obj($dn, $obj){
  51. return ldap_add($this->conn, $dn, $obj);
  52. }
  53. function exist_ldap_obj($dn){
  54. $dn_array=ldap_explode_dn($dn, 0);
  55. $new_dn=array();
  56. for ($i=1; $i<$dn_array['count']; $i++){
  57. $new_dn[]=$dn_array[$i];
  58. }
  59. $search=ldap_search($this->conn, implode(',', $new_dn), $dn_array[0]);
  60. if (ldap_count_entries($this->conn, $search)==0){
  61. return False;
  62. }
  63. return True;
  64. }
  65. function set_ldap_attr($dn, $attr, $value){
  66. return ldap_modify($this->conn, $dn , array($attr=>$value));
  67. }
  68. }
  69. abstract class Adapter{
  70. function __construct($dn){
  71. $this->dn = $dn;
  72. $this->setters = array();
  73. $this->getters = array();
  74. }
  75. function add_getter($attr, $fn = Null){
  76. if (array_key_exists($attr, $this->getters)){
  77. $this->getters[$attr][]= $fn;
  78. }else{
  79. $this->getters[$attr] = array($fn);
  80. }
  81. }
  82. function add_setter($attr, $fn = Null){
  83. if (array_key_exists($attr, $this->setters)){
  84. $this->setters[$attr][]= $fn;
  85. }else{
  86. $this->setters[$attr] = array($fn);
  87. }
  88. }
  89. function get_attr($la, $username, $attr){
  90. if (array_key_exists($attr, $this->getters)){
  91. foreach ($this->getters[$attr] as $getter){
  92. $result=$la->get_ldap_attr(sprintf($this->dn, $username), $attr);
  93. if ($getter != Null)
  94. return $getter($result);
  95. return $result;
  96. }
  97. }
  98. return Null;
  99. }
  100. function set_attr($la, $username, $attr, $value){
  101. $done=False;
  102. if (array_key_exists($attr, $this->setters)){
  103. $done=True;
  104. foreach ($this->setters[$attr] as $setter){
  105. if ($setter != Null)
  106. $value=$setter($value);
  107. $la->set_ldap_attr(sprintf($this->dn, $username), $attr, $value);
  108. }
  109. }
  110. return $done;
  111. }
  112. function get_attributes(){
  113. $attributes=array();
  114. foreach ($this->setters as $setter => $value)
  115. $attributes[]=$setter;
  116. return $attributes;
  117. }
  118. function exist($la, $username){
  119. if ($la->exist_ldap_obj(sprintf($this->dn, $username))){
  120. return True;
  121. }
  122. return False;
  123. }
  124. function bind($username, $password){
  125. global $HOST, $PORT, $LOGIN_DN;
  126. return LdapAdapter::bind($HOST, $PORT, sprintf($this->dn,$username), $password);
  127. }
  128. }
  129. class MailAdapter extends Adapter{
  130. function __construct($dn){
  131. global $ssha;
  132. parent::__construct($dn);
  133. $this->add_getter('mail', function($x){return $x[0];}); # function($x){return substr($x, strlen("@lilik.it")*-1);}
  134. $this->add_setter('mail'); # function($x){return $x[0]."@lilik.it";}
  135. $this->add_getter('cn', function($x){return $x[0];});
  136. $this->add_setter('cn');
  137. $this->add_getter('userPassword', function($x){return $x[0];});
  138. $this->add_setter('userPassword', $ssha);
  139. $this->add_getter('accountActive', function($x){return $x[0];});
  140. $this->add_setter('accountActive');
  141. }
  142. function create($la, $id, $name, $surname, $password){
  143. global $ssha;
  144. $new_mail_obj=['cn'=> [sprintf('%s %s',$name,$surname)],
  145. 'accountActive'=> ['FALSE'],
  146. 'objectClass'=> ['top', 'VirtualMailAccount', 'Vacation', 'VirtualForward', 'amavisAccount'],
  147. 'smtpAuth'=> ['FALSE'],
  148. 'mailAutoreply'=> [sprintf('%s@lilik.it.autoreply',$id)],
  149. 'uid'=> [sprintf('%s.lilik.it',$id)],
  150. 'vacationEnd'=> ['200701010000'],
  151. 'userPassword'=> [$ssha($password)],
  152. 'amavisBypassSpamChecks'=> ['FALSE'],
  153. 'amavisSpamTagLevel'=> ['3.0'],
  154. 'otherTransport'=> ['phamm=>'],
  155. 'vacationInfo'=> ['vacation'],
  156. 'mail'=> [sprintf('%s@lilik.it',$id)],
  157. 'vacationStart'=> ['200701010000'],
  158. 'vacationActive'=> ['FALSE'],
  159. 'amavisSpamTag2Level'=> ['5.5'],
  160. 'vdHome'=> [sprintf('/home/mail_deliver/lilik.it/%s',$id)],
  161. 'quota'=> ['1024000'],
  162. 'mailbox'=> [sprintf('lilik.it/%s/',$id)],
  163. 'forwardActive'=> ['FALSE'],
  164. 'amavisBypassVirusChecks'=> ['FALSE'],
  165. 'sn'=> [sprintf('%s',$surname)],
  166. 'amavisSpamKillLevel'=> ['6.0'],
  167. 'givenName'=> [sprintf('%s',$name)],
  168. 'delete'=> ['FALSE'],
  169. 'lastChange'=> [sprintf('%d',time())]
  170. ];
  171. return $la->add_ldap_obj(sprintf($this->dn,$id),$new_mail_obj);
  172. }
  173. }
  174. class PosixAdapter extends Adapter{
  175. function __construct($dn){
  176. global $ssha;
  177. parent::__construct($dn);
  178. $this->add_getter('cn', function($x){return $x[0];});
  179. $this->add_setter('cn');
  180. $this->add_getter('host');
  181. $this->add_setter('host');
  182. $this->add_getter('userPassword', function($x){return $x[0];});
  183. $this->add_setter('userPassword', $ssha);
  184. $this->add_getter('memberOf');
  185. $this->add_setter('memberOf');
  186. }
  187. function create($la, $id, $name, $surname, $password){
  188. global $ssha;
  189. $new_posix_obj=['uid'=> [sprintf('%s',$id)],
  190. 'objectClass'=> ['top', 'shadowAccount', 'posixAccount', 'account'],
  191. 'loginShell'=> ['/bin/bash'],
  192. 'userPassword'=> [$ssha($password)],
  193. 'uidNumber'=> [$la->get_ldap_attr_max('o=People,dc=lilik,dc=it', 'uidNumber')],
  194. 'host'=> ['*'],
  195. 'gidNumber'=> ['9000'], #stdusers
  196. 'homeDirectory'=> [sprintf('/home/%s',$id)],
  197. 'cn'=> [sprintf('%s %s',$name,$surname)],
  198. ];
  199. return $la->add_ldap_obj(sprintf($this->dn,$id),$new_posix_obj);
  200. }
  201. }
  202. class GroupAdapter extends Adapter{
  203. function __construct($dn){
  204. parent::__construct($dn);
  205. $this->add_getter('member');
  206. $this->add_setter('member');
  207. $this->add_getter('memberUid');
  208. $this->add_setter('memberUid');
  209. }
  210. }
  211. abstract class pippo{
  212. function __construct($id){
  213. global $HOST, $PORT, $LOGIN_DN, $LOGIN_PASS;
  214. $this->id=$id;
  215. $this->la=new LdapAdapter($HOST, $PORT, $LOGIN_DN, $LOGIN_PASS);
  216. }
  217. function get_bind_status(){
  218. return $this->la->get_bind_status();
  219. }
  220. function get_attr($attr){
  221. foreach($this->adapters as $adapter){
  222. $result=$adapter->get_attr($this->la, $this->id, $attr);
  223. if ($result!=Null)
  224. return $result;
  225. }
  226. return Null;
  227. }
  228. function set_attr($attr, $value){
  229. $result=False;
  230. foreach($this->adapters as $adapter){
  231. if ($adapter->set_attr($this->la, $this->id, $attr, $value)){
  232. $result=True;
  233. }
  234. }
  235. return $result;
  236. }
  237. function add_in_list($attr, $value){
  238. $tmp=$this->get_attr($attr);
  239. if (in_array($value, $tmp)){
  240. return True;
  241. }
  242. $tmp[]=$value;
  243. unset($tmp['count']);
  244. if ($this->set_attr($attr, $tmp)){
  245. return True;
  246. }
  247. return False;
  248. }
  249. function del_in_list($attr, $value){
  250. $tmp=$this->get_attr($attr);
  251. if (!in_array($value, $tmp)){
  252. return True;
  253. }
  254. if(($key = array_search($value, $tmp)) !== false) {
  255. unset($tmp[$key]);
  256. }
  257. unset($tmp['count']);
  258. $tmp=array_values($tmp);
  259. if ($this->set_attr($attr, $tmp)){
  260. return True;
  261. }
  262. return False;
  263. }
  264. function exist(){
  265. foreach ($this->adapters as $adapter){
  266. if ($adapter->exist($this->la, $this->id)){
  267. return True;
  268. }
  269. }
  270. return False;
  271. }
  272. function check_password($password){
  273. foreach ($this->adapters as $adapter)
  274. if ($adapter->bind($this->id, $password))
  275. return True;
  276. return False;
  277. }
  278. }
  279. class LilikGroup extends pippo{
  280. function __construct($id, $is_posix=False){
  281. global $HOST, $PORT, $LOGIN_DN;
  282. parent::__construct($id);
  283. $this->adapters=[new GroupAdapter("cn=%s,o=Group,dc=lilik,dc=it")];
  284. $this->is_posix=$is_posix;
  285. if ($is_posix){
  286. $this->member_attr="memberUid";
  287. }else{
  288. $this->member_attr="member";
  289. }
  290. }
  291. function get_id($user){
  292. if ($this->is_posix){
  293. return $user->id;
  294. }else{
  295. return sprintf($user->adapters[1]->dn,$user->id);
  296. }
  297. }
  298. function add_user($user){
  299. return $this->add_in_list($this->member_attr, $this->get_id($user));
  300. }
  301. function del_user($user){
  302. return $this->del_in_list($this->member_attr, $this->get_id($user));
  303. }
  304. function is_user($user){
  305. if (in_array($this->get_id($user), $this->get_attr($this->member_attr))){
  306. return True;
  307. }
  308. return False;
  309. }
  310. }
  311. class LilikUser extends pippo{
  312. function __construct($id){
  313. parent::__construct($id);
  314. $this->adapters=array(new MailAdapter("mail=%s@lilik.it,vd=lilik.it,o=hosting,dc=lilik,dc=it"),
  315. new PosixAdapter("uid=%s,o=People,dc=lilik,dc=it"));
  316. $this->_flag=array('mail'=>'accountActive');
  317. $this->_host=array('ltsp'=>'ltsp',
  318. 'users'=>'users');
  319. $this->_member=array('admin'=>'admin',
  320. 'wiki'=>'wiki',
  321. 'lilik.it'=>'lilik.it',
  322. 'cloud'=>'cloud',
  323. 'projects'=>'projects',
  324. 'teambox'=>'teambox',
  325. 'im'=>'im'
  326. );
  327. $this->_posix_member=array('users_sites'=>'users_sites');
  328. if ($this->exist()){
  329. $this->sanitize();
  330. }
  331. }
  332. function is_admin(){
  333. return $this->status('admin');
  334. }
  335. function is_binded(){
  336. }
  337. function enable($service){
  338. if (array_key_exists($service, $this->_flag)){
  339. return $this->set_attr($this->_flag[$service], 'TRUE');
  340. }elseif (array_key_exists($service, $this->_host)){
  341. return $this->add_in_list('host', $this->_host[$service]);
  342. }elseif (array_key_exists($service, $this->_member)){
  343. $l=new LilikGroup($this->_member[$service]);
  344. return $l->add_user($this);
  345. }elseif (array_key_exists($service, $this->_posix_member)){
  346. $l=new LilikGroup($this->_posix_member[$service], True);
  347. return $l->add_user($this);
  348. }else{
  349. throw new Exception("Service not found");
  350. }
  351. }
  352. function disable($service){
  353. if (array_key_exists($service, $this->_flag)){
  354. return $this->set_attr($this->_flag[$service], 'FALSE');
  355. }elseif (array_key_exists($service, $this->_host)){
  356. return $this->del_in_list('host', $this->_host[$service]);
  357. }elseif (array_key_exists($service, $this->_member)){
  358. $l=new LilikGroup($this->_member[$service]);
  359. return $l->del_user($this);
  360. }elseif (array_key_exists($service, $this->_posix_member)){
  361. $l=new LilikGroup($this->_posix_member[$service], True);
  362. return $l->del_user($this);
  363. }else{
  364. throw new Exception("Service not found");
  365. }
  366. }
  367. function status($service){
  368. if (array_key_exists($service, $this->_flag)){
  369. if ($this->get_attr($this->_flag[$service])=='TRUE'){
  370. return True;
  371. }
  372. return False;
  373. }elseif (array_key_exists($service, $this->_host)){
  374. if (in_array($this->_host[$service], $this->get_attr("host"))){
  375. return True;
  376. }
  377. return False;
  378. }elseif (array_key_exists($service, $this->_member)){
  379. $l=new LilikGroup($this->_member[$service]);
  380. return $l->is_user($this);
  381. }elseif (array_key_exists($service, $this->_posix_member)){
  382. $l=new LilikGroup($this->_posix_member[$service], True);
  383. return $l->is_user($this);
  384. }else{
  385. throw new Exception("Service not found");
  386. }
  387. }
  388. function get_attributes(){
  389. $attributes=array();
  390. foreach ($this->adapters as $adapter)
  391. $attributes+= $adapter->get_attributes();
  392. return $attributes;
  393. }
  394. function get_services(){
  395. $services=array();
  396. foreach (array($this->_flag, $this->_host, $this->_member, $this->_posix_member) as $k)
  397. foreach ($k as $x => $value)
  398. $services[]= $x;
  399. return $services;
  400. }
  401. function get_enabled_services(){
  402. $enabled_services=array();
  403. foreach ($this->get_services() as $service){
  404. if ($this->status($service)){
  405. $enabled_services[]=$service;
  406. }
  407. }
  408. return $enabled_services;
  409. }
  410. function sanitize(){
  411. $tmp=explode(' ', $this->get_attr('cn'), 2);
  412. if (count($tmp) > 1){
  413. $name=$tmp[0];
  414. $surname=$tmp[1];
  415. }else{
  416. $name=$this->get_attr('cn');
  417. $surname='';
  418. }
  419. return $this->create($name, $surname, $this->get_attr('userPassword'));
  420. }
  421. function create($name, $surname, $password){
  422. $result=True;
  423. foreach ($this->adapters as $adapter){
  424. if (!$adapter->exist($this->la, $this->id)){
  425. if (!$adapter->create($this->la, $this->id, $name, $surname, $password)){
  426. $result=False;
  427. }
  428. }
  429. }
  430. return $result;
  431. }
  432. }