]> jfr.im git - irc/SurrealServices/srsv.git/blob - branches/0.5.0/modules/serviceslibs/hostserv.pm
7557c10b7889b25d89450568f8f891e50d7a4329
[irc/SurrealServices/srsv.git] / branches / 0.5.0 / modules / serviceslibs / hostserv.pm
1 # This file is part of SurrealServices.
2 #
3 # SurrealServices is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
7 #
8 # SurrealServices is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with SurrealServices; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 package hostserv;
17
18 use strict;
19
20 use SrSv::Text::Format qw(columnar);
21 use SrSv::Errors;
22
23 use SrSv::HostMask qw(parse_mask);
24
25 use SrSv::User qw(get_user_nick get_user_id :flood);
26 use SrSv::User::Notice;
27 use SrSv::Help qw( sendhelp );
28
29 use SrSv::NickReg::Flags qw(NRF_NOHIGHLIGHT nr_chk_flag_user);
30 use SrSv::NickReg::User qw(is_identified);
31 use SrSv::IRCd::State qw($ircline synced initial_synced %IRCd_capabilities);
32 use SrSv::MySQL '$dbh';
33 use SrSv::MySQL::Glob;
34 require SrSv::DB::StubGen;
35
36
37 our $hsnick_default = 'HostServ';
38 our $hsnick = $hsnick_default;
39 our $hsuser = { NICK => $hsnick, ID => ircd::getAgentUuid($hsnick) };
40 sub init() {
41 $hsuser = { NICK => $hsnick, ID => ircd::getAgentUuid($hsnick) };
42 import SrSv::DB::StubGen (
43 dbh => $dbh,
44 generator => 'services_mysql_stubgen',
45 );
46
47 services_mysql_stubgen(
48 [set_vhost => 'INSERT', "REPLACE INTO vhost SELECT id, ?, ?, ?, UNIX_TIMESTAMP() FROM nickreg WHERE nick=?"],
49 [get_vhost => 'ROW', "SELECT vhost.ident, vhost.vhost
50 FROM vhost, nickalias
51 WHERE nickalias.nrid=vhost.nrid AND nickalias.alias=?"],
52 [del_vhost => 'NULL', "DELETE FROM vhost USING vhost, nickreg WHERE nickreg.nick=? AND vhost.nrid=nickreg.id"],
53 [get_matching_vhosts => 'ARRAY', "SELECT nickreg.nick, vhost.ident, vhost.vhost, vhost.adder, vhost.time
54 FROM vhost JOIN nickreg ON (vhost.nrid=nickreg.id)
55 WHERE nickreg.nick LIKE ? AND vhost.ident LIKE ? AND vhost.vhost LIKE ?
56 ORDER BY nickreg.nick"],
57 );
58 }
59
60 sub dispatch($$$) {
61 my ($user, $dstUser, $msg) = @_;
62 my $src = $user->{NICK};
63 $msg =~ s/^\s+//;
64 my @args = split(/\s+/, $msg);
65 my $cmd = shift @args;
66 $user->{AGENT} = $hsuser;
67 get_user_id ($user);
68 return if flood_check($user);
69 return unless (lc $dstUser->{NICK} eq lc $hsnick);
70 if(lc $cmd eq 'on') {
71 hs_on($user, $src, 0);
72 }
73 elsif(lc $cmd eq 'off') {
74 hs_off($user);
75 }
76 elsif($cmd =~ /^(add|set(host))?$/i) {
77 if (@args == 2) {
78 hs_sethost($user, @args);
79 }
80 else {
81 notice($user, 'Syntax: SETHOST <nick> <[ident@]vhost>');
82 }
83 }
84 elsif($cmd =~ /^del(ete)?$/i) {
85 if (@args == 1) {
86 hs_delhost($user, @args);
87 }
88 else {
89 notice($user, 'Syntax: DELETE <nick>');
90 }
91 }
92 elsif($cmd =~ /^list$/i) {
93 if (@args == 1) {
94 hs_list($user, @args);
95 }
96 else {
97 notice($user, 'Syntax: LIST <nick!vident@vhost>');
98 }
99 }
100 elsif($cmd =~ /^help$/i) {
101 sendhelp($user, 'hostserv', @args)
102 }
103 else { notice($user, "Unknown command."); }
104 }
105
106 sub hs_on($$;$) {
107 my ($user, $nick, $identify) = @_;
108 my $src = get_user_nick($user);
109
110 unless(nickserv::is_registered($nick)) {
111 notice($user, "Your nick, \002$nick\002, is not registered.");
112 return;
113 }
114
115 if(!$identify and !is_identified($user, $nick)) {
116 notice($user, "You are not identified to \002$nick\002.");
117 return;
118 }
119 if ($IRCd_capabilities{"CHGHOST"} eq "" || $IRCd_capabilities{"CHGIDENT"} eq "" || $IRCd_capabilities{"CLOAKHOST"} eq "" || $IRCd_capabilities{"CLOAK"} eq "") {
120 notice ($user, "The IRCd is not properly configured to support vhosts. Please contact your friendly network administrators.");
121 notice ($user, "CHGHOST, CHGIDENT, CLOAKHOST and CLOAK need to be enabled for proper vhost support.");
122 return;
123 }
124 my ($vident, $vhost) = get_vhost($nick);
125 unless ($vhost) {
126 notice($user, "You don't have a vHost.") unless $identify;
127 return;
128 }
129
130 if ($vident) {
131 ircd::chgident($hsuser, $user, $vident);
132 }
133 ircd::chghost($hsuser, $user, $vhost);
134
135 notice($user, "Your vHost has been changed to \002".($vident?"$vident\@":'')."$vhost\002");
136 }
137
138 sub hs_off($) {
139 my ($user) = @_;
140 my $src = get_user_nick($user);
141 if (!$IRCd_capabilities{"CHGHOST"} || !$IRCd_capabilities{"CHGIDENT"} || !$IRCd_capabilities{"CLOAKHOST"} || !$IRCd_capabilities{"CLOAK"}) {
142 notice ($user, "The IRCd is not properly configured to support vhosts. Please contact your friendly network administrators.");
143 notice ($user, "CHGHOST, CHGIDENT, CLOAKHOST and CLOAK need to be enabled for proper vhost support.");
144 return;
145 }
146 # This requires a hack that is only known to work in UnrealIRCd 3.2.6 and later.
147 # And insp!
148 ircd::reset_cloakhost($hsuser, $user);
149
150 notice($user, "vHost reset to cloakhost.");
151 }
152
153 sub hs_sethost($$$) {
154 my ($user, $target, $vhost) = @_;
155 unless(adminserv::is_svsop($user, adminserv::S_OPER())) {
156 notice($user, $err_deny);
157 return;
158 }
159 if (!$IRCd_capabilities{"CHGHOST"} || !$IRCd_capabilities{"CHGIDENT"} || !$IRCd_capabilities{"CLOAKHOST"} || !$IRCd_capabilities{"CLOAK"}) {
160 notice ($user, "The IRCd is not properly configured to support vhosts. Please contact your friendly network administrators.");
161 notice ($user, "CHGHOST, CHGIDENT, CLOAKHOST and CLOAK need to be enabled for proper vhost support.");
162 return;
163 }
164 my $rootnick = nickserv::get_root_nick($target);
165
166 unless ($rootnick) {
167 notice($user, "\002$target\002 is not registered.");
168 return;
169 }
170
171 my $vident = '';
172 if($vhost =~ /\@/) {
173 ($vident, $vhost) = split(/\@/, $vhost);
174 }
175 my $src = get_user_nick($user);
176 set_vhost($vident, $vhost, $src, $rootnick);
177
178 notice($user, "vHost for \002$target ($rootnick)\002 set to \002".($vident?"$vident\@":'')."$vhost\002");
179 }
180
181 sub hs_delhost($$) {
182 my ($user, $target) = @_;
183 unless(adminserv::is_svsop($user, adminserv::S_OPER())) {
184 notice($user, $err_deny);
185 return;
186 }
187 my $rootnick = nickserv::get_root_nick($target);
188
189 unless ($rootnick) {
190 notice($user, "\002$target\002 is not registered.");
191 return;
192 }
193
194 del_vhost($rootnick);
195
196 notice($user, "vHost for \002$target ($rootnick)\002 deleted.");
197 }
198
199 sub hs_list($$) {
200 my ($user, $mask) = @_;
201
202 unless(adminserv::is_svsop($user, adminserv::S_HELP())) {
203 notice($user, $err_deny);
204 return;
205 }
206
207 my ($mnick, $mident, $mhost) = glob2sql(parse_mask($mask));
208
209 $mnick = '%' if($mnick eq '');
210 $mident = '%' if($mident eq '');
211 $mhost = '%' if($mhost eq '');
212
213 my @data;
214 foreach my $vhostEnt (get_matching_vhosts($mnick, $mident, $mhost)) {
215 my ($rnick, $vident, $vhost) = @$vhostEnt;
216 push @data, [$rnick, ($vident?"$vident\@":'').$vhost];
217 }
218
219 notice($user, columnar({TITLE => "vHost list matching \002$mask\002:",
220 NOHIGHLIGHT => nr_chk_flag_user($user, NRF_NOHIGHLIGHT)}, @data));
221 }
222
223
224 ### MISCELLANEA ###
225
226
227
228 ## IRC EVENTS ##
229
230 1;