fixed module loading
[ZNCAdmin.git] / zncadmin.php
1 <?php
2 /* czncadmin.php - main script - ZNCAdmin
3  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
4  * 
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License 
16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
17  */
18
19 error_reporting(E_ALL & ~E_NOTICE);
20 require_once("zncadmin/HTTPConnector.class.php");
21 require_once("zncadmin/ZNCServer.class.php");
22 require_once("zncadmin/Table.class.php");
23
24 require_once("config.inc.php");
25
26 /*
27 $argv[1]   subcommand
28 */
29
30 function error($msg) {
31     echo"\00304ZNCAdmin error:\003 ".$msg."\n";
32 }
33
34 if(strtolower($argv[1]) == "force") {
35     $argv = array_slice($argv, 1);
36     $force = true;
37 } else
38     $force = false;
39
40 switch(strtolower($argv[1])) {
41     case "add":
42         zncadmin_add();
43         break;
44     case "del":
45         zncadmin_del();
46         break;
47     case "search":
48         zncadmin_search();
49         break;
50         case "seen":
51         zncadmin_seen();
52         break;
53     case "resetpass":
54         zncadmin_resetpass();
55         break;
56     case "simul":
57         zncadmin_simul();
58         break;
59     case "block":
60         zncadmin_block();
61         break;
62     case "unblock":
63         zncadmin_unblock();
64         break;
65     case "stats":
66         zncadmin_stats();
67         break;
68     default:
69         error("invalid subcommand '".$argv[1]."'");
70         break;
71 }
72
73 function preg_prepare($string,$wildcards = true,$pregstart = "#") {
74     $in = array("\\","^",".","$","|","(",")","[","]","+","?","{","}",",",$pregstart);
75     if(!$wildcards) array_push($in,"*");
76     $out = array();
77     foreach($in as $item) {
78         $out[] = "\\".$item;
79     }
80     if($wildcards) { 
81         array_push($in,"*");
82         array_push($out,"(.*)");
83     }
84     $string = str_replace($in,$out,$string);
85     return $string;
86 }
87
88 function generate_password() {
89     $password_chars = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
90     $password_length = 10;
91     $password = 0;
92     srand();
93     for($i = 0; $i < $password_length; $i++) {
94         $password .= $password_chars[rand(0, strlen($password_chars))-1];
95     }
96     return $password;
97 }
98
99 function str2time($duration) {
100     $str="0";
101     $dur=0;
102     $mult=1;
103     for($i=0;$i<strlen($duration);$i++) {
104         if(is_numeric($duration[$i])) {
105             $str.=$duration[$i];
106         } else if($duration[$i] != " ") {
107             switch ($duration[$i]) {
108                 case "y":
109                     $mult=365*24*60*60;
110                     break;
111                 case "M":
112                     $mult=31*24*60*60;
113                     break;
114                 case "w":
115                     $mult=7*24*60*60;
116                     break;
117                 case "d":
118                     $mult=24*60*60;
119                     break;
120                 case "h":
121                     $mult=60*60;
122                     break;
123                 case "m":
124                     $mult=60;
125                     break;
126                 case "s":
127                     $mult=1;
128                     break;
129                 case "*":
130                     $mult=0;
131                     break;
132                 default:
133                     return null;
134                     break;
135             }
136             $dur=$dur+($str*$mult);
137             $str="0";
138         }
139     }
140     $dur=$dur+$str;
141     return $dur;
142 }
143
144 /***********************************************************
145  *                   ZNCAdmin SUBCOMMANDS                  *
146  ***********************************************************/
147
148 //SUBCOMMAND: search
149 function zncadmin_search() {
150     global $argv, $zncservers;
151     $mask = $argv[2];
152     if(!$mask) {
153         error("missing mask parameter");
154         return;
155     }
156     $extraflags = array();
157     if($argv[3]) {
158         $extraflags = explode(" ", $argv[3]);
159     }
160     $mask = preg_prepare($mask);
161     $table = new Table(5);
162     $table->add("Server", "User", "Clients", "Server", "");
163     $count = 0;
164     foreach($zncservers as $zncserver) {
165         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
166         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
167         foreach($zncserver['conn']->getUserList() as $user) {
168             $skip = false;
169             foreach($extraflags as $flag) {
170                 //some additional flags ;)
171                 if($flag[0] == '-') {
172                     $flag = substr($flag, 1);
173                     $positive = false;
174                 } else if($flag[0] == '+') {
175                     $flag = substr($flag, 1);
176                     $positive = true;
177                 } else
178                     $positive = true;
179                 $flag = explode("=", $flag, 2);
180                 $flagval = $flag[1];
181                 switch (strtolower($flag[0])) {
182                     case "online":
183                         $skip = (($user['clients'] > 0) != $positive);
184                         break;
185                     case "connected":
186                         $skip = (($user['server'] == "-N/A-") == $positive);
187                         break;
188                     case "server":
189                         $skip = (preg_match("#^".preg_prepare($flagval)."$#i", $user['server']) != $positive);
190                         break;
191                     case "server_regex":
192                         $skip = (preg_match("#^".$flagval."$#i", $user['server']) != $positive);
193                         break;
194                     case "nick":
195                         $skip = (preg_match("#^".preg_prepare($flagval)."$#i", $user['nick']) != $positive);
196                         break;
197                     case "nick_regex":
198                         $skip = (preg_match("#^".$flagval."$#i", $user['nick']) != $positive);
199                         break;
200                     case "znc":
201                         $skip = (preg_match("#^".preg_prepare($flagval)."$#i", $zncserver['name']) != $positive);
202                         break;
203                     default:
204                         
205                         break;
206                 }
207                 if($skip)
208                     break;
209             }
210             if($skip) continue;
211             if(preg_match("#^".$mask."$#i", $user['user'])) {
212                 $extra = "";
213                 if(isset($user['nick'])) {
214                     if($extra != "")
215                         $extra .= ", ";
216                     $extra .= "Nick: ".$user['nick'];
217                 }
218                 $table->add($zncserver['name'], $user['user'], $user['clients'], $user['server'], $extra);
219                 $count++;
220             }
221         }
222     }
223     if($count) {
224         foreach($table->end() as $line) {
225             echo$line."\n";
226         }
227         echo"Found \002".$count."\002 users.\n";
228     } else {
229         echo "no user matching \002".$argv[2]."\002 found.\n";
230     }
231 }
232
233 //SUBCOMMAND: search
234 function zncadmin_seen() {
235     global $argv, $zncservers;
236         $time = $argv[2];
237         $over_time = true;
238         if($time[0] == '>' || $time[0] == '<') {
239                 if($time[0] == '<') $over_time = false;
240                 $time = substr($time, 1);
241         }
242         $time = time() - str2time($time);
243     $mask = $argv[3];
244     if(!$time) {
245         error("missing time parameter");
246         return;
247     }
248     if($mask)
249         $mask = preg_prepare($mask);
250     else
251         $mask = "(.*)";
252     $table = new Table(4);
253     $table->add("Server", "User", "Seen", "Info");
254     $found = false;
255     foreach($zncservers as $zncserver) {
256         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
257         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
258         foreach($zncserver['conn']->getSeenList() as $user) {
259             if(preg_match("#^".$mask."$#i", $user['user']) && (($over_time && $user['seen_unix'] < $time) || (!$over_time && $user['seen_unix'] > $time))) {
260                 $table->add($zncserver['name'], $user['user'], $user['seen'], $user['info']);
261                 $found = true;
262             }
263         }
264     }
265     if($found) {
266         foreach($table->end() as $line) {
267             echo$line."\n";
268         }
269     } else {
270         echo "no user matching \002".$argv[2]."\002 found.\n";
271     }
272 }
273
274 //SUBCOMMAND: del
275 function zncadmin_del() {
276     global $argv, $zncservers, $force;
277     $username = strtolower($argv[2]);
278     if(!$username) {
279         error("missing username");
280         return;
281     }
282     $delusers = array();
283     foreach($zncservers as $zncserver) {
284         if($argv[3] && (strtolower($argv[3]) != strtolower($zncserver['name']))) continue;
285         if($username == strtolower($zncserver['auser'])) continue;
286         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
287         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
288         foreach($zncserver['conn']->getUserList() as $user) {
289             if(strtolower($user['user']) == $username) {
290                 $delusers[] = array("server" => $zncserver, "user" => $user);
291             }
292         }
293     }
294     if(count($delusers) > 1) {
295         error($argv[2]." exists on multiple servers! please add the server name, the user should be removed from.");
296         echo"Found User on following Servers:\n";
297         foreach($delusers as $server) {
298             echo "\002".$server['server']['name']."\002  Server: ".$server['user']['server']."  Nick: ".$server['user']['nick']."  Clients: ".$server['user']['clients']."\n";
299         }
300     } else if(count($delusers) == 0) {
301         error("Couldn't find an user called \002".$argv[2]."\002.");
302     } else if($delusers[0]['server']['protected'] && !$force) {
303         error("Access denied\n");
304     } else {
305         $deluser = $delusers[0];
306         $deluser['server']['conn']->delZNC($deluser['user']['user']);
307         echo "Deleted \002".$deluser['user']['user']."\002 from Server \002".$deluser['server']['name']."\002\n";
308         echo"/log\n";
309     }
310 }
311
312 //SUBCOMMAND: add
313 function zncadmin_add() {
314     global $argv, $zncservers, $add_settings, $force;
315     $username = strtolower($argv[2]);
316     if(!$username) {
317         error("missing username");
318         return;
319     }
320     $addserv = array();
321     $priority = 1;
322     foreach($zncservers as $zncserver) {
323         if($argv[3] && (strtolower($argv[3]) != strtolower($zncserver['name']))) continue;
324         if(!$argv[3] && $zncserver['priority'] < $priority) continue;
325         if($zncserver['protected'] === true && !$force) {
326             error("Access denied\n");
327             return;
328         }
329         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
330         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
331         $zncserver['users'] = $zncserver['conn']->getUserList();
332         $existing = false;
333         foreach($zncserver['users'] as $user) {
334             if(strtolower($user['user']) == $username) $existing = true;
335         }
336         if(!$existing && count($zncserver['users']) < $zncserver['maxznc']) {
337             if($zncserver['priority'] > $priority) {
338                 $priority = $zncserver['priority'];
339                 $addserv = array();
340             }
341             $addserv[] = $zncserver;
342         }
343     }
344     if(count($addserv) > 1) {
345         //select server with lowest user count
346         $usercount = count($addserv[0]['users']);
347         $selected = 0;
348         for($i = 1; $i < count($addserv); $i++) {
349             if(count($addserv[$i]['users']) < $usercount) {
350                 $usercount = count($addserv[$i]['users']);
351                 $selected = $i;
352             }
353         }
354         $addserv = $addserv[$selected];
355     } else if(count($addserv) == 0) {
356         error("Couldn't find a server the user could be added to.");
357         return;
358     } else {
359         $addserv = $addserv[0];
360     }
361     $password = generate_password();
362     $settings = array();
363     $settings['nick'] = $argv[2];
364     $settings['altnick'] = $argv[2]."`";
365     $settings['ident'] = $username;
366     $ret = $addserv['conn']->addZNC($argv[2], $password, $settings, $add_settings['servers'], $add_settings['modules'], $add_settings['netmodules'], $add_settings['other']);
367     if($ret) {
368         echo "Added user ".$argv[2]." to Server ".$addserv['name'].".\n";
369         echo "  Server Host: ".$addserv['public']."  Port: ".$addserv['port']."  SSL Port: ".$addserv['sslport']."\n";
370         echo "  Password: ".$password."\n";
371         echo "[mIRC]\n";
372         echo " /server -a ".$addserv['public']." -p ".$addserv['port']." -g ".$add_settings['mirccmds']['groupname']." -w ".$argv[2].":".$password." -d ".$add_settings['mirccmds']['groupname']."\n";
373         foreach($add_settings['mirccmds']['hosts'] AS $host) {
374             echo " /AS addmask *@*.".$host."\n";
375         }
376         echo " /server -m ".$add_settings['mirccmds']['groupname']."\n";
377         echo"/log\n";
378         foreach($add_settings["channel"] AS $channel) {
379             $addserv['conn']->addChan($argv[2], $channel);
380         }
381     } else
382         error("Error while adding user.");
383 }
384
385 //SUBCOMMAND: resetpass
386 function zncadmin_resetpass() {
387     global $argv, $zncservers, $force;
388     $username = strtolower($argv[2]);
389     if(!$username) {
390         error("missing username");
391         return;
392     }
393     $delusers = array();
394     foreach($zncservers as $zncserver) {
395         if($argv[3] && (strtolower($argv[3]) != strtolower($zncserver['name']))) continue;
396         if($username == strtolower($zncserver['auser'])) continue;
397         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
398         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
399         foreach($zncserver['conn']->getUserList() as $user) {
400             if(strtolower($user['user']) == $username) {
401                 $delusers[] = array("server" => $zncserver, "user" => $user);
402             }
403         }
404     }
405     if(count($delusers) > 1) {
406         error($argv[2]." exists on multiple servers! please add the server name the user, the password should be resetted, is on.");
407         echo"Found User on following Servers:\n";
408         foreach($delusers as $server) {
409             echo "\002".$server['server']['name']."\002  Server: ".$server['user']['server']."  Nick: ".$server['user']['nick']."  Clients: ".$server['user']['clients']."\n";
410         }
411     } else if(count($delusers) == 0) {
412         error("Couldn't find an user called \002".$argv[2]."\002.");
413     } else if($delusers[0]['server']['protected'] && !$force) {
414         error("Access denied\n");
415     } else {
416         $deluser = $delusers[0];
417         $password = generate_password();
418         $deluser['server']['conn']->editZNC($deluser['user']['user'], $password);
419         echo "Changed password of \002".$deluser['user']['user']."\002 on Server ".$deluser['server']['name']." to \002".$password."\002\n";
420         echo"/log\n";
421     }
422 }
423
424 //SUBCOMMAND: simul
425 function zncadmin_simul() {
426     global $argv, $zncservers, $force;
427     $username = strtolower($argv[2]);
428     $server = strtolower($argv[3]);
429     $raw = $argv[4];
430     if(!$username) {
431         error("missing username");
432         return;
433     }
434     if($server) {
435         $found = false;
436         foreach($zncservers as $zncserver) {
437             if(strtolower($server) == strtolower($zncserver['name'])) {
438                 $found = true;
439                 break;
440             }
441         }
442         if(!$found) {
443             $raw = $argv[3]." ".$raw;
444             $server = null;
445         }
446     }
447     if(!$raw) {
448         error("missing raw");
449         return;
450     }
451     $delusers = array();
452     foreach($zncservers as $zncserver) {
453         if($server && (strtolower($server) != strtolower($zncserver['name']))) continue;
454         if($username == strtolower($zncserver['auser'])) continue;
455         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
456         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
457         foreach($zncserver['conn']->getUserList() as $user) {
458             if(strtolower($user['user']) == $username) {
459                 $delusers[] = array("server" => $zncserver, "user" => $user);
460             }
461         }
462     }
463     if(count($delusers) > 1) {
464         error($argv[2]." exists on multiple servers! please add the server name the user should be simuled on.");
465         echo"Found User on following Servers:\n";
466         foreach($delusers as $server) {
467             echo "\002".$server['server']['name']."\002  Server: ".$server['user']['server']."  Nick: ".$server['user']['nick']."  Clients: ".$server['user']['clients']."\n";
468         }
469     } else if(count($delusers) == 0) {
470         error("Couldn't find an user called \002".$argv[2]."\002.");
471     } else if($delusers[0]['server']['protected'] && !$force) {
472         error("Access denied\n");
473     } else {
474         $deluser = $delusers[0];
475         $ret = $deluser['server']['conn']->simulZNC($deluser['user']['user'], $raw);
476         if($ret == ERR_MODULE_NOT_FOUND) {
477             error("send_raw module is not installed or not activated for user ".$deluser['server']['auser']." on ".$deluser['server']['name']);
478         } else {
479             echo "Simuled \002".$deluser['user']['user']."\002 on Server ".$deluser['server']['name'].": ".$raw."\n";
480             echo"/log\n";
481         }
482     }
483 }
484
485 //SUBCOMMAND: block
486 function zncadmin_block() {
487     global $argv, $zncservers, $force;
488     $username = strtolower($argv[2]);
489     $server = strtolower($argv[3]);
490     if(!$username) {
491         error("missing username");
492         return;
493     }
494     $delusers = array();
495     foreach($zncservers as $zncserver) {
496         if($server && (strtolower($server) != strtolower($zncserver['name']))) continue;
497         if($username == strtolower($zncserver['auser'])) continue;
498         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
499         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
500         foreach($zncserver['conn']->getUserList() as $user) {
501             if(strtolower($user['user']) == $username) {
502                 $delusers[] = array("server" => $zncserver, "user" => $user);
503             }
504         }
505     }
506     if(count($delusers) > 1) {
507         error($argv[2]." exists on multiple servers! please add the server name the user should be blocked on.");
508         echo"Found User on following Servers:\n";
509         foreach($delusers as $server) {
510             echo "\002".$server['server']['name']."\002  Server: ".$server['user']['server']."  Nick: ".$server['user']['nick']."  Clients: ".$server['user']['clients']."\n";
511         }
512     } else if(count($delusers) == 0) {
513         error("Couldn't find an user called \002".$argv[2]."\002.");
514     } else if($delusers[0]['server']['protected'] && !$force) {
515         error("Access denied\n");
516     } else {
517         $deluser = $delusers[0];
518         $ret = $deluser['server']['conn']->blockZNC($deluser['user']['user'], true);
519         if($ret == ERR_MODULE_NOT_FOUND) {
520             error("blockuser module is not installed or not activated on ".$deluser['server']['name']);
521         } else {
522             echo "Blocked \002".$deluser['user']['user']."\002 on Server ".$deluser['server']['name'].".\n";
523             echo"/log\n";
524         }
525     }
526 }
527
528 //SUBCOMMAND: unblock
529 function zncadmin_unblock() {
530     global $argv, $zncservers, $force;
531     $username = strtolower($argv[2]);
532     $server = strtolower($argv[3]);
533     if(!$username) {
534         error("missing username");
535         return;
536     }
537     $delusers = array();
538     foreach($zncservers as $zncserver) {
539         if($server && (strtolower($server) != strtolower($zncserver['name']))) continue;
540         if($username == strtolower($zncserver['auser'])) continue;
541         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
542         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
543         foreach($zncserver['conn']->getUserList() as $user) {
544             if(strtolower($user['user']) == $username) {
545                 $delusers[] = array("server" => $zncserver, "user" => $user);
546             }
547         }
548     }
549     if(count($delusers) > 1) {
550         error($argv[2]." exists on multiple servers! please add the server name the user should be unblocked on.");
551         echo"Found User on following Servers:\n";
552         foreach($delusers as $server) {
553             echo "\002".$server['server']['name']."\002  Server: ".$server['user']['server']."  Nick: ".$server['user']['nick']."  Clients: ".$server['user']['clients']."\n";
554         }
555     } else if(count($delusers) == 0) {
556         error("Couldn't find an user called \002".$argv[2]."\002.");
557     } else if($delusers[0]['server']['protected'] && !$force) {
558         error("Access denied\n");
559     } else {
560         $deluser = $delusers[0];
561         $ret = $deluser['server']['conn']->blockZNC($deluser['user']['user'], false);
562         if($ret == ERR_MODULE_NOT_FOUND) {
563             error("blockuser module is not installed or not activated on ".$deluser['server']['name']);
564         } else {
565             echo "Unblocked \002".$deluser['user']['user']."\002 on Server ".$deluser['server']['name'].".\n";
566             echo"/log\n";
567         }
568     }
569 }
570
571 //SUBCOMMAND: stats
572 function zncadmin_stats() {
573     global $argv, $zncservers;
574     $table = new Table(6);
575     $table->add("Server", "Port / SSL Port", "Total ZNC's", "Connected (IRC)", "Online (User)", "Protected?");
576     $count = 0;
577     foreach($zncservers as $zncserver) {
578         $total = 0;
579         $connected = 0;
580         $online = 0;
581         $zncserver['conn'] = new ZNCServer($zncserver['host'], $zncserver['port'], (isset($zncserver['version']) ? $zncserver['version'] : NULL));
582         $zncserver['conn']->login($zncserver['auser'], $zncserver['apass']);
583         foreach($zncserver['conn']->getUserList() as $user) {
584             if($user['server'] != "-N/A-") $connected++;
585             if($user['clients'] > 0) $online++;
586             $total++;
587         }
588         $table->add($zncserver['name'], $zncserver['port'].($zncserver['sslport'] ? "/".$zncserver['sslport'] : ""), $total.($zncserver['maxznc'] ? "/".$zncserver['maxznc'] : ""), $connected, $online, ($zncserver['protected'] === true ? "X" : ""));
589         $count++;
590     }
591     if($count) {
592         foreach($table->end() as $line) {
593             echo$line."\n";
594         }
595     } else {
596         echo "No Servers configured...\n";
597     }
598 }
599
600 ?>