paste.org.ru Wed Nov  5 23:32:59 2014 : Anonymous : perl : 42760 wide : parent [ 11 years ]
cookies:
name:

scheme:

custom css:


tools:
custom css sample
paste bash script
more coming soon
or not soon...
last:

- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- kek

  1. #!/usr/bin/perl
  2. ########################################
  3. ### Хранит функции работы с системой ###
  4. ########################################
  5. package System;
  6. use strict;
  7. use warnings;
  8. use Conf;
  9. use File::Path qw(make_path);
  10. use File::Copy;
  11. use File::Read;
  12. use DBI;
  13. ##################################
  14. ### Функции для работы с linux ###
  15. ##################################
  16. # возвращает аптайм
  17. sub linux_get_uptime
  18. {
  19. my @uptime = split(/,/, `/usr/bin/uptime 2>/dev/null`, 3);
  20. $uptime[0] =~ s/^[\s]+//;
  21. chomp $uptime[2];
  22. return $uptime[0] . "," . $uptime[2];
  23. }
  24. # возвращает версию ядра
  25. sub linux_get_kernel_version
  26. {
  27. my $tmp = `/bin/uname -r -m`;
  28. chomp $tmp;
  29. return $tmp;
  30. }
  31. # возвращает hostname
  32. sub linux_get_hostname
  33. {
  34. my $tmp = `/bin/hostname -f 2>/dev/null`;
  35. chomp $tmp;
  36. return $tmp;
  37. }
  38. # возвращает информацию о свободном месте на примонтированых ext234 файловых системах
  39. sub linux_get_spaceinfo
  40. {
  41. my @tmp = `/bin/df 2>/dev/null -h -l -t ext4 -t ext3 -t ext2 | tail -n +2`;
  42. my $result = '';
  43. foreach (@tmp) {
  44. my @line = split /\s+/;
  45. $result .= $line[5] . ': ' . $line[3] . ', ';
  46. }
  47. $result =~ s/^(.*),/$1/i;
  48. return $result;
  49. }
  50. # возвращает информацию о памяти
  51. sub linux_get_usage
  52. {
  53. my @meminfo = `cat /proc/meminfo 2>/dev/null |egrep -i "memtotal|memfree|swaptotal|swapfree"`;
  54. my $result = '';
  55. my @tmp;
  56. @tmp = split /:\s+/, $meminfo[0];
  57. chomp $tmp[1];
  58. $tmp[1] =~ s/[\s]+//i;
  59. $result .= $tmp[1];
  60. @tmp = split /:\s+/, $meminfo[1];
  61. $tmp[1] =~ s/[\s]+//i;
  62. chomp $tmp[1];
  63. $result .= '/' . $tmp[1] . ', ';
  64. @tmp = split /:\s+/, $meminfo[2];
  65. $tmp[1] =~ s/[\s]+//i;
  66. chomp $tmp[1];
  67. $result .= $tmp[1];
  68. @tmp = split /:\s+/, $meminfo[3];
  69. $tmp[1] =~ s/[\s]+//i;
  70. chomp $tmp[1];
  71. $result .= '/' . $tmp[1];
  72. return $result;
  73. }
  74. # возвращает ip сервера для интерфейса
  75. sub linux_get_ip
  76. {
  77. my $server_ip = `/bin/ip 2>/dev/null addr show dev eth0 |grep inet |grep -v inet6`;
  78. my @server_ip = split /\s+/, $server_ip;
  79. if (defined($server_ip[2])) {
  80. $server_ip = (split /\//, $server_ip[2])[0];
  81. return $server_ip;
  82. } else {
  83. return '';
  84. }
  85. }
  86. # возвращает список пользователей
  87. sub linux_get_users
  88. {
  89. my %users;
  90. open my $fh, "<", "/etc/passwd"
  91. or Logger::warn('Manager: could not read /etc/passwd');
  92. while (<$fh>) {
  93. chomp;
  94. my @fields = split /:/;
  95. if (@fields && ($fields[2] >= 1000) && ($fields[2] <= 65000)) {
  96. $users{$fields[2]} = \@fields;
  97. }
  98. }
  99. close $fh;
  100. return %users;
  101. }
  102. # возвращает пользователя по id
  103. sub linux_get_user
  104. {
  105. my ($user_id) = @_;
  106. my @user;
  107. open my $fh, "<", "/etc/passwd"
  108. or Logger::warn('Manager: could not read /etc/passwd');
  109. while (<$fh>) {
  110. chomp;
  111. my @fields = split /:/;
  112. if (@fields && $user_id && ( $fields[2] eq $user_id ) ) {
  113. @user = @fields;
  114. last();
  115. }
  116. }
  117. close $fh;
  118. return @user;
  119. }
  120. # проверяет логин пользователя на свободность
  121. sub linux_login_free
  122. {
  123. my $login = shift();
  124. my $result = `cat /etc/passwd 2>/dev/null | egrep '^$login:'`;
  125. chomp $result;
  126. return ($result) ? 0 : 1;
  127. }
  128. # меняет пароль пользователю
  129. sub linux_passwd
  130. {
  131. my ($login, $password) = @_;
  132. # trim
  133. $login =~ s/^\s+//;
  134. $login =~ s/\s+$//;
  135. # проверяем длину
  136. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  137. if (length ($login) == 0);
  138. # проверяем длину
  139. return {'status' => 1, 'message' => 'User password length must be grater 0'}
  140. if (length ($password) == 0);
  141. # нет ли ещё такого пользователя
  142. my $usercounter = `cat /etc/passwd | egrep "^$login:" |wc -l`;
  143. chomp $usercounter;
  144. return {'status' => $?, 'message' => 'User NOT exists'}
  145. if ($usercounter == 0);
  146. # Меняем пароль
  147. my $cmd = '/bin/echo -e "' . $login . ':' . $password . '" | chpasswd -c SHA512';
  148. system($cmd);
  149. }
  150. # добавляет пользователя
  151. sub linux_add_user
  152. {
  153. my ($login, $password) = @_;
  154. # trim
  155. $login =~ s/^\s+//;
  156. $login =~ s/\s+$//;
  157. # проверяем длину
  158. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  159. if (length ($login) == 0);
  160. # проверяем формат
  161. return {'status' => 1, 'message' => 'Error in format of login (^[a-z][-a-z0-9_\.]*$)'}
  162. if ($login !~ m/^[a-z][-a-z0-9_\.]*$/);
  163. # проверяем длину
  164. return {'status' => 1, 'message' => 'User password length must be grater 0'}
  165. if (length ($password) == 0);
  166. # нет ли уже такого пользователя
  167. my $usercounter = `cat /etc/passwd | egrep "^$login:" |wc -l`;
  168. chomp $usercounter;
  169. return {'status' => $?, 'message' => 'User exists'}
  170. if ($usercounter > 0);
  171. my $salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
  172. my $phash = crypt($password, '$6$' . $salt . '$');
  173. $phash =~ s/\$/\\\$/g;
  174. my $add_result = system("/usr/sbin/useradd -d /var/www/$login -s /bin/false -m -p $phash $login 2>/dev/null");
  175. # нет ли ошибок при создании пользователя
  176. return {'status' => $add_result, 'message' => 'error adding user'}
  177. if ($add_result != 0);
  178. # создаем структуру каталогов
  179. make_path( '/var/www/' . $login . '/data',
  180. '/var/www/' . $login . '/data/www',
  181. '/var/www/' . $login . '/data/logs',
  182. '/var/www/' . $login . '/data/tmp', {
  183. mode => 0755,
  184. owner => $login,
  185. group => $login
  186. });
  187. return {'status' => 0, 'message' => 'User successfully created'};
  188. }
  189. # удаляет пользователя
  190. sub linux_del_user
  191. {
  192. my $login = shift();
  193. # trim
  194. $login =~ s/^\s+//;
  195. $login =~ s/\s+$//;
  196. # проверяем длину
  197. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  198. if (length ($login) == 0);
  199. # нет ли ещё такого пользователя
  200. my $usercounter = `cat /etc/passwd | egrep "^$login:" |wc -l`;
  201. chomp $usercounter;
  202. return {'status' => $?, 'message' => 'User NOT exists'}
  203. if ($usercounter == 0);
  204. return system("userdel -f $login");
  205. }
  206. # производит операции с сервисом linux
  207. sub linux_service
  208. {
  209. my ($daemon, $action) = @_;
  210. my $tmp = `/etc/init.d/$daemon $action 2>&1`;
  211. #возвращаем результат
  212. return {'status' => $?,
  213. 'message' => $tmp};
  214. }
  215. # производит операции с сервисом linux (утилитой service)
  216. sub linux_service2
  217. {
  218. my ($daemon, $action) = @_;
  219. my $tmp = `/usr/bin/service $daemon $action 2>&1`;
  220. #возвращаем результат
  221. return {'status' => $?,
  222. 'message' => $tmp};
  223. }
  224. ####################################
  225. ### Функции для работы с proftpd ###
  226. ####################################
  227. # получает список фтп пользователей из файла ftp пользователей
  228. sub linux_ftp_get_users
  229. {
  230. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  231. open(my $fh, '<', $ftp_passwd_file)
  232. or Logger::warn('Manager: could not read FTP passwd file');
  233. my @users;
  234. my %users;
  235. while (<$fh>) {
  236. chomp;
  237. push(@users, $_);
  238. my @fields = split /:/;
  239. $users{$fields[0]} = \@fields;
  240. }
  241. close($fh);
  242. return %users;
  243. }
  244. # проверяет логин пользователя на свободность
  245. sub linux_ftp_login_free
  246. {
  247. my $login = shift();
  248. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  249. open(my $fh, '<', $ftp_passwd_file)
  250. or Logger::warn('Manager: could not read FTP passwd file');
  251. my $user = '';
  252. while (<$fh>) {
  253. chomp;
  254. if (m/$login:/) {
  255. $user = $_;
  256. last();
  257. }
  258. }
  259. close($fh);
  260. return (length($user)) ? 0 : 1;
  261. }
  262. # добавляет фтп пользователя
  263. sub linux_ftp_add_user
  264. {
  265. my ($login, $passw, $owner_id, $homedir) = @_;
  266. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  267. # trim
  268. $login =~ s/^\s+//;
  269. $login =~ s/\s+$//;
  270. # проверяем длину
  271. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  272. if (length ($login) == 0);
  273. # проверяем формат
  274. return {'status' => 2, 'message' => 'Error in format of login (^[a-z][-a-z0-9_\.]*$)'}
  275. if ($login !~ m/^[a-z][-a-z0-9_\.]*$/);
  276. # проверяем длину
  277. return {'status' => 3, 'message' => 'User password length must be grater 0'}
  278. if (length ($passw) == 0);
  279. # если логин свободен
  280. if (linux_ftp_login_free($login))
  281. {
  282. my $salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
  283. my $phash = crypt($passw, '$6$' . $salt . '$');
  284. $homedir =~ s/^\///;
  285. my @user = linux_get_user($owner_id);
  286. if (@user) {
  287. $homedir = $user[5] . '/' . $homedir;
  288. # добавляем пользователя
  289. open(my $fh, '>>', $ftp_passwd_file)
  290. or Logger::warn('Manager: could not open FTP passwd file for write');
  291. my $userstr = $login . ":" . $phash . ":" . $owner_id . ":" . $owner_id . "::" . $homedir . ":/bin/false\n";
  292. print($fh $userstr);
  293. close($fh);
  294. # перезагружаем фтп сервер
  295. linux_service('proftpd', 'force-reload');
  296. # все ок
  297. return {'status' => 0, 'message' => 'User added'};
  298. } else {
  299. # id родителя указано не верно
  300. return {'status' => 4, 'message' => 'Owner user not found'};
  301. }
  302. } else {
  303. # логин уже занят
  304. return {'status' => $?, 'message' => 'User exists'};
  305. }
  306. }
  307. # удаляет пользователя из файла ftp аккаунтов
  308. sub linux_ftp_del_user
  309. {
  310. my $login = shift();
  311. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  312. # trim
  313. $login =~ s/^\s+//;
  314. $login =~ s/\s+$//;
  315. # проверяем длину
  316. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  317. if (length ($login) == 0);
  318. # есть ли такой пользователь
  319. return {'status' => 2, 'message' => 'User NOT exists'}
  320. if (linux_ftp_login_free($login));
  321. # читаем пользователей кроме искомого в массив
  322. open(my $fh, '<', $ftp_passwd_file)
  323. or Logger::warn('Manager: could not read FTP passwd file');
  324. my @users;
  325. while (<$fh>) {
  326. chomp;
  327. if ($_ !~ m/^$login:/) {
  328. push(@users, $_);
  329. }
  330. }
  331. close($fh);
  332. # создаем временный файл с пользователями
  333. open(my $fh2, '>', $ftp_passwd_file . ".tmp")
  334. or Logger::warn('Manager: could not open FTP passwd temp file ' . $ftp_passwd_file . ".tmp" . ' for write');
  335. foreach (@users)
  336. {
  337. print($fh2 $_ . "\n");
  338. }
  339. close($fh2);
  340. # копируем временный файл в реальный, а реальный предварительно бекапим
  341. copy($ftp_passwd_file, $ftp_passwd_file . '-');
  342. move($ftp_passwd_file . ".tmp", $ftp_passwd_file);
  343. # перезагружаем фтп сервер
  344. linux_service('proftpd', 'force-reload');
  345. # все ОК
  346. return {'status' => 0, 'message' => 'User deleted'}
  347. }
  348. # изменяет пароль пользователю
  349. sub linux_ftp_passwd
  350. {
  351. my ($login, $passw) = @_;
  352. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  353. # проверяем длину
  354. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  355. if (length ($login) == 0);
  356. # проверяем длину
  357. return {'status' => 2, 'message' => 'User password length must be grater 0'}
  358. if (length ($passw) == 0);
  359. # ищем пользователя
  360. my @found_user = linux_ftp_get_user($login);
  361. # удаляем пользователя и добавляем нового с новым паролем
  362. if (@found_user) {
  363. # удалим пользователя
  364. my $r = linux_ftp_del_user($login);
  365. return $r
  366. if ($r->{'status'} != 0);
  367. # добавим нового с новым паролем
  368. $r = linux_ftp_add_user($login, $passw, $found_user[2], $found_user[5]);
  369. return $r
  370. if ($r->{'status'} != 0);
  371. # перезагружаем фтп сервер
  372. linux_service('proftpd', 'force-reload');
  373. # все ок
  374. return {'status' => 0, 'message' => 'Password updated!'};
  375. } else {
  376. # пользователь для изменения пароля не найден
  377. return {'status' => 3, 'message' => 'User NOT exists'};
  378. }
  379. }
  380. # изменяет домашнюю директорию
  381. sub linux_ftp_homedir
  382. {
  383. my ($login, $homedir) = @_;
  384. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  385. # trim
  386. $login =~ s/^\s+//;
  387. $login =~ s/\s+$//;
  388. $homedir =~ s/^\///;
  389. # проверяем длину
  390. return {'status' => 1, 'message' => 'User login length must be grater 0'}
  391. if (length ($login) == 0);
  392. # ищем пользователя
  393. my @found_user = linux_ftp_get_user($login);
  394. # удаляем пользователя и добавляем нового с новым паролем
  395. if (@found_user)
  396. {
  397. # ищем владельца
  398. my @owner_user = linux_get_user($found_user[2]);
  399. if (@owner_user) {
  400. # удаляем пользователя
  401. my $r = linux_ftp_del_user($login);
  402. return $r
  403. if ($r->{'status'} != 0);
  404. # trim
  405. $owner_user[5] =~ s/\/$//;
  406. # добавим нового с новым паролем
  407. $r = linux_ftp_add_user($found_user[0], $found_user[1], $found_user[2], $homedir);
  408. return $r
  409. if ($r->{'status'} != 0);
  410. # перезагружаем фтп сервер
  411. linux_service('proftpd', 'force-reload');
  412. # все ок
  413. return {'status' => 0, 'message' => $owner_user[5] . '/' . $homedir};
  414. } else {
  415. # родительский пользователь не найден
  416. return {'status' => 4, 'message' => 'Owner user NOT exists'};
  417. }
  418. } else {
  419. # пользователь для изменения пароля не найден
  420. return {'status' => 3, 'message' => 'User NOT exists'};
  421. }
  422. }
  423. # получает фтп пользователя из файла users.txt по логину
  424. sub linux_ftp_get_user
  425. {
  426. my $login = shift();
  427. my $ftp_passwd_file = Conf::get('Manager.ftp_passwd_file');
  428. open(my $fh, '<', $ftp_passwd_file)
  429. or Logger::warn('Manager: could not read FTP passwd file');
  430. my $user;
  431. while (<$fh>) {
  432. chomp;
  433. if (m/$login:/) {
  434. $user = $_;
  435. last();
  436. }
  437. }
  438. close($fh);
  439. return split(/:/, $user);
  440. }
  441. ####################################
  442. ### Функции для работы с apache2 ###
  443. ####################################
  444. # возвращает все виртуалхосты
  445. sub apache2_vhost_get_all
  446. {
  447. my @sites_available = `ls /etc/apache2/sites-available/ 2>/dev/null`;
  448. chomp @sites_available;
  449. my %vhosts;
  450. foreach (@sites_available) {
  451. $vhosts{$_} = (-e '/etc/apache2/sites-available/' . $_) ? 1 : 0;
  452. }
  453. return %vhosts;
  454. }
  455. # возвращает все виртуалхосты для пользователя
  456. sub apache2_vhost_get_all_for_user
  457. {
  458. my ($user_id) = @_;
  459. my @sites_available = `ls /etc/apache2/sites-available/ 2>/dev/null | egrep -i "^_$user_id"`;
  460. chomp @sites_available;
  461. my %vhosts;
  462. foreach (@sites_available) {
  463. $vhosts{$_} = (-e '/etc/apache2/sites-available/' . $_) ? 1 : 0;
  464. }
  465. return %vhosts;
  466. }
  467. # получает параметры виртуалхоста
  468. sub apache2_vhost_get
  469. {
  470. my ($vhost_filename) = @_;
  471. return {} if (!apache2_vhost_exists($vhost_filename));
  472. # вначале читаем vhost в массив
  473. my @vhost_lines;
  474. open my $fh, "<", "/etc/apache2/sites-available/" . $vhost_filename
  475. or Logger::warn('Manager: could not read apache2 vhost file ' . "/etc/apache2/sites-available/" . $vhost_filename);
  476. while (<$fh>) {
  477. chomp;
  478. push(@vhost_lines, $_);
  479. }
  480. close $fh;
  481. # собираем все свойства
  482. my $properties = {};
  483. my @directives;
  484. # парсим ServerName
  485. @directives = grep(/ServerName/i, @vhost_lines);
  486. if (defined($directives[0])) {
  487. $directives[0] =~ m/ServerName[\s]+(\S+)/i;
  488. $properties->{'ServerName'} = trim($1);
  489. }
  490. # парсим ServerAlias
  491. @directives = grep(/ServerAlias/i, @vhost_lines);
  492. if (defined($directives[0])) {
  493. $directives[0] =~ m/ServerAlias[\s]+(.*?)(?:\s)?+$/i;
  494. $properties->{'ServerAlias'} = trim($1);
  495. }
  496. # парсим ServerAdmin
  497. @directives = grep(/ServerAdmin/i, @vhost_lines);
  498. if (defined($directives[0])) {
  499. $directives[0] =~ m/ServerAdmin[\s]+(.*?)(?:\s)?+$/i;
  500. $properties->{'ServerAdmin'} = trim($1);
  501. }
  502. # парсим AssignUserID
  503. @directives = grep(/AssignUserID/i, @vhost_lines);
  504. if (defined($directives[0])) {
  505. $directives[0] =~ m/AssignUserID[\s]+(.*?)(?:\s)?+$/i;
  506. $properties->{'AssignUserID'} = trim($1);
  507. }
  508. # парсим DocumentRoot
  509. @directives = grep(/DocumentRoot/i, @vhost_lines);
  510. if (defined($directives[0])) {
  511. $directives[0] =~ m/DocumentRoot[\s]+(.*?)(?:\s)?+$/i;
  512. $properties->{'DocumentRoot'} = trim($1);
  513. }
  514. # парсим CustomLog
  515. @directives = grep(/CustomLog/i, @vhost_lines);
  516. if (defined($directives[0])) {
  517. $directives[0] =~ m/CustomLog[\s]+(.*?)(?:\s)?+$/i;
  518. $properties->{'CustomLog'} = trim($1);
  519. }
  520. # парсим ErrorLog
  521. @directives = grep(/ErrorLog/i, @vhost_lines);
  522. if (defined($directives[0])) {
  523. $directives[0] =~ m/ErrorLog[\s]+(.*?)(?:\s)?+$/i;
  524. $properties->{'ErrorLog'} = trim($1);
  525. }
  526. # парсим DirectoryIndex
  527. @directives = grep(/DirectoryIndex/i, @vhost_lines);
  528. if (defined($directives[0])) {
  529. $directives[0] =~ m/DirectoryIndex[\s]+(.*?)(?:\s)?+$/i;
  530. $properties->{'DirectoryIndex'} = trim($1);
  531. }
  532. #########################################
  533. # парсим установки php
  534. # парсим memory_limit
  535. @directives = grep(/memory_limit/i, @vhost_lines);
  536. if (defined($directives[0])) {
  537. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+memory_limit[\s]+(\S*)/i;
  538. $properties->{'memory_limit'} = {
  539. directive => $1,
  540. value => trim($2)
  541. };
  542. }
  543. # парсим max_execution_time
  544. @directives = grep(/max_execution_time/i, @vhost_lines);
  545. if (defined($directives[0])) {
  546. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+max_execution_time[\s]+(\S*)/i;
  547. $properties->{'max_execution_time'} = {
  548. directive => $1,
  549. value => trim($2)
  550. };
  551. }
  552. # парсим upload_max_filesize
  553. @directives = grep(/upload_max_filesize/i, @vhost_lines);
  554. if (defined($directives[0])) {
  555. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+upload_max_filesize[\s]+(\S*)/i;
  556. $properties->{'upload_max_filesize'} = {
  557. directive => $1,
  558. value => trim($2)
  559. };
  560. }
  561. # парсим post_max_size
  562. @directives = grep(/post_max_size/i, @vhost_lines);
  563. if (defined($directives[0])) {
  564. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+post_max_size[\s]+(\S*)/i;
  565. $properties->{'post_max_size'} = {
  566. directive => $1,
  567. value => trim($2)
  568. };
  569. }
  570. # парсим error_log
  571. @directives = grep(/php_.*error_log/i, @vhost_lines);
  572. if (defined($directives[0])) {
  573. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+error_log[\s]+(\S*)/i;
  574. $properties->{'error_log'} = {
  575. directive => $1,
  576. value => trim($2)
  577. };
  578. }
  579. # парсим error_reporting
  580. @directives = grep(/error_reporting/i, @vhost_lines);
  581. if (defined($directives[0])) {
  582. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+error_reporting[\s]+(\S*)/i;
  583. $properties->{'error_reporting'} = {
  584. directive => $1,
  585. value => trim($2)
  586. };
  587. }
  588. # парсим display_errors
  589. @directives = grep(/display_errors/i, @vhost_lines);
  590. if (defined($directives[0])) {
  591. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+display_errors[\s]+(\S*)/i;
  592. $properties->{'display_errors'} = {
  593. directive => $1,
  594. value => trim($2)
  595. };
  596. }
  597. # парсим log_errors
  598. @directives = grep(/log_errors/i, @vhost_lines);
  599. if (defined($directives[0])) {
  600. $directives[0] =~ m/(php_(?:admin_)?(?:value|flag))[\s]+log_errors[\s]+(\S*)/i;
  601. $properties->{'log_errors'} = {
  602. directive => $1,
  603. value => trim($2)
  604. };
  605. }
  606. return $properties;
  607. }
  608. # проверяет существует ли файл виртуалхоста в /etc/apache2/sites-available/
  609. sub apache2_vhost_exists {
  610. my ($file_name) = @_;
  611. return (-e '/etc/apache2/sites-available/' . $file_name) ? 1 : 0;
  612. }
  613. # возвращает количество виртуалхостов апача
  614. sub apache2_vhosts_count
  615. {
  616. my @enabled = `/bin/ls -l /etc/apache2/sites-enabled 2>/dev/null | tail -n +2`;
  617. my @available = `/bin/ls -l /etc/apache2/sites-available 2>/dev/null | tail -n +2`;
  618. return @enabled . '/' . @available;
  619. }
  620. # проверяет конфиг апача
  621. sub apache2_configtest
  622. {
  623. my $tmp = `/usr/sbin/apache2ctl -t 2>&1`;
  624. #возвращаем результат
  625. return {'status' => $?,
  626. 'message' => $tmp};
  627. }
  628. # возвращает текстовую строку статуса апача
  629. sub apache2_status
  630. {
  631. my $result = linux_service('apache2', 'status');
  632. #возвращаем результат
  633. chomp $result->{'message'};
  634. return $result->{'message'};
  635. }
  636. # Добавляет vhost для апача. принимает:
  637. # строка $vhostsroot - корневая директория (/var/www)
  638. # строка $username - логин владельца vhost'а (домашняя директория пользователя, $vhostsroot . '/' . $username)
  639. # строка $servername - имя сервера (hostname)
  640. # строка|реф массив строк $alias - строка|строки алиасов домена
  641. # строка $adminemail - e-mail администатора домена
  642. sub apache2_add_vhost
  643. {
  644. my ($vhostsroot, $username, $servername, $alias, $adminemail) = @_;
  645. $vhostsroot =~ s/\/*$//;
  646. if (ref $alias eq 'ARRAY') {
  647. $alias = sprintf "@{$alias}";
  648. }
  649. my $vhost_config = '
  650. <VirtualHost *:8080>
  651. ServerName ' . $servername . '
  652. ServerAlias ' . $alias . '
  653. ServerAdmin ' . $adminemail . '
  654. AssignUserID ' . $username . ' ' . $username . '
  655. DocumentRoot ' . $vhostsroot . '/' . $username . '/data/www/' . $servername . '
  656. CustomLog ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.access.log combined
  657. ErrorLog ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.error.log
  658. DirectoryIndex index.php index.html index.htm
  659. AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
  660. AddType application/x-httpd-php-source .phps
  661. php_admin_value open_basedir "' . $vhostsroot . '/' . $username . '/data:."
  662. php_admin_value upload_tmp_dir "' . $vhostsroot . '/' . $username . '/data/tmp"
  663. php_admin_value session.save_path "' . $vhostsroot . '/' . $username . '/data/tmp"
  664. # runtime configuration
  665. php_value memory_limit "64M"
  666. php_value max_execution_time "300"
  667. # uploading configuration (memory_limit > post_max_size > upload_max_filesize)
  668. php_value upload_max_filesize "10M"
  669. php_value post_max_size "12M"
  670. # error handling
  671. php_value error_log "' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.error.log"
  672. php_value error_reporting "7"
  673. php_flag display_errors "Off"
  674. php_flag log_errors "On"
  675. # directories configuration
  676. <Directory "' . $vhostsroot . '/' . $username . '/data/www/' . $servername . '/">
  677. AllowOverride All
  678. Options -Indexes
  679. </Directory>
  680. </VirtualHost>
  681. ';
  682. my $confname = '/etc/apache2/sites-available/' . $servername . '.conf';
  683. my $enabledname = '/etc/apache2/sites-enabled/' . $servername . '.conf';
  684. # создаем конфиг виртуалхоста
  685. open(my $fh, '>', $confname)
  686. or Logger::warn('Manager: could not open ' . $confname . ' for write!');
  687. print($fh $vhost_config);
  688. close($fh);
  689. # создаем симлинк на файл виртуалхоста
  690. symlink($confname, $enabledname);
  691. }
  692. # проверяет включен ли виртуалхост
  693. sub apache2_vhost_enabled
  694. {
  695. my ($vhost_filename) = @_;
  696. if (!-e '/etc/apache2/sites-available/' . $vhost_filename) {
  697. return 0;
  698. }
  699. if (!-e '/etc/apache2/sites-enabled/' . $vhost_filename) {
  700. return 0;
  701. }
  702. return 1;
  703. }
  704. # удаляет виртуалхост апача
  705. sub apache2_vhost_delete
  706. {
  707. my ($vhost_filename) = @_;
  708. if (-e '/etc/apache2/sites-enabled/' . $vhost_filename) {
  709. unlink('/etc/apache2/sites-enabled/' . $vhost_filename)
  710. or Logger::warn('Manager: could not unlink file ' . '/etc/apache2/sites-enabled/' . $vhost_filename);
  711. }
  712. if (-e '/etc/apache2/sites-available/' . $vhost_filename) {
  713. unlink('/etc/apache2/sites-available/' . $vhost_filename)
  714. or Logger::warn('Manager: could not unlink file ' . '/etc/apache2/sites-available/' . $vhost_filename);
  715. }
  716. return 1;
  717. }
  718. # получает текст виртуалхоста
  719. sub apache2_vhost_get_text
  720. {
  721. my ($vhost_filename) = @_;
  722. return read_file('/etc/apache2/sites-available/' . $vhost_filename)
  723. or Logger::warn('Manager: could not read file ' . '/etc/apache2/sites-available/' . $vhost_filename);
  724. }
  725. # устанавливает текст виртуалхоста
  726. sub apache2_vhost_set_text
  727. {
  728. my ($vhost_filename, $vhost_text) = @_;
  729. # обновляем конфиг виртуалхоста
  730. open(my $fh, '>', '/etc/apache2/sites-available/' . $vhost_filename)
  731. or Logger::warn('Manager: could not open ' . '/etc/apache2/sites-available/' . $vhost_filename . ' for write!');
  732. print($fh $vhost_text);
  733. close($fh);
  734. }
  735. ##################################
  736. ### Функции для работы с nginx ###
  737. ##################################
  738. sub nginx_vhost_count
  739. {
  740. my @enabled = `/bin/ls -l /etc/nginx/sites-enabled 2>/dev/null| tail -n +2`;
  741. my @available = `/bin/ls -l /etc/nginx/sites-available 2>/dev/null| tail -n +2`;
  742. return @enabled . '/' . @available;
  743. }
  744. sub nginx_configtest
  745. {
  746. my $tmp = `/usr/sbin/nginx -t 2>&1`;
  747. #возвращаем результат
  748. return {'status' => $?,
  749. 'message' => $tmp};
  750. }
  751. sub nginx_status
  752. {
  753. my $result = linux_service('nginx', 'status');
  754. #возвращаем результат
  755. chomp $result->{'message'};
  756. return $result->{'message'};
  757. }
  758. # проверяет существует ли файл виртуалхоста в /etc/nginx/sites-available/
  759. sub nginx_vhost_exists {
  760. my ($file_name) = @_;
  761. return (-e '/etc/nginx/sites-available/' . $file_name) ? 1 : 0;
  762. }
  763. # Добавляет vhost для nginx. принимает:
  764. # строка $vhostsroot - корневая директория (/var/www)
  765. # строка $username - логин владельца vhost'а (домашняя директория пользователя, $vhostsroot . '/' . $username)
  766. # строка $servername - имя сервера (hostname)
  767. # строка|реф массив строк $alias - строка|строки алиасов домена
  768. sub nginx_add_vhost {
  769. my ($vhostsroot, $username, $servername, $alias) = @_;
  770. $vhostsroot =~ s/\/*$//;
  771. if (ref $alias eq 'ARRAY') {
  772. $alias = sprintf "@{$alias}";
  773. }
  774. my $vhost_config = '
  775. server {
  776. listen 80;
  777. server_name ' . $servername . ' ' . $alias . ';
  778. root ' . $vhostsroot . '/' . $username . '/data/www/' . $servername . ';
  779. access_log ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.access.log;
  780. error_log ' . $vhostsroot . '/' . $username . '/data/logs/' . $servername . '.error.log;
  781. index index.php index.html index.htm;
  782. error_page 500 502 503 504 /50x.html;
  783. server_name_in_redirect off;
  784. client_max_body_size 12M;
  785. location = /50x.html
  786. {
  787. root /var/www/nginx-default;
  788. }
  789. location /
  790. {
  791. proxy_set_header X-Real-IP $remote_addr;
  792. proxy_set_header Host $host;
  793. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  794. proxy_pass http://127.0.0.1:8080;
  795. #proxy_redirect http://' . $servername . ':8080/ /;
  796. }
  797. location ~* ^.+\.(jpg|jpeg|gif|png|rar|txt|tar|wav|bz2|exe|pdf|doc|xls|ppt|bmp|rtf|js|ico|css|zip|tgz|gz)$
  798. {
  799. root ' . $vhostsroot . '/' . $username . '/data/www/' . $servername . ';
  800. expires 30d;
  801. access_log off;
  802. }
  803. location ~ /\.ht
  804. {
  805. deny all;
  806. }
  807. }
  808. ';
  809. my $confname = '/etc/nginx/sites-available/' . $servername . '.conf';
  810. my $enabledname = '/etc/nginx/sites-enabled/' . $servername . '.conf';
  811. # создаем конфиг виртуалхоста
  812. open(my $fh, '>', $confname)
  813. or Logger::warn('Manager: could not open ' . $confname . ' for write!');
  814. print($fh $vhost_config);
  815. close($fh);
  816. # создаем симлинк на файл виртуалхоста
  817. symlink($confname, $enabledname);
  818. }
  819. # получает параметры виртуалхоста
  820. sub nginx_vhost_get
  821. {
  822. my ($vhost_filename) = @_;
  823. return {}
  824. if (!nginx_vhost_exists($vhost_filename));
  825. # вначале читаем vhost в массив
  826. my @vhost_lines;
  827. open my $fh, "<", "/etc/nginx/sites-available/" . $vhost_filename
  828. or Logger::warn('Manager: could not read file' . "/etc/nginx/sites-available/" . $vhost_filename);
  829. while (<$fh>) {
  830. chomp;
  831. push(@vhost_lines, $_);
  832. }
  833. close $fh;
  834. # собираем все свойства
  835. my $properties = {};
  836. my @directives;
  837. # парсим server_name
  838. @directives = grep(/server_name/i, @vhost_lines);
  839. if (defined($directives[0])) {
  840. $directives[0] =~ m/server_name[\s]+(.*);/i;
  841. $properties->{'server_name'} = trim($1);
  842. }
  843. # парсим root
  844. @directives = grep(/root/i, @vhost_lines);
  845. if (defined($directives[0])) {
  846. $directives[0] =~ m/root[\s]+(.*);/i;
  847. $properties->{'root'} = trim($1);
  848. }
  849. # парсим access_log
  850. @directives = grep(/access_log/i, @vhost_lines);
  851. if (defined($directives[0])) {
  852. $directives[0] =~ m/access_log[\s]+(.*);/i;
  853. $properties->{'access_log'} = trim($1);
  854. }
  855. # парсим error_log
  856. @directives = grep(/error_log/i, @vhost_lines);
  857. if (defined($directives[0])) {
  858. $directives[0] =~ m/error_log[\s]+(.*);/i;
  859. $properties->{'error_log'} = trim($1);
  860. }
  861. # парсим index
  862. @directives = grep(/index/i, @vhost_lines);
  863. if (defined($directives[0])) {
  864. $directives[0] =~ m/index[\s]+(.*);/i;
  865. $properties->{'index'} = trim($1);
  866. }
  867. # парсим client_max_body_size
  868. @directives = grep(/client_max_body_size/i, @vhost_lines);
  869. if (defined($directives[0])) {
  870. $directives[0] =~ m/client_max_body_size[\s]+(.*);/i;
  871. $properties->{'client_max_body_size'} = trim($1);
  872. }
  873. return $properties;
  874. }
  875. # проверяет включен ли виртуалхост
  876. sub nginx_vhost_enabled
  877. {
  878. my ($vhost_filename) = @_;
  879. if (!-e '/etc/nginx/sites-available/' . $vhost_filename) {
  880. return 0;
  881. }
  882. if (!-e '/etc/nginx/sites-enabled/' . $vhost_filename) {
  883. return 0;
  884. }
  885. return 1;
  886. }
  887. # удаляет виртуалхост nginx
  888. sub nginx_vhost_delete
  889. {
  890. my ($vhost_filename) = @_;
  891. if (-e '/etc/nginx/sites-enabled/' . $vhost_filename) {
  892. unlink('/etc/nginx/sites-enabled/' . $vhost_filename)
  893. or Logger::warn('Manager: could not unlink file ' . '/etc/nginx/sites-enabled/' . $vhost_filename . '');
  894. }
  895. if (-e '/etc/nginx/sites-available/' . $vhost_filename) {
  896. unlink('/etc/nginx/sites-available/' . $vhost_filename)
  897. or Logger::warn('Manager: could not unlink file ' . '/etc/nginx/sites-available/' . $vhost_filename . '');
  898. }
  899. return 1;
  900. }
  901. # получает текст виртуалхоста
  902. sub nginx_vhost_get_text
  903. {
  904. my ($vhost_filename) = @_;
  905. return read_file('/etc/nginx/sites-available/' . $vhost_filename)
  906. or Logger::warn('Manager: could not read file ' . '/etc/nginx/sites-available/' . $vhost_filename);
  907. }
  908. # устанавливает текст виртуалхоста
  909. sub nginx_vhost_set_text
  910. {
  911. my ($vhost_filename, $vhost_text) = @_;
  912. # обновляем конфиг виртуалхоста
  913. open(my $fh, '>', '/etc/nginx/sites-available/' . $vhost_filename)
  914. or Logger::warn('Manager: could not open ' . $vhost_filename . ' for write!');
  915. print($fh $vhost_text);
  916. close($fh);
  917. }
  918. ##################################
  919. ### Функции для работы с MySQL ###
  920. ##################################
  921. sub mysql5_get_space
  922. {
  923. my @tmp = split /\s+/, `/usr/bin/du /var/lib/mysql -h --max-depth 0 2>/dev/null`;
  924. return $tmp[0];
  925. }
  926. sub mysql5_status
  927. {
  928. my $result = linux_service2('mysql', 'status');
  929. #возвращаем результат
  930. chomp $result->{'message'};
  931. return $result->{'message'}
  932. }
  933. # возвращает mysql пользователей
  934. sub mysql5_get_users
  935. {
  936. my $mysql_user = Conf::get('Manager.mysql_user');
  937. my $mysql_pass = Conf::get('Manager.mysql_pass');
  938. my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
  939. my $results = $dbh->selectall_hashref('SELECT * FROM `user` u WHERE u.User != "root" AND u.User != "debian-sys-maint" GROUP BY `User`', 'User');
  940. $dbh->disconnect();
  941. return $results;
  942. }
  943. # проверяет свободность логина
  944. sub mysql5_login_free {
  945. my ($login, $hostname) = @_;
  946. # проверяем на заполненность
  947. if (!length ($login) || !length ($hostname)) {
  948. return 0;
  949. }
  950. my $mysql_user = Conf::get('Manager.mysql_user');
  951. my $mysql_pass = Conf::get('Manager.mysql_pass');
  952. my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
  953. my @results = $dbh->selectrow_array('SELECT count(*) as `count` FROM `user` u WHERE `u`.`User`=\'' . $login . '\' AND `u`.`Host`=\'' . $hostname . '\' LIMIT 1');
  954. $dbh->disconnect();
  955. return ($results[0] > 0) ? 0 : 1;
  956. }
  957. # удаляет mysql пользователя без баз
  958. sub mysql5_del_user {
  959. my $login = shift();
  960. my $mysql_user = Conf::get('Manager.mysql_user');
  961. my $mysql_pass = Conf::get('Manager.mysql_pass');
  962. my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
  963. $dbh->do('DROP USER ' . $login);
  964. $dbh->disconnect();
  965. }
  966. # добавляет mysql пользователя
  967. sub mysql5_add_user {
  968. my ($login, $passw, $properties) = @_;
  969. if (!length ($login)) {
  970. return {'status' => 1,
  971. 'message' => 'user login not specified'};
  972. }
  973. if (!length ($passw)) {
  974. return {'status' => 1,
  975. 'message' => 'user passw not specified'};
  976. }
  977. my $mxucs = '0';
  978. my $mxuph = '0';
  979. my $mxqph = '0';
  980. my $mxcph = '0';
  981. # менять ли max updates per hour
  982. if (defined($properties->{'mxuph'}) && length($properties->{'mxuph'})) {
  983. $mxuph = $properties->{'mxuph'};
  984. }
  985. # менять ли max queries per hour
  986. if (defined($properties->{'mxqph'}) && length($properties->{'mxqph'})) {
  987. $mxqph = $properties->{'mxqph'};
  988. }
  989. # менять ли max connections per hour
  990. if (defined($properties->{'mxcph'}) && length($properties->{'mxcph'})) {
  991. $mxcph = $properties->{'mxcph'};
  992. }
  993. # менять ли max user connections
  994. if (defined($properties->{'mxucs'}) && length($properties->{'mxucs'})) {
  995. $mxucs = $properties->{'mxucs'};
  996. }
  997. my $mysql_user = Conf::get('Manager.mysql_user');
  998. my $mysql_pass = Conf::get('Manager.mysql_pass');
  999. my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
  1000. $dbh->do('CREATE USER ' . $login . ' IDENTIFIED BY \'' . $passw . '\'');
  1001. $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' IDENTIFIED BY \'' . $passw . '\' WITH MAX_QUERIES_PER_HOUR ' . $mxqph . ' MAX_CONNECTIONS_PER_HOUR ' . $mxcph . ' MAX_UPDATES_PER_HOUR ' . $mxuph . ' MAX_USER_CONNECTIONS ' . $mxucs);
  1002. $dbh->do('FLUSH PRIVILEGES');
  1003. $dbh->disconnect();
  1004. }
  1005. #изменяет mysql пользователя
  1006. sub mysql5_update_user {
  1007. my ($login, $properties) = @_;
  1008. if (!length ($login)) {
  1009. return {'status' => 1,
  1010. 'message' => 'user login not specified'};
  1011. }
  1012. my $passw = '';
  1013. my $mxucs = '';
  1014. my $mxuph = '';
  1015. my $mxqph = '';
  1016. my $mxcph = '';
  1017. # менять ли пароль
  1018. if (defined($properties->{'passw'}) && length($properties->{'passw'})) {
  1019. $passw = $properties->{'passw'};
  1020. }
  1021. # менять ли max updates per hour
  1022. if (defined($properties->{'mxuph'}) && length($properties->{'mxuph'})) {
  1023. $mxuph = $properties->{'mxuph'};
  1024. }
  1025. # менять ли max queries per hour
  1026. if (defined($properties->{'mxqph'}) && length($properties->{'mxqph'})) {
  1027. $mxqph = $properties->{'mxqph'};
  1028. }
  1029. # менять ли max connections per hour
  1030. if (defined($properties->{'mxcph'}) && length($properties->{'mxcph'})) {
  1031. $mxcph = $properties->{'mxcph'};
  1032. }
  1033. # менять ли max user connections
  1034. if (defined($properties->{'mxucs'}) && length($properties->{'mxucs'})) {
  1035. $mxucs = $properties->{'mxucs'};
  1036. }
  1037. # выполняем действия
  1038. my $mysql_user = Conf::get('Manager.mysql_user');
  1039. my $mysql_pass = Conf::get('Manager.mysql_pass');
  1040. my $dbh = DBI->connect('DBI:mysql:mysql;host=localhost', $mysql_user, $mysql_pass, { RaiseError => 1 });
  1041. my $updated = 0;
  1042. if (length($passw)) {
  1043. $dbh->do('SET PASSWORD FOR ' . $login . ' = PASSWORD(\'' . $passw . '\')');
  1044. $updated = 1;
  1045. }
  1046. if (length($mxucs) && ($mxucs =~ m/^[\d]+$/)) {
  1047. $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_USER_CONNECTIONS ' . $mxucs);
  1048. $updated = 1;
  1049. }
  1050. if (length($mxcph) && ($mxcph =~ m/^[\d]+$/)) {
  1051. $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_CONNECTIONS_PER_HOUR ' . $mxcph);
  1052. $updated = 1;
  1053. }
  1054. if (length($mxqph) && ($mxqph =~ m/^[\d]+$/)) {
  1055. $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_QUERIES_PER_HOUR ' . $mxqph);
  1056. $updated = 1;
  1057. }
  1058. if (length($mxuph) && ($mxuph =~ m/^[\d]+$/)) {
  1059. $dbh->do('GRANT USAGE ON *.* TO ' . $login . ' WITH MAX_UPDATES_PER_HOUR ' . $mxuph);
  1060. $updated = 1;
  1061. }
  1062. if ($updated) {
  1063. $dbh->do('FLUSH PRIVILEGES');
  1064. }
  1065. $dbh->disconnect();
  1066. }
  1067. #################################
  1068. ### Функции для работы с php5 ###
  1069. #################################
  1070. sub php_get_version
  1071. {
  1072. my $version = `/usr/bin/php -r 'echo phpversion();' 2>/dev/null`;
  1073. chomp $version;
  1074. return $version;
  1075. }
  1076. # вспомогательная функция тримящая пробелы и кавычки
  1077. sub trim
  1078. {
  1079. my($string) = @_;
  1080. if (!defined($string)) {
  1081. $string = '';
  1082. }
  1083. for ($string) {
  1084. s/^[\s'"]+//;
  1085. s/[\s'"]+$//;
  1086. }
  1087. return $string;
  1088. }
  1089. return 1;


viewable in any browser valid css valid html 4.01 powered by lighttpd colored by colorer written in perl hosted by stavcom