ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/nickserv/vhost.C
Revision: 1.9
Committed: Sat Sep 22 14:27:28 2007 UTC (19 years, 1 month 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

# User Rev Content
1 pippijn 1.8 /**
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 pippijn 1.4 * Copyright © 2005 William Pitcock <nenolod -at- nenolod.net>
10 pippijn 1.2 * Rights to this code are as documented in doc/pod/license.pod.
11 pippijn 1.1 *
12 pippijn 1.9 * $Id: vhost.C,v 1.8 2007-09-16 18:54:43 pippijn Exp $
13 pippijn 1.1 */
14    
15     #include "atheme.h"
16 pippijn 1.4 #include <ermyth/module.h>
17 pippijn 1.1 #include <account/myuser.h>
18 pippijn 1.4 #include <boost/foreach.hpp>
19 pippijn 1.1
20 pippijn 1.9 static char const rcsid[] = "$Id: vhost.C,v 1.8 2007-09-16 18:54:43 pippijn Exp $";
21 pippijn 1.1
22 pippijn 1.9 REGISTER_MODULE ("nickserv/vhost", false, "The Ermyth Team <http://ermyth.xinutec.org>");
23 pippijn 1.1
24 pippijn 1.4 E cmdvec ns_cmdtree;
25     E helpvec ns_helptree;
26 pippijn 1.1
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 pippijn 1.4 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 pippijn 1.1
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 pippijn 1.4 phandler->sethost_sts (nicksvs.nick, u->nick, u->vhost);
47 pippijn 1.1 }
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 pippijn 1.4 phandler->sethost_sts (nicksvs.nick, u->nick, u->vhost);
57 pippijn 1.1 }
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 pippijn 1.4 phandler->sethost_sts (nicksvs.nick, u->nick, u->host);
73 pippijn 1.1 }
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 pippijn 1.6 command_fail (si, fault::needmoreparams, STR_INVALID_PARAMS, "VHOST");
88     command_fail (si, fault::needmoreparams, _("Syntax: VHOST <nick> [vhost]"));
89 pippijn 1.1 return;
90     }
91    
92     /* find the user... */
93 pippijn 1.5 if (!(mu = myuser_t::find_ext (target)))
94 pippijn 1.1 {
95 pippijn 1.6 command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), target);
96 pippijn 1.1 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 pippijn 1.6 command_fail (si, fault::badparams, _("The vhost provided contains invalid characters."));
115 pippijn 1.1 return;
116     }
117     if (strlen (host) >= HOSTLEN)
118     {
119 pippijn 1.6 command_fail (si, fault::badparams, _("The vhost provided is too long."));
120 pippijn 1.1 return;
121     }
122     p = strrchr (host, '/');
123     if (p != NULL && isdigit (p[1]))
124     {
125 pippijn 1.6 command_fail (si, fault::badparams, _("The vhost provided looks like a CIDR mask."));
126 pippijn 1.1 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 pippijn 1.4 char const * const pattern = parc >= 1 ? parv[0] : "*";
142 pippijn 1.1 myuser_t *mu;
143 pippijn 1.7 metadata *md;
144 pippijn 1.1 int matches = 0;
145    
146     snoop ("LISTVHOST: \2%s\2 by \2%s\2", pattern, get_oper_name (si));
147 pippijn 1.7 foreach (myuser_t::pair_type &mup, myuser_t::map)
148 pippijn 1.4 {
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 pippijn 1.1 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 pippijn 1.4 vhost_on_identify (user_t *u)
169 pippijn 1.1 {
170     myuser_t *mu = u->myuser;
171 pippijn 1.7 metadata *md;
172 pippijn 1.1
173     /* NO CLOAK?!*$*%*&&$(!& */
174     if (!(md = mu->find_metadata ("private:usercloak")))
175     return;
176    
177     do_sethost (u, md->value);
178     }
179 pippijn 1.4
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     }