ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/modules/nickserv/vhost.C
Revision: 1.9
Committed: Sat Sep 22 14:27:28 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +3 -3 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /**
2 * vhost.C: Allows setting a vhost on an account
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Copyright © 2005 William Pitcock <nenolod -at- nenolod.net>
10 * Rights to this code are as documented in doc/pod/license.pod.
11 *
12 * $Id: vhost.C,v 1.8 2007-09-16 18:54:43 pippijn Exp $
13 */
14
15 #include "atheme.h"
16 #include <ermyth/module.h>
17 #include <account/myuser.h>
18 #include <boost/foreach.hpp>
19
20 static char const rcsid[] = "$Id: vhost.C,v 1.8 2007-09-16 18:54:43 pippijn Exp $";
21
22 REGISTER_MODULE ("nickserv/vhost", false, "The Ermyth Team <http://ermyth.xinutec.org>");
23
24 E cmdvec ns_cmdtree;
25 E helpvec ns_helptree;
26
27 static void ns_cmd_vhost (sourceinfo_t *si, int parc, char *parv[]);
28 static void ns_cmd_listvhost (sourceinfo_t *si, int parc, char *parv[]);
29
30 command_t const ns_vhost = { "VHOST", N_("Manages user virtualhosts."), PRIV_USER_VHOST, 2, ns_cmd_vhost };
31 command_t const ns_listvhost = { "LISTVHOST", N_("Lists user virtualhosts."), PRIV_USER_AUSPEX, 1, ns_cmd_listvhost };
32
33 static void
34 do_sethost_all (myuser_t *mu, char *host)
35 {
36 user_t *u;
37 myuser_t::login_vector::iterator it, it_end;
38
39 for (it = mu->logins.begin (), it_end = mu->logins.end (); it != it_end; ++it)
40 {
41 u = *it;
42
43 if (!strcmp (u->vhost, host))
44 continue;
45 strlcpy (u->vhost, host, HOSTLEN);
46 phandler->sethost_sts (nicksvs.nick, u->nick, u->vhost);
47 }
48 }
49
50 static void
51 do_sethost (user_t *u, char *host)
52 {
53 if (!strcmp (u->vhost, host))
54 return;
55 strlcpy (u->vhost, host, HOSTLEN);
56 phandler->sethost_sts (nicksvs.nick, u->nick, u->vhost);
57 }
58
59 static void
60 do_restorehost_all (myuser_t *mu)
61 {
62 user_t *u;
63 myuser_t::login_vector::iterator it, it_end;
64
65 for (it = mu->logins.begin (), it_end = mu->logins.end (); it != it_end; ++it)
66 {
67 u = *it;
68
69 if (!strcmp (u->vhost, u->host))
70 continue;
71 strlcpy (u->vhost, u->host, HOSTLEN);
72 phandler->sethost_sts (nicksvs.nick, u->nick, u->host);
73 }
74 }
75
76 /* VHOST <nick> [host] */
77 static void
78 ns_cmd_vhost (sourceinfo_t *si, int parc, char *parv[])
79 {
80 char *target = parv[0];
81 char *host = parv[1];
82 myuser_t *mu;
83 char *p;
84
85 if (!target)
86 {
87 command_fail (si, fault::needmoreparams, STR_INVALID_PARAMS, "VHOST");
88 command_fail (si, fault::needmoreparams, _("Syntax: VHOST <nick> [vhost]"));
89 return;
90 }
91
92 /* find the user... */
93 if (!(mu = myuser_t::find_ext (target)))
94 {
95 command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), target);
96 return;
97 }
98
99 /* deletion action */
100 if (!host)
101 {
102 mu->del_metadata ("private:usercloak");
103 command_success_nodata (si, _("Deleted vhost for \2%s\2."), mu->name);
104 snoop ("VHOST:REMOVE: \2%s\2 by \2%s\2", mu->name, get_oper_name (si));
105 logcommand (si, CMDLOG_ADMIN, "VHOST REMOVE %s", mu->name);
106 do_restorehost_all (mu);
107 return;
108 }
109
110 /* Never ever allow @!?* as they have special meaning in all ircds */
111 /* Empty, space anywhere and colon at the start break the protocol */
112 if (strchr (host, '@') || strchr (host, '!') || strchr (host, '?') || strchr (host, '*') || strchr (host, ' ') || *host == ':' || *host == '\0')
113 {
114 command_fail (si, fault::badparams, _("The vhost provided contains invalid characters."));
115 return;
116 }
117 if (strlen (host) >= HOSTLEN)
118 {
119 command_fail (si, fault::badparams, _("The vhost provided is too long."));
120 return;
121 }
122 p = strrchr (host, '/');
123 if (p != NULL && isdigit (p[1]))
124 {
125 command_fail (si, fault::badparams, _("The vhost provided looks like a CIDR mask."));
126 return;
127 }
128 /* XXX more checks here, perhaps as a configurable regexp? */
129
130 mu->add_metadata ("private:usercloak", host);
131 command_success_nodata (si, _("Assigned vhost \2%s\2 to \2%s\2."), host, mu->name);
132 snoop ("VHOST:ASSIGN: \2%s\2 to \2%s\2 by \2%s\2", host, mu->name, get_oper_name (si));
133 logcommand (si, CMDLOG_ADMIN, "VHOST ASSIGN %s %s", mu->name, host);
134 do_sethost_all (mu, host);
135 return;
136 }
137
138 static void
139 ns_cmd_listvhost (sourceinfo_t *si, int parc, char *parv[])
140 {
141 char const * const pattern = parc >= 1 ? parv[0] : "*";
142 myuser_t *mu;
143 metadata *md;
144 int matches = 0;
145
146 snoop ("LISTVHOST: \2%s\2 by \2%s\2", pattern, get_oper_name (si));
147 foreach (myuser_t::pair_type &mup, myuser_t::map)
148 {
149 mu = mup.second;
150 md = mu->find_metadata ("private:usercloak");
151 if (md == NULL)
152 continue;
153 if (!match (pattern, md->value))
154 {
155 command_success_nodata (si, "- %-30s %s", mu->name, md->value);
156 matches++;
157 }
158 }
159
160 logcommand (si, CMDLOG_ADMIN, "LISTVHOST %s (%d matches)", pattern, matches);
161 if (matches == 0)
162 command_success_nodata (si, _("No vhosts matched pattern \2%s\2"), pattern);
163 else
164 command_success_nodata (si, ngettext (N_("\2%d\2 match for pattern \2%s\2"), N_("\2%d\2 matches for pattern \2%s\2"), matches), matches, pattern);
165 }
166
167 static void
168 vhost_on_identify (user_t *u)
169 {
170 myuser_t *mu = u->myuser;
171 metadata *md;
172
173 /* NO CLOAK?!*$*%*&&$(!& */
174 if (!(md = mu->find_metadata ("private:usercloak")))
175 return;
176
177 do_sethost (u, md->value);
178 }
179
180 bool
181 _modinit (module *m)
182 {
183 user_t::callback.identify.attach (vhost_on_identify);
184
185 ns_cmdtree << ns_vhost;
186 ns_cmdtree << ns_listvhost;
187
188 help_addentry (ns_helptree, "VHOST", "help/nickserv/vhost", NULL);
189 help_addentry (ns_helptree, "LISTVHOST", "help/nickserv/listvhost", NULL);
190
191 return true;
192 }
193
194 void
195 _moddeinit (void)
196 {
197 user_t::callback.identify.detach (vhost_on_identify);
198
199 ns_cmdtree >> ns_vhost;
200 ns_cmdtree >> ns_listvhost;
201
202 help_delentry (ns_helptree, "VHOST");
203 help_delentry (ns_helptree, "LISTVHOST");
204 }