]>
Commit | Line | Data |
---|---|---|
3e3692bf CP |
1 | /* |
2 | * NOperserv v0.01 | |
3 | * | |
4 | * A replacement for Germania's ageing Operservice2 | |
5 | * | |
6 | * Copyright (C) 2005 Chris Porter. | |
7 | */ | |
8 | ||
9 | #include "../localuser/localuser.h" | |
10 | #include "../lib/irc_string.h" | |
d7a70850 | 11 | #include "../lib/strlfunc.h" |
87698d77 | 12 | #include "../lib/version.h" |
fb17e427 | 13 | #include "../authext/authext.h" |
3e3692bf CP |
14 | #include "noperserv.h" |
15 | #include "noperserv_db.h" | |
16 | #include "noperserv_hooks.h" | |
17 | #include "noperserv_policy.h" | |
18 | ||
19 | #include <stdio.h> | |
20 | #include <string.h> | |
21 | #include <stdarg.h> | |
22 | ||
70b0a4e5 | 23 | MODULE_VERSION(""); |
87698d77 | 24 | |
3e3692bf CP |
25 | #define FLAGBUFLEN 100 |
26 | ||
27 | #define NO_FOUND_NICKNAME 1 | |
28 | #define NO_FOUND_AUTHNAME 2 | |
29 | ||
30 | const flag no_commandflags[] = { | |
31 | { 'o', __NO_OPER }, | |
32 | { 't', __NO_TRUST }, | |
33 | { 's', __NO_STAFF }, | |
34 | { 'S', __NO_SEC }, | |
35 | { 'd', __NO_DEVELOPER }, | |
36 | { 'L', __NO_LEGACY }, | |
37 | { 'O', __NO_OPERED }, | |
38 | { 'r', __NO_AUTHED }, | |
39 | { 'R', __NO_ACCOUNT }, | |
3f5ead93 | 40 | { 'Y', __NO_RELAY }, |
3e3692bf CP |
41 | { '\0', 0 } |
42 | }; | |
43 | ||
44 | const flag no_userflags[] = { | |
45 | { 'o', __NO_OPER }, | |
46 | { 't', __NO_TRUST }, | |
47 | { 's', __NO_STAFF }, | |
48 | { 'S', __NO_SEC }, | |
49 | { 'd', __NO_DEVELOPER }, | |
3f5ead93 | 50 | { 'Y', __NO_RELAY }, |
3e3692bf CP |
51 | { '\0', 0 } |
52 | }; | |
53 | ||
54 | const flag no_noticeflags[] = { | |
55 | { 'm', NL_MANAGEMENT }, /* hello, password, userflags, noticeflags */ | |
56 | { 't', NL_TRUSTS }, /* trust stuff... */ | |
a50e1bf1 CP |
57 | { 'k', NL_KICKKILLS }, /* KICK/KILL commands */ |
58 | { 'I', NL_MISC }, /* misc commands */ | |
3e3692bf CP |
59 | { 'g', NL_GLINES }, /* GLINE commands */ |
60 | { 'h', NL_HITS }, /* Where a gline or kill is set automatically by the bot */ | |
61 | { 'c', NL_CLONING }, /* Clone detection */ | |
62 | { 'C', NL_CLEARCHAN }, /* When someone clearchans */ | |
63 | { 'f', NL_FAKEUSERS }, /* Fakeuser addition */ | |
64 | { 'b', NL_BROADCASTS }, /* Broadcast/mbroadcast/sbroadcast */ | |
65 | { 'o', NL_OPERATIONS }, /* insmod/rmmod/etc */ | |
66 | { 'O', NL_OPERING }, /* when someone opers */ | |
67 | { 'n', NL_NOTICES }, /* turn off to receive notices instead of privmsgs */ | |
68 | { 'A', NL_ALL_COMMANDS }, /* all commands sent */ | |
69 | { '\0', 0 } | |
70 | }; | |
71 | ||
72 | int noperserv_hello(void *sender, int cargc, char **cargv); | |
73 | int noperserv_noticeflags(void *sender, int cargc, char **cargv); | |
74 | int noperserv_userflags(void *sender, int cargc, char **cargv); | |
75 | int noperserv_deluser(void *sender, int cargc, char **cargv); | |
76 | void noperserv_oper_detection(int hooknum, void *arg); | |
bb4b25ee | 77 | void noperserv_reply(nick *np, char *format, ...) __attribute__ ((format (printf, 2, 3))); |
3e3692bf | 78 | |
7a32ca6e CP |
79 | int init = 0; |
80 | ||
3e3692bf | 81 | void _init() { |
7a32ca6e CP |
82 | if(!noperserv_load_db()) |
83 | return; | |
3e3692bf | 84 | |
7078aa50 | 85 | noperserv_ext = registerauthnameext("noperserv", 1); |
3e3692bf CP |
86 | |
87 | noperserv_setup_hooks(); | |
88 | ||
89 | registercontrolhelpcmd("hello", NO_OPERED | NO_AUTHED, 1, &noperserv_hello, "Syntax: HELLO ?nickname|#authname?\nCreates an account on the service for the specified nick, or if one isn't supplied, your nickname."); | |
cc3768c4 CP |
90 | registercontrolhelpcmd("userflags", NO_ACCOUNT, 2, &noperserv_userflags, |
91 | "Syntax: USERFLAGS <nickname|#authname> ?modifications?\n" | |
92 | " Views and modifies user permissions.\n" | |
93 | " If no nickname or authname is supplied, you are substituted for it.\n" | |
94 | " If no flags are supplied, flags are just displayed instead of modified." | |
95 | " Flags:\n" | |
96 | " +o: Operator\n" | |
97 | " +s: Staff member\n" | |
98 | " +S: Security team member\n" | |
99 | " +d: NOperserv developer\n" | |
100 | " +t: Trust queue worker\n" | |
3f5ead93 | 101 | " +Y: Relay\n" |
cc3768c4 CP |
102 | " Additional flags may show up in SHOWCOMMANDS but are not userflags as such:\n" |
103 | " +r: Authed user\n" | |
a50e1bf1 CP |
104 | " +R: Registered NOperserv user\n" |
105 | " +O: Must be /OPER'ed\n" | |
cc3768c4 CP |
106 | " +L: Legacy command\n" |
107 | ); | |
3e3692bf CP |
108 | registercontrolhelpcmd("noticeflags", NO_ACCOUNT, 1, &noperserv_noticeflags, |
109 | "Syntax: NOTICEFLAGS ?(nickname|#authname)|flags?\n" | |
110 | " This command can view and modify your own notice flags, and view that of other users.\n" | |
111 | " Flags:\n" | |
112 | " +m: Management (hello, password, userflags, noticeflags)\n" | |
113 | " +t: Trusts\n" | |
a50e1bf1 | 114 | " +k: KICK/KILL commands\n" |
3e3692bf | 115 | " +g: GLINE commands\n" |
35070c19 | 116 | " +h: Shows when glines are set by code (hits)\n" |
3e3692bf CP |
117 | " +c: Clone information\n" |
118 | " +C: CLEARCHAN command\n" | |
cc3768c4 | 119 | " +f: FAKEUSER commands\n" |
3e3692bf CP |
120 | " +b: BROADCAST commands\n" |
121 | " +o: Operation commands, such as insmod, rmmod, die, etc\n" | |
122 | " +O: /OPER\n" | |
9aacd544 | 123 | " +I: Misc commands (resync, etc)\n" |
3e3692bf | 124 | " +n: Sends notices instead of privmsgs\n" |
cc3768c4 | 125 | " +A: Every single command sent to the service (spammy)\n" |
3e3692bf CP |
126 | ); |
127 | ||
128 | registercontrolhelpcmd("deluser", NO_OPERED | NO_ACCOUNT, 2, &noperserv_deluser, "Syntax: DELUSER <nickname|#authname>\nDeletes the specified user."); | |
129 | registerhook(HOOK_NICK_MODEOPER, &noperserv_oper_detection); | |
7a32ca6e CP |
130 | |
131 | init = 1; | |
3e3692bf CP |
132 | } |
133 | ||
134 | #ifdef BROKEN_DLCLOSE | |
135 | void __fini() { | |
136 | #else | |
137 | void _fini() { | |
138 | #endif | |
7a32ca6e CP |
139 | if(!init) |
140 | return; | |
141 | ||
3e3692bf CP |
142 | deregisterhook(HOOK_NICK_MODEOPER, &noperserv_oper_detection); |
143 | ||
144 | deregistercontrolcmd("noticeflags", &noperserv_noticeflags); | |
145 | deregistercontrolcmd("userflags", &noperserv_userflags); | |
146 | deregistercontrolcmd("noticeflags", &noperserv_noticeflags); | |
7821bd5e CP |
147 | deregistercontrolcmd("hello", &noperserv_hello); |
148 | deregistercontrolcmd("deluser", &noperserv_deluser); | |
3e3692bf CP |
149 | |
150 | noperserv_cleanup_hooks(); | |
151 | ||
152 | noperserv_cleanup_db(); | |
153 | ||
7078aa50 | 154 | releaseauthnameext(noperserv_ext); |
3e3692bf CP |
155 | } |
156 | ||
157 | /* @test */ | |
158 | int noperserv_hello(void *sender, int cargc, char **cargv) { | |
7078aa50 | 159 | authname *newaccount = NULL; |
3e3692bf | 160 | no_autheduser *au; |
3e3692bf CP |
161 | nick *np = (nick *)sender, *np2, *target = NULL; |
162 | ||
163 | if(cargc == 0) { | |
7078aa50 | 164 | newaccount = np->auth; |
3e3692bf CP |
165 | } else { |
166 | if(cargv[0][0] == '#') { | |
7b1a4a73 | 167 | authname *a = getauthbyname(cargv[0] + 1); |
fb17e427 | 168 | if(!a) { |
3e3692bf CP |
169 | controlreply(np, "Cannot find anyone with that authname on the network."); |
170 | return CMD_ERROR; | |
171 | } | |
7078aa50 | 172 | newaccount = a; |
3e3692bf CP |
173 | } else { |
174 | target = getnickbynick(cargv[0]); | |
175 | if(!target) { | |
176 | controlreply(np, "Supplied nickname is not on the network."); | |
177 | return CMD_ERROR; | |
178 | } | |
7078aa50 | 179 | newaccount = target->auth; |
3e3692bf CP |
180 | } |
181 | } | |
7078aa50 GB |
182 | if(!newaccount) { |
183 | controlreply(np, "Supplied user is not authed with the network."); | |
184 | return CMD_ERROR; | |
185 | } | |
3e3692bf CP |
186 | au = noperserv_get_autheduser(newaccount); |
187 | if(au) { | |
188 | controlreply(np, "Authname already registered."); | |
189 | return CMD_ERROR; | |
190 | } | |
191 | ||
7078aa50 | 192 | au = noperserv_new_autheduser(newaccount->userid, newaccount->name); |
3e3692bf CP |
193 | if(!au) { |
194 | controlreply(np, "Memory allocation error."); | |
195 | return CMD_ERROR; | |
196 | } | |
197 | ||
198 | if(noperserv_get_autheduser_count() == 1) { | |
199 | au->authlevel = NO_FIRST_USER_LEVEL; | |
200 | au->noticelevel = NO_FIRST_USER_DEFAULT_NOTICELEVEL; | |
201 | } else { | |
202 | au->authlevel = NO_DEFAULT_LEVEL; | |
203 | au->noticelevel = NO_DEFAULT_NOTICELEVEL; | |
204 | } | |
205 | ||
3e3692bf CP |
206 | noperserv_update_autheduser(au); |
207 | ||
7078aa50 GB |
208 | for(np2=newaccount->nicks;np2;np2=np2->nextbyauthname) { |
209 | controlreply(np2, "An account has been created for you (auth %s).", au->authname->name); | |
210 | if(NOGetAuthLevel(au)) | |
211 | controlreply(np2, "User flags: %s", printflags(NOGetAuthLevel(au), no_userflags)); | |
212 | controlreply(np2, "Notice flags: %s", printflags(NOGetNoticeLevel(au), no_noticeflags)); | |
213 | } | |
3e3692bf | 214 | |
7078aa50 GB |
215 | if(np->auth==newaccount) { /* send a message to the person who HELLO'ed if we haven't already been told */ |
216 | controlreply(np, "Account created for auth %s.", au->authname->name); | |
3e3692bf CP |
217 | if(NOGetAuthLevel(au)) |
218 | controlreply(np, "User flags: %s", printflags(NOGetAuthLevel(au), no_userflags)); | |
219 | controlreply(np, "Notice flags: %s", printflags(NOGetNoticeLevel(au), no_noticeflags)); | |
220 | controlreply(np, "Instructions sent to all authed users."); | |
7078aa50 | 221 | } else if(newaccount->nicks && newaccount->nicks->next) { /* if we have already been told, tell the user it was sent to more than themselves */ |
3e3692bf CP |
222 | controlreply(np, "Instructions sent to all authed users."); |
223 | } | |
224 | ||
7078aa50 | 225 | controlwall(NO_OPERED, NL_MANAGEMENT, "%s/%s just HELLO'ed: %s", np->nick, np->authname, au->authname->name); |
3e3692bf CP |
226 | return CMD_OK; |
227 | } | |
228 | ||
229 | no_autheduser *noperserv_autheduser_from_command(nick *np, char *command, int *typefound, char **returned) { | |
230 | no_autheduser *au; | |
7078aa50 | 231 | authname *anp; |
3e3692bf | 232 | if(command[0] == '#') { |
7078aa50 GB |
233 | anp = findauthnamebyname(command + 1); |
234 | if(!anp) { | |
235 | controlreply(np, "Authname not found."); | |
236 | return NULL; | |
237 | } | |
238 | au = noperserv_get_autheduser(anp); | |
3e3692bf CP |
239 | if(!au) { |
240 | controlreply(np, "Authname not found."); | |
241 | } else { | |
242 | *typefound = NO_FOUND_AUTHNAME; | |
7078aa50 | 243 | *returned = au->authname->name; |
3e3692bf CP |
244 | return au; |
245 | } | |
246 | } else { | |
247 | nick *np2 = getnickbynick(command); | |
248 | if(!np2) { | |
249 | controlreply(np, "Nickname not on the network."); | |
7078aa50 | 250 | return NULL; |
3e3692bf CP |
251 | } |
252 | if(!IsAccount(np2)) { | |
253 | controlreply(np, "User is not authed with the network."); | |
7078aa50 | 254 | return NULL; |
3e3692bf CP |
255 | } |
256 | au = NOGetAuthedUser(np2); | |
257 | if(!au) { | |
258 | controlreply(np, "User does not have an account."); | |
259 | } else { | |
260 | *typefound = NO_FOUND_NICKNAME; | |
261 | *returned = np2->nick; | |
262 | return au; | |
263 | } | |
264 | } | |
265 | ||
266 | return NULL; | |
267 | } | |
268 | ||
269 | int noperserv_noticeflags(void *sender, int cargc, char **cargv) { | |
7078aa50 | 270 | nick *np2, *np = (nick *)sender; |
3e3692bf CP |
271 | no_autheduser *au; |
272 | ||
273 | if(cargc == 1) { | |
274 | if((cargv[0][0] == '+') || (cargv[0][0] == '-')) { | |
275 | int ret; | |
276 | au = NOGetAuthedUser(np); | |
277 | flag_t fwas = NOGetNoticeLevel(au), permittedchanges = noperserv_policy_permitted_noticeflags(au); | |
278 | ||
279 | ret = setflags(&au->noticelevel, permittedchanges, cargv[0], no_noticeflags, REJECT_DISALLOWED | REJECT_UNKNOWN); | |
280 | if(ret != REJECT_UNKNOWN) { | |
281 | if(ret == REJECT_DISALLOWED) { | |
282 | flag_t fnow = fwas; | |
283 | setflags(&fnow, NL_ALL, cargv[0], no_noticeflags, REJECT_NONE); | |
284 | if(fnow == fwas) { | |
285 | controlreply(np, "No changes made to existing flags."); | |
286 | } else { | |
287 | char ourflags[FLAGBUFLEN], ournoticeflags[FLAGBUFLEN]; | |
288 | controlreply(np, "Flag alterations denied."); | |
289 | ||
290 | strlcpy(ourflags, printflags(NOGetAuthLevel(au), no_userflags), sizeof(ourflags)); | |
291 | strlcpy(ournoticeflags, printflags(NOGetNoticeLevel(au), no_noticeflags), sizeof(ournoticeflags)); | |
292 | controlwall(NO_OPER, NL_MANAGEMENT, "%s/%s (%s) attempted to NOTICEFLAGS (%s): %s", np->nick, np->authname, ourflags, ournoticeflags, printflagdiff(fwas, fnow, no_noticeflags)); | |
293 | return CMD_ERROR; | |
294 | } | |
295 | } else if(ret == REJECT_NONE) { | |
296 | if(NOGetNoticeLevel(au) == fwas) { | |
297 | controlreply(np, "No changes made to existing flags."); | |
298 | } else { | |
299 | char ourflags[FLAGBUFLEN], ournoticeflags[FLAGBUFLEN], diff[FLAGBUFLEN * 2 + 1], finalflags[FLAGBUFLEN]; | |
3e3692bf CP |
300 | noperserv_update_autheduser(au); |
301 | controlreply(np, "Flag alterations complete."); | |
302 | ||
303 | strlcpy(ourflags, printflags(NOGetAuthLevel(au), no_userflags), sizeof(ourflags)); | |
304 | strlcpy(ournoticeflags, printflags(fwas, no_noticeflags), sizeof(ournoticeflags)); | |
305 | strlcpy(diff, printflagdiff(fwas, NOGetNoticeLevel(au), no_noticeflags), sizeof(diff)); | |
306 | controlwall(NO_OPER, NL_MANAGEMENT, "%s/%s (%s) successfully used NOTICEFLAGS (%s): %s", np->nick, np->authname, ourflags, ournoticeflags, diff); | |
307 | ||
308 | strlcpy(finalflags, printflags(NOGetNoticeLevel(au), no_noticeflags), sizeof(finalflags)); | |
7078aa50 GB |
309 | for(np2=au->authname->nicks;np2;np2=np2->nextbyauthname) |
310 | if(np2 != np) { | |
311 | controlreply(np2, "!!! %s just used NOTICEFLAGS (%s): %s", np->nick, ournoticeflags, diff); | |
312 | controlreply(np2, "Your notice flags are %s", finalflags); | |
3e3692bf CP |
313 | } |
314 | } | |
315 | } | |
316 | } else { | |
317 | controlreply(np, "Unknown flag(s) supplied."); | |
318 | return CMD_ERROR; | |
319 | } | |
320 | } else { | |
321 | int typefound; | |
322 | char *itemfound; | |
323 | au = noperserv_autheduser_from_command(np, cargv[0], &typefound, &itemfound); | |
324 | if(!au) | |
325 | return CMD_ERROR; | |
326 | ||
327 | if(au != NOGetAuthedUser(np)) { | |
328 | controlreply(np, "Notice flags for %s %s are: %s", typefound==NO_FOUND_NICKNAME?"user":"authname", itemfound, printflags(NOGetNoticeLevel(au), no_noticeflags)); | |
329 | return CMD_OK; | |
330 | } | |
331 | } | |
332 | } else { | |
333 | au = NOGetAuthedUser(np); | |
334 | } | |
335 | ||
336 | if(!au) /* shouldn't happen */ | |
337 | return CMD_ERROR; | |
338 | ||
339 | controlreply(np, "Your notice flags are: %s", printflags(NOGetNoticeLevel(au), no_noticeflags)); | |
340 | ||
341 | return CMD_OK; | |
342 | } | |
343 | ||
344 | /* @test */ | |
345 | int noperserv_deluser(void *sender, int cargc, char **cargv) { | |
7078aa50 | 346 | nick *np2, *np = (nick *)sender; |
3e3692bf CP |
347 | no_autheduser *target /* target user */, *au = NOGetAuthedUser(np); /* user executing command */ |
348 | char *userreturned = NULL; /* nickname or authname of the target, pulled from the db */ | |
349 | int typefound; /* whether it was an authname or a username */ | |
3e3692bf CP |
350 | char targetflags[FLAGBUFLEN], ourflags[FLAGBUFLEN], deleteduser[NOMax(ACCOUNTLEN, NICKLEN) + 1]; |
351 | ||
352 | if(cargc != 1) | |
353 | return CMD_USAGE; | |
354 | ||
355 | target = noperserv_autheduser_from_command(np, cargv[0], &typefound, &userreturned); | |
356 | if(!target) | |
357 | return CMD_ERROR; | |
358 | ||
359 | strlcpy(targetflags, printflags(NOGetAuthLevel(target), no_userflags), sizeof(targetflags)); | |
360 | strlcpy(ourflags, printflags(NOGetAuthLevel(au), no_userflags), sizeof(ourflags)); | |
361 | ||
362 | /* we have to copy it as it might point to an autheduser, which we're about to delete */ | |
363 | strlcpy(deleteduser, userreturned, sizeof(deleteduser)); | |
364 | ||
365 | /* we have to check if target != au, because if successful policy_modification_permitted just returns the flags we're allowed | |
366 | to modify, if we have no flags we won't be able to delete ourselves */ | |
367 | if((target != au) && !noperserv_policy_permitted_modifications(au, target)) { | |
368 | controlreply(np, "Deletion denied."); | |
7078aa50 | 369 | controlwall(NO_OPER, NL_MANAGEMENT, "%s/%s (%s) attempted to DELUSER %s (%s)", np->nick, np->authname, ourflags, target->authname->name, targetflags); |
3e3692bf CP |
370 | |
371 | return CMD_ERROR; | |
372 | } | |
373 | ||
7078aa50 GB |
374 | for(np2=target->authname->nicks;np2;np2=np2->nextbyauthname) |
375 | if(np2 != np) | |
376 | controlreply(np2, "!!! %s/%s (%s) just DELUSERed you.", np->nick, np->authname, ourflags); | |
3e3692bf CP |
377 | |
378 | noperserv_delete_autheduser(target); | |
379 | ||
7078aa50 | 380 | controlwall(NO_OPER, NL_MANAGEMENT, "%s/%s (%s) successfully used DELUSER on %s (%s)", np->nick, np->authname, ourflags, deleteduser, targetflags); |
3e3692bf CP |
381 | |
382 | if(target == au) { | |
383 | controlreply(np, "You have been deleted."); | |
384 | } else { | |
385 | controlreply(np, "%s %s deleted.", typefound==NO_FOUND_AUTHNAME?"Auth":"User", deleteduser); | |
386 | } | |
387 | ||
388 | return CMD_OK; | |
389 | } | |
390 | ||
391 | /* @test */ | |
392 | /* this command needs LOTS of checking */ | |
393 | int noperserv_userflags(void *sender, int cargc, char **cargv) { | |
7078aa50 | 394 | nick *np2, *np = (nick *)sender; |
3e3692bf CP |
395 | no_autheduser *au = NOGetAuthedUser(np), *target = NULL; |
396 | char *flags = NULL, *nicktarget = NULL; | |
397 | int typefound; | |
398 | ||
399 | if(cargc == 0) { | |
400 | target = au; | |
401 | } else if(cargc == 1) { | |
402 | if((cargv[0][0] == '+') || (cargv[0][0] == '-')) { /* modify our own */ | |
403 | flags = cargv[0]; | |
404 | target = au; | |
405 | } else { /* viewing someone elses */ | |
406 | nicktarget = cargv[0]; | |
407 | } | |
408 | } else if(cargc == 2) { | |
409 | nicktarget = cargv[0]; | |
410 | flags = cargv[1]; | |
411 | } else { | |
412 | return CMD_USAGE; | |
413 | } | |
414 | ||
415 | if(nicktarget) { | |
416 | target = noperserv_autheduser_from_command(np, nicktarget, &typefound, &nicktarget); | |
417 | if(!target) | |
418 | return CMD_ERROR; | |
419 | } | |
420 | ||
421 | if(flags) { | |
422 | int ret; | |
423 | flag_t permitted = noperserv_policy_permitted_modifications(au, target), fwas = NOGetAuthLevel(target), fours = NOGetAuthLevel(au); | |
424 | ||
425 | ret = setflags(&target->authlevel, permitted, flags, no_userflags, REJECT_DISALLOWED | REJECT_UNKNOWN); | |
426 | if(ret != REJECT_UNKNOWN) { | |
427 | if(ret == REJECT_DISALLOWED) { | |
428 | flag_t fnow = fwas; | |
429 | setflags(&fnow, NO_ALL_FLAGS, flags, no_userflags, REJECT_NONE); | |
430 | if(fnow == fwas) { | |
431 | controlreply(np, "No changes made to existing flags."); | |
432 | } else { | |
433 | char targetflags[FLAGBUFLEN], ourflags[FLAGBUFLEN]; | |
434 | controlreply(np, "Flag alterations denied."); | |
435 | ||
436 | strlcpy(targetflags, printflags(fwas, no_userflags), sizeof(targetflags)); | |
437 | strlcpy(ourflags, printflags(fours, no_userflags), sizeof(ourflags)); | |
438 | ||
7078aa50 | 439 | controlwall(NO_OPER, NL_MANAGEMENT, "%s/%s (%s) attempted to use USERFLAGS on %s (%s): %s", np->nick, np->authname, ourflags, target->authname->name, targetflags, printflagdiff(fwas, fnow, no_userflags)); |
3e3692bf CP |
440 | return CMD_ERROR; |
441 | } | |
442 | } else if(ret == REJECT_NONE) { | |
443 | if(NOGetAuthLevel(target) == fwas) { | |
444 | controlreply(np, "No changes made to existing flags."); | |
445 | } else { | |
446 | char targetflags[FLAGBUFLEN], ourflags[FLAGBUFLEN], finalflags[FLAGBUFLEN]; | |
3e3692bf CP |
447 | |
448 | noperserv_policy_update_noticeflags(fwas, target); | |
449 | noperserv_update_autheduser(target); | |
450 | ||
451 | controlreply(np, "Flag alterations complete."); | |
452 | ||
453 | strlcpy(targetflags, printflags(fwas, no_userflags), sizeof(targetflags)); | |
454 | strlcpy(ourflags, printflags(fours, no_userflags), sizeof(ourflags)); | |
455 | ||
7078aa50 | 456 | controlwall(NO_OPER, NL_MANAGEMENT, "%s/%s (%s) successfully used USERFLAGS on %s (%s): %s", np->nick, np->authname, ourflags, target->authname->name, targetflags, printflagdiff(fwas, NOGetAuthLevel(target), no_userflags)); |
3e3692bf CP |
457 | |
458 | strlcpy(finalflags, printflags(NOGetAuthLevel(target), no_userflags), sizeof(finalflags)); | |
7078aa50 GB |
459 | for(np2=target->authname->nicks;np2;np2=np2->nextbyauthname) |
460 | if(np2 != np) { | |
461 | controlreply(np2, "!!! %s/%s (%s) just used USERFLAGS on you (%s): %s", np->nick, np->authname, ourflags, targetflags, printflagdiff(fwas, NOGetAuthLevel(target), no_userflags)); | |
462 | controlreply(np2, "Your user flags are now: %s", finalflags); | |
463 | controlreply(np2, "Your notice flags are now: %s", printflags(target->noticelevel, no_noticeflags)); | |
3e3692bf CP |
464 | } |
465 | } | |
466 | } | |
467 | } else { | |
468 | controlreply(np, "Unknown flag(s) supplied."); | |
469 | return CMD_ERROR; | |
470 | } | |
471 | } | |
472 | ||
473 | if(target != au) { | |
474 | controlreply(np, "User flags for %s %s: %s", typefound==NO_FOUND_AUTHNAME?"auth":"user", nicktarget, printflags(NOGetAuthLevel(target), no_userflags)); | |
475 | controlreply(np, "Notice flags for %s %s: %s", typefound==NO_FOUND_AUTHNAME?"auth":"user", nicktarget, printflags(target->noticelevel, no_noticeflags)); | |
476 | } else { | |
477 | controlreply(np, "Your user flags are: %s", printflags(NOGetAuthLevel(target), no_userflags)); | |
478 | controlreply(np, "Your notice flags are: %s", printflags(target->noticelevel, no_noticeflags)); | |
479 | } | |
480 | ||
481 | return CMD_OK; | |
482 | } | |
483 | ||
484 | void noperserv_oper_detection(int hooknum, void *arg) { | |
510b754a | 485 | nick *np = (nick *)arg; |
3e3692bf | 486 | |
3e3692bf | 487 | if(np->umodes & UMODE_OPER) { |
510b754a CP |
488 | if(np->opername && strcmp(np->opername->content, "-")) { |
489 | controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just OPERed as %s", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"", np->opername->content); | |
490 | } else { | |
3e3692bf | 491 | controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just OPERed", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:""); |
510b754a CP |
492 | } |
493 | } else { | |
494 | controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just DEOPERed", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:""); | |
3e3692bf CP |
495 | } |
496 | } |