Remove cruft left behind by removed stats_p_hook.
[seven-1.x.git] / modules / m_grant.c
blobb616cbbd930523034326d99c1e2f6c758fdda3bd
1 /*
2 * Copyright (C) 2006 Jilles Tjoelker
3 * Copyright (C) 2006 Stephen Bennett <spb@gentoo.org>
4 */
6 #include "stdinc.h"
7 #include "modules.h"
8 #include "client.h"
9 #include "ircd.h"
10 #include "send.h"
11 #include "s_user.h"
12 #include "s_serv.h"
13 #include "s_conf.h"
14 #include "s_newconf.h"
16 static int mo_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
17 static int me_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
19 static int do_grant(struct Client *source_p, struct Client *target_p, int addflags, int removeflags, int dooper,
20 int dodeoper, int add_snomask, int remove_snomask);
22 struct Message grant_msgtab = {
23 "GRANT", 0, 0, 0, MFLG_SLOW,
24 { mg_ignore, mg_not_oper, mg_ignore, mg_ignore, {me_grant, 5}, {mo_grant, 3}}
27 mapi_clist_av1 grant_clist[] = { &grant_msgtab, NULL };
29 DECLARE_MODULE_AV1(grant, NULL, NULL, grant_clist, NULL, NULL, "$Revision$");
31 /* copied from src/newconf.c */
32 struct mode_table
34 const char *name;
35 int mode;
38 extern struct mode_table flag_table[];
40 static int
41 mo_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
43 struct Client *target_p;
44 int addflags = 0, removeflags = 0;
45 int dooper = 0, dodeoper = 0;
46 int i, j;
47 int dir;
48 const char *p;
49 char *q;
50 int add_snomask = 0, remove_snomask = 0;
51 char oper_flag_changes[32], snomask_changes[64];
53 if(!IsOperGrant(source_p))
55 sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant");
56 return 0;
59 target_p = find_named_person(parv[1]);
60 if (target_p == NULL)
62 sendto_one_numeric(source_p, ERR_NOSUCHNICK,
63 form_str(ERR_NOSUCHNICK), parv[1]);
64 return 0;
67 for (i = 2; i < parc; i++)
69 p = parv[i];
70 if (*p == '-')
71 dir = MODE_DEL, p++;
72 else if (*p == '+')
73 dir = MODE_ADD, p++;
74 else
75 dir = MODE_ADD;
76 if (!irccmp(p, "oper"))
78 if (dir == MODE_ADD)
79 dooper = 1, dodeoper = 0;
80 else
81 dodeoper = 1, dooper = 0;
82 continue;
84 if (!irccmp(p, "snomask"))
86 add_snomask = parse_snobuf_to_mask(0, parv[++i]);
87 remove_snomask = ~parse_snobuf_to_mask(~0, parv[i]);
88 continue;
91 for (j = 0; flag_table[j].name != NULL; j++)
93 if (!irccmp(p, flag_table[j].name))
95 if (dir == MODE_ADD)
96 addflags |= flag_table[j].mode, removeflags &= ~flag_table[j].mode;
97 else
98 removeflags |= flag_table[j].mode, addflags &= ~flag_table[j].mode;
99 break;
102 if (flag_table[j].name == NULL)
104 sendto_one_notice(source_p, ":Unknown GRANT keyword '%s'", p);
105 return 0;
108 if (((addflags | removeflags) & source_p->operflags) != (addflags | removeflags))
110 sendto_one_notice(source_p, ":You may not change flags you do not have access to");
111 return 0;
114 if (MyClient(target_p))
116 do_grant(source_p, target_p, addflags, removeflags, dooper, dodeoper,
117 add_snomask, remove_snomask);
119 else
121 q = oper_flag_changes;
123 for (i = 0; oper_flagtable[i].flag; ++i)
125 if (addflags & oper_flagtable[i].flag)
126 *q++ = oper_flagtable[i].has;
127 else if (removeflags & oper_flagtable[i].flag)
128 *q++ = oper_flagtable[i].hasnt;
130 if(q == oper_flag_changes)
131 *q++ = '.';
132 *q++ = '\0';
134 strlcpy(snomask_changes, construct_snobuf_changes(add_snomask, remove_snomask), sizeof(snomask_changes));
136 sendto_one(target_p, ":%s ENCAP %s GRANT %s %s %d %d %s",
137 get_id(source_p, target_p), target_p->servptr->name,
138 get_id(target_p, target_p), oper_flag_changes, dooper, dodeoper,
139 snomask_changes);
142 return 0;
145 static int me_grant(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
147 struct Client *target_p;
148 int addflags = 0, removeflags = 0, dooper = 0, dodeoper = 0, add_snomask = 0, remove_snomask = 0;
149 int i = 0;
150 const char *p;
152 target_p = find_person(parv[1]);
153 if (target_p == NULL)
155 sendto_one_numeric(source_p, ERR_NOSUCHNICK,
156 form_str(ERR_NOSUCHNICK), parv[1]);
157 return 0;
160 if (!find_client_shared_conf(source_p, SHARED_GRANT))
162 sendto_one(source_p, ":%s NOTICE %s :*** You don't have an appropriate shared"
163 "block to grant privilege on this server.", me.name, source_p->name);
164 return 0;
167 p = parv[2];
169 for (i = 0; oper_flagtable[i].flag; ++i)
171 if (*p == oper_flagtable[i].has)
172 addflags |= oper_flagtable[i].flag;
173 else if (*p == oper_flagtable[i].hasnt)
174 removeflags |= oper_flagtable[i].flag;
175 else if (*p == '\0' || *p == '.')
176 break;
177 else
178 continue;
179 ++p;
182 dooper = atoi(parv[3]);
183 dodeoper = atoi(parv[4]);
185 add_snomask = parse_snobuf_to_mask(0, parv[5]);
186 remove_snomask = ~parse_snobuf_to_mask(~0, parv[5]);
188 do_grant(source_p, target_p, addflags, removeflags, dooper, dodeoper, add_snomask, remove_snomask);
190 return 0;
194 static int do_grant(struct Client *source_p, struct Client *target_p, int addflags, int removeflags, int dooper,
195 int dodeoper, int add_snomask, int remove_snomask)
197 const char *newparv[4];
198 struct oper_conf oper;
199 int changes = 0;
200 int orig_snomask = target_p->allowed_snomask;
201 char desc[512];
202 int j;
204 if (dodeoper)
206 if (!IsOper(target_p))
207 sendto_one_notice(source_p, ":%s is not an oper",
208 target_p->name);
209 else
211 newparv[0] = target_p->name;
212 newparv[1] = target_p->name;
213 newparv[2] = "-o";
214 newparv[3] = NULL;
215 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
216 "%s is deopering %s",
217 get_oper_name(source_p),
218 get_client_name(target_p, HIDE_IP));
219 sendto_one_notice(target_p, ":%s is deopering you",
220 source_p->name);
221 user_mode(target_p, target_p, 3, newparv);
222 sendto_one_notice(source_p, ":Deopered %s",
223 target_p->name);
224 changes++;
227 else if (dooper)
229 if (IsOper(target_p))
230 sendto_one_notice(source_p, ":%s is already an oper",
231 target_p->name);
232 else
234 desc[0] = '\0';
235 for (j = 0; flag_table[j].name != NULL; j++)
237 if ((addflags & flag_table[j].mode) == flag_table[j].mode)
239 if (desc[0] != '\0')
240 strlcat(desc, " ", sizeof desc);
241 strlcat(desc, "+", sizeof desc);
242 strlcat(desc, flag_table[j].name, sizeof desc);
245 if (desc[0] == '\0')
246 strlcpy(desc, "<none>", sizeof desc);
247 oper.name = "<grant>";
248 oper.username = "";
249 oper.host = "";
250 oper.passwd = "";
251 oper.flags = addflags;
252 oper.umodes = 0;
253 oper.snomask = 0;
254 oper.allowed_snomask = add_snomask;
255 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
256 "%s is opering %s with flags %s and snomask %s",
257 get_oper_name(source_p),
258 get_client_name(target_p, HIDE_IP),
259 desc,
260 construct_snobuf(oper.allowed_snomask));
261 sendto_one_notice(target_p, ":%s is opering you",
262 source_p->name);
263 oper_up(target_p, &oper);
264 sendto_one_notice(source_p, ":Opered %s with flags %s and snomask %s",
265 target_p->name, desc, construct_snobuf(oper.allowed_snomask));
266 changes++;
269 removeflags &= target_p->operflags;
270 addflags &= ~target_p->operflags;
271 remove_snomask &= target_p->allowed_snomask;
272 add_snomask &= ~target_p->allowed_snomask;
273 if ((addflags | removeflags | add_snomask | remove_snomask) != 0)
275 if (!IsOper(target_p))
277 sendto_one_notice(source_p, ":%s is not an oper",
278 target_p->name);
280 else
282 target_p->operflags |= addflags;
283 target_p->operflags &= ~removeflags;
284 target_p->allowed_snomask |= add_snomask;
285 target_p->allowed_snomask &= ~remove_snomask;
286 desc[0] = '\0';
287 for (j = 0; flag_table[j].name != NULL; j++)
289 if ((addflags & flag_table[j].mode) == flag_table[j].mode)
291 if (desc[0] != '\0')
292 strlcat(desc, " ", sizeof desc);
293 strlcat(desc, "+", sizeof desc);
294 strlcat(desc, flag_table[j].name, sizeof desc);
296 else if ((removeflags & flag_table[j].mode) == flag_table[j].mode)
298 if (desc[0] != '\0')
299 strlcat(desc, " ", sizeof desc);
300 strlcat(desc, "-", sizeof desc);
301 strlcat(desc, flag_table[j].name, sizeof desc);
304 if(desc[0] == '\0')
305 strlcpy(desc, "<none>", sizeof desc);
306 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
307 "%s is changing oper flags on %s (%s, snomask %s)",
308 get_oper_name(source_p),
309 get_client_name(target_p, HIDE_IP),
310 desc,
311 construct_snobuf_changes(target_p->allowed_snomask & ~orig_snomask,
312 orig_snomask & ~target_p->allowed_snomask));
313 sendto_one_notice(target_p, ":%s is changing oper flags on you: %s, snomask %s",
314 source_p->name, desc, construct_snobuf_changes(target_p->allowed_snomask & ~orig_snomask,
315 orig_snomask & ~target_p->allowed_snomask));
316 sendto_one_notice(source_p, ":Changed oper flags on %s: %s, snomask %s",
317 target_p->name, desc, construct_snobuf_changes(target_p->allowed_snomask & ~orig_snomask,
318 orig_snomask & ~target_p->allowed_snomask));
320 sendto_server(source_p, NULL, CAP_TS6, NOCAPS, ":%s ENCAP * OPER %s",
321 get_id(target_p, target_p), get_oper_privs(target_p->operflags));
323 sendto_server(source_p, NULL, NOCAPS, CAP_TS6, ":%s ENCAP * OPER %s",
324 target_p->name, get_oper_privs(target_p->operflags));
326 /* fix up any umodes/snomasks they may not have
327 * anymore */
328 newparv[0] = target_p->name;
329 newparv[1] = target_p->name;
330 newparv[2] = "+";
331 newparv[3] = NULL;
332 user_mode(target_p, target_p, 3, newparv);
333 changes++;
336 if (!changes)
337 sendto_one_notice(source_p, ":Oper flags on %s unchanged",
338 target_p->name);
340 return 0;