2 # Parent 49deac8a9792a5f312d2ebead245bcaa5f20f60c
4 diff -r 49deac8a9792 include/client.h
5 --- a/include/client.h Fri Jul 19 22:50:34 2013 +0100
6 +++ b/include/client.h Fri Jul 19 22:51:32 2013 +0100
8 PRIV_FORCE_OPMODE, /**< can hack modes on quarantined channels */
9 PRIV_FORCE_LOCAL_OPMODE, /**< can hack modes on quarantined local channels */
10 PRIV_APASS_OPMODE, /**< can hack modes +A/-A/+U/-U */
11 + PRIV_CHANSERV, /* oper can set usermode +k */
12 + PRIV_XTRA_OPER, /* oper can set usermode +X */
13 + PRIV_NOIDLE, /* oper can set usermode +I */
14 + PRIV_FREEFORM, /* oper can use freeform sethost */
15 + PRIV_PARANOID, /* oper can set paranoid */
16 + PRIV_CHECK, /* oper can use /check */
17 + PRIV_WALL, /* oper can use /wallusers, /wallops */
18 + PRIV_CLOSE, /* oper can use /close */
19 + PRIV_ROUTE, /* oper can use /connect/squit NOTE: you need serverinfo priv to do remote connect */
20 + PRIV_ROUTEINFO, /* oper can use /map, /trace, /asll, /links and view jupe list */
21 + PRIV_USER_PRIVACY, /* oper can bypass user privacy +x etc gives i.e. see real ip's */
22 + PRIV_CHANNEL_PRIVACY, /* oper can bypass channel privacy i.e. can see modes on channels they are not on and channel keys */
23 + PRIV_SERVERINFO, /* oper can use /get, /stats, /hash, retrieve remote information */
24 PRIV_LAST_PRIV /**< number of privileges */
27 diff -r 49deac8a9792 ircd/channel.c
28 --- a/ircd/channel.c Fri Jul 19 22:50:34 2013 +0100
29 +++ b/ircd/channel.c Fri Jul 19 22:51:32 2013 +0100
32 if (previous_parameter)
34 - if (is_chan_op(cptr, chptr) || IsServer(cptr) || IsOper(cptr)) {
35 + if (is_chan_op(cptr, chptr) || IsServer(cptr) || (IsOper(cptr) && HasPriv(cptr, PRIV_CHANNEL_PRIVACY))) {
36 strcat(pbuf, chptr->mode.key);
39 diff -r 49deac8a9792 ircd/client.c
40 --- a/ircd/client.c Fri Jul 19 22:50:34 2013 +0100
41 +++ b/ircd/client.c Fri Jul 19 22:51:32 2013 +0100
43 FlagClr(&privs_global, PRIV_BADCHAN);
44 FlagClr(&privs_global, PRIV_LOCAL_BADCHAN);
45 FlagClr(&privs_global, PRIV_APASS_OPMODE);
46 + FlagClr(&privs_global, PRIV_GLINE);
47 + FlagClr(&privs_global, PRIV_REHASH);
48 + FlagClr(&privs_global, PRIV_DIE);
49 + FlagClr(&privs_global, PRIV_RESTART);
50 + FlagClr(&privs_global, PRIV_JUPE);
52 memset(&privs_local, 0, sizeof(privs_local));
53 FlagSet(&privs_local, PRIV_CHAN_LIMIT);
55 P(BADCHAN), P(LOCAL_BADCHAN), P(SEE_CHAN), P(PROPAGATE),
56 P(DISPLAY), P(SEE_OPERS), P(WIDE_GLINE), P(LIST_CHAN),
57 P(FORCE_OPMODE), P(FORCE_LOCAL_OPMODE), P(APASS_OPMODE),
58 + P(CHANSERV), P(XTRA_OPER), P(NOIDLE), P(FREEFORM),
59 + P(PARANOID), P(CHECK), P(WALL), P(CLOSE),
60 + P(ROUTE), P(ROUTEINFO), P(SERVERINFO), P(CHANNEL_PRIVACY),
65 diff -r 49deac8a9792 ircd/gline.c
66 --- a/ircd/gline.c Fri Jul 19 22:50:34 2013 +0100
67 +++ b/ircd/gline.c Fri Jul 19 22:51:32 2013 +0100
69 get_client_name(acptr, SHOW_IP));
71 /* and get rid of him */
72 - /* Asuka - Reimplement HEAD_IN_SAND_GLINE from Lain */
73 - if ((tval = exit_client_msg(cptr, acptr, &me,
74 - feature_bool(FEAT_HIS_GLINE) ? "G-lined" : "G-lined (%s)", gline->gl_reason)))
75 + if ((tval = exit_client_msg(cptr, acptr, &me, "G-lined (%s)", gline->gl_reason)))
76 retval = tval; /* retain killed status */
79 diff -r 49deac8a9792 ircd/hash.c
80 --- a/ircd/hash.c Fri Jul 19 22:50:34 2013 +0100
81 +++ b/ircd/hash.c Fri Jul 19 22:51:32 2013 +0100
87 + if (!HasPriv(sptr, PRIV_SERVERINFO))
88 + return send_reply(sptr, ERR_NOPRIVILEGES);
90 sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Hash Table Statistics", sptr);
92 diff -r 49deac8a9792 ircd/ircd_lexer.l
93 --- a/ircd/ircd_lexer.l Fri Jul 19 22:50:34 2013 +0100
94 +++ b/ircd/ircd_lexer.l Fri Jul 19 22:51:32 2013 +0100
96 { "walk_lchan", TPRIV_WALK_LCHAN },
97 { "wide_gline", TPRIV_WIDE_GLINE },
98 { "whox", TPRIV_WHOX },
99 + { "chanserv", TPRIV_CHANSERV },
100 + { "xtraoper", TPRIV_XTRA_OPER },
101 + { "noidle", TPRIV_NOIDLE },
102 + { "freeform", TPRIV_FREEFORM },
103 + { "paranoid", TPRIV_PARANOID },
104 + { "check", TPRIV_CHECK },
105 + { "wall", TPRIV_WALL },
106 + { "close", TPRIV_CLOSE },
107 + { "route", TPRIV_ROUTE },
108 + { "routeinfo", TPRIV_ROUTEINFO },
109 + { "serverinfo", TPRIV_SERVERINFO },
110 + { "user_privacy", TPRIV_USER_PRIVACY },
111 + { "channel_privacy", TPRIV_CHANNEL_PRIVACY },
115 diff -r 49deac8a9792 ircd/ircd_parser.y
116 --- a/ircd/ircd_parser.y Fri Jul 19 22:50:34 2013 +0100
117 +++ b/ircd/ircd_parser.y Fri Jul 19 22:51:32 2013 +0100
119 %token TPRIV_SEE_CHAN TPRIV_SHOW_INVIS TPRIV_SHOW_ALL_INVIS TPRIV_PROPAGATE
120 %token TPRIV_UNLIMIT_QUERY TPRIV_DISPLAY TPRIV_SEE_OPERS TPRIV_WIDE_GLINE
121 %token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE TPRIV_APASS_OPMODE
122 -%token TPRIV_LIST_CHAN
123 +%token TPRIV_CHANSERV TPRIV_XTRA_OPER TPRIV_NOIDLE TPRIV_FREEFORM TPRIV_PARANOID
124 +%token TPRIV_CHECK TPRIV_WALL TPRIV_CLOSE TPRIV_ROUTE TPRIV_ROUTEINFO TPRIV_SERVERINFO
125 +%token TPRIV_CHANNEL_PRIVACY TPRIV_USER_PRIVACY TPRIV_LIST_CHAN
126 /* and some types... */
128 %type <num> timespec timefactor factoredtimes factoredtime
130 LOCAL { $$ = PRIV_PROPAGATE; invert = 1; } |
131 TPRIV_FORCE_OPMODE { $$ = PRIV_FORCE_OPMODE; } |
132 TPRIV_FORCE_LOCAL_OPMODE { $$ = PRIV_FORCE_LOCAL_OPMODE; } |
133 - TPRIV_APASS_OPMODE { $$ = PRIV_APASS_OPMODE; } ;
134 + TPRIV_APASS_OPMODE { $$ = PRIV_APASS_OPMODE; } |
135 + TPRIV_CHANSERV { $$ = PRIV_CHANSERV; } |
136 + TPRIV_XTRA_OPER { $$ = PRIV_XTRA_OPER; } |
137 + TPRIV_NOIDLE { $$ = PRIV_NOIDLE; } |
138 + TPRIV_FREEFORM { $$ = PRIV_FREEFORM; } |
139 + TPRIV_CHECK { $$ = PRIV_CHECK; } |
140 + TPRIV_WALL { $$ = PRIV_WALL; } |
141 + TPRIV_CLOSE { $$ = PRIV_CLOSE ; } |
142 + TPRIV_ROUTE { $$ = PRIV_ROUTE ; } |
143 + TPRIV_ROUTEINFO { $$ = PRIV_ROUTEINFO ; } |
144 + TPRIV_SERVERINFO { $$ = PRIV_SERVERINFO ; } |
145 + TPRIV_CHANNEL_PRIVACY { $$ = PRIV_CHANNEL_PRIVACY ; } |
146 + TPRIV_USER_PRIVACY { $$ = PRIV_USER_PRIVACY ; } |
147 + TPRIV_PARANOID { $$ = PRIV_PARANOID; } ;
149 yesorno: YES { $$ = 1; } | NO { $$ = 0; };
151 diff -r 49deac8a9792 ircd/m_asll.c
152 --- a/ircd/m_asll.c Fri Jul 19 22:50:34 2013 +0100
153 +++ b/ircd/m_asll.c Fri Jul 19 22:51:32 2013 +0100
158 + if (!HasPriv(sptr, PRIV_ROUTEINFO))
159 + return send_reply(sptr, ERR_NOPRIVILEGES);
162 return need_more_params(sptr, "ASLL");
164 diff -r 49deac8a9792 ircd/m_check.c
165 --- a/ircd/m_check.c Fri Jul 19 22:50:34 2013 +0100
166 +++ b/ircd/m_check.c Fri Jul 19 22:51:32 2013 +0100
168 struct Client *acptr;
169 int flags = CHECK_SHOWUSERS, i;
171 + if (!HasPriv(sptr, PRIV_CHECK))
172 + return send_reply(sptr, ERR_NOPRIVILEGES);
175 send_reply(sptr, ERR_NEEDMOREPARAMS, "CHECK");
177 diff -r 49deac8a9792 ircd/m_close.c
178 --- a/ircd/m_close.c Fri Jul 19 22:50:34 2013 +0100
179 +++ b/ircd/m_close.c Fri Jul 19 22:51:32 2013 +0100
181 assert(cptr == sptr);
182 assert(IsAnOper(sptr));
184 + if (!HasPriv(sptr, PRIV_CLOSE))
185 + return send_reply(sptr, ERR_NOPRIVILEGES);
187 return send_reply(sptr, RPL_CLOSEEND,
188 net_close_unregistered_connections(sptr));
190 diff -r 49deac8a9792 ircd/m_connect.c
191 --- a/ircd/m_connect.c Fri Jul 19 22:50:34 2013 +0100
192 +++ b/ircd/m_connect.c Fri Jul 19 22:51:32 2013 +0100
194 assert(cptr == sptr);
195 assert(IsAnOper(sptr));
197 + if (!HasPriv(sptr, PRIV_ROUTE))
198 + return send_reply(sptr, ERR_NOPRIVILEGES);
201 return need_more_params(sptr, "CONNECT");
203 diff -r 49deac8a9792 ircd/m_get.c
204 --- a/ircd/m_get.c Fri Jul 19 22:50:34 2013 +0100
205 +++ b/ircd/m_get.c Fri Jul 19 22:51:32 2013 +0100
208 int mo_get(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
210 + if (!HasPriv(sptr, PRIV_SERVERINFO))
211 + return send_reply(sptr, ERR_NOPRIVILEGES);
213 return feature_get(sptr, (const char* const*)parv + 1, parc - 1);
215 diff -r 49deac8a9792 ircd/m_gline.c
216 --- a/ircd/m_gline.c Fri Jul 19 22:50:34 2013 +0100
217 +++ b/ircd/m_gline.c Fri Jul 19 22:51:32 2013 +0100
220 char *mask = parv[1], *target = 0, *reason = 0, *end;
223 - return gline_list(sptr, 0);
225 + if (!HasPriv(sptr, PRIV_SERVERINFO))
226 + return send_reply(sptr, ERR_NOPRIVILEGES);
228 + return gline_list(sptr, 0);
233 diff -r 49deac8a9792 ircd/m_jupe.c
234 --- a/ircd/m_jupe.c Fri Jul 19 22:50:34 2013 +0100
235 +++ b/ircd/m_jupe.c Fri Jul 19 22:51:32 2013 +0100
238 char *server = parv[1], *target = 0, *reason;
242 + if (!HasPriv(sptr, PRIV_ROUTEINFO))
243 + return send_reply(sptr, ERR_NOPRIVILEGES);
244 return jupe_list(sptr, 0);
247 if (*server == '+') {
248 flags |= JUPE_ACTIVE;
249 diff -r 49deac8a9792 ircd/m_links.c
250 --- a/ircd/m_links.c Fri Jul 19 22:50:34 2013 +0100
251 +++ b/ircd/m_links.c Fri Jul 19 22:51:32 2013 +0100
254 struct Client *acptr;
256 - if (feature_bool(FEAT_HIS_LINKS) && !IsAnOper(sptr))
257 + if (feature_bool(FEAT_HIS_LINKS) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_ROUTEINFO))))
259 send_reply(sptr, RPL_ENDOFLINKS, parc < 2 ? "*" : parv[1]);
260 sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s %s", sptr,
261 diff -r 49deac8a9792 ircd/m_map.c
262 --- a/ircd/m_map.c Fri Jul 19 22:50:34 2013 +0100
263 +++ b/ircd/m_map.c Fri Jul 19 22:51:32 2013 +0100
265 int m_map(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
268 - if (feature_bool(FEAT_HIS_MAP) && !IsAnOper(sptr))
269 + if (feature_bool(FEAT_HIS_MAP) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_ROUTEINFO))))
271 sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s %s", sptr,
272 "/MAP has been disabled, from CFV-165. "
278 -int mo_map(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
283 - dump_map(sptr, &me, parv[1], 0);
284 - send_reply(sptr, RPL_MAPEND);
288 diff -r 49deac8a9792 ircd/m_mode.c
289 --- a/ircd/m_mode.c Fri Jul 19 22:50:34 2013 +0100
290 +++ b/ircd/m_mode.c Fri Jul 19 22:51:32 2013 +0100
295 + /* We don't want mode requests from non-members, prolly to counter ban evasion. Allow channel-privacy opers and opers overriding a local chan */
296 + /* if the aim is to hide the banlist from outsiders, but not the modes and creation time
297 + thus only block the request when 3 or more parameters are given -> move check here - wiebe */
298 + if (! (member || HasPriv(sptr, PRIV_CHANNEL_PRIVACY) || (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_MODE_LCHAN)))) {
299 + send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname);
303 if (!member || !IsChanOp(member)) {
304 if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_MODE_LCHAN)) {
305 modebuf_init(&mbuf, sptr, cptr, chptr,
306 diff -r 49deac8a9792 ircd/m_privs.c
307 --- a/ircd/m_privs.c Fri Jul 19 22:50:34 2013 +0100
308 +++ b/ircd/m_privs.c Fri Jul 19 22:51:32 2013 +0100
311 return client_report_privs(sptr, sptr);
313 + if (!HasPriv(sptr, PRIV_SERVERINFO))
314 + return send_reply(sptr, ERR_NOPRIVILEGES);
316 for (i = 1; i < parc; i++) {
317 for (name = ircd_strtok(&p, parv[i], " "); name;
318 name = ircd_strtok(&p, 0, " ")) {
319 diff -r 49deac8a9792 ircd/m_rping.c
320 --- a/ircd/m_rping.c Fri Jul 19 22:50:34 2013 +0100
321 +++ b/ircd/m_rping.c Fri Jul 19 22:51:32 2013 +0100
323 assert(cptr == sptr);
324 assert(IsAnOper(sptr));
326 + if (!HasPriv(sptr, PRIV_ROUTEINFO))
327 + return send_reply(sptr, ERR_NOPRIVILEGES);
330 return need_more_params(sptr, "RPING");
332 diff -r 49deac8a9792 ircd/m_settime.c
333 --- a/ircd/m_settime.c Fri Jul 19 22:50:34 2013 +0100
334 +++ b/ircd/m_settime.c Fri Jul 19 22:51:32 2013 +0100
336 static char tbuf[11];
338 /* Must be a global oper */
340 + if (!IsOper(sptr) || !HasPriv(sptr, PRIV_ROUTE))
341 return send_reply(sptr, ERR_NOPRIVILEGES);
343 if (parc < 2) /* verify argument count */
344 diff -r 49deac8a9792 ircd/m_squit.c
345 --- a/ircd/m_squit.c Fri Jul 19 22:50:34 2013 +0100
346 +++ b/ircd/m_squit.c Fri Jul 19 22:51:32 2013 +0100
348 struct Client *acptr;
349 struct Client *acptr2;
352 + if (!HasPriv(sptr, PRIV_ROUTE))
353 + return send_reply(sptr, ERR_NOPRIVILEGES);
356 return need_more_params(sptr, "SQUIT");
357 diff -r 49deac8a9792 ircd/m_stats.c
358 --- a/ircd/m_stats.c Fri Jul 19 22:50:34 2013 +0100
359 +++ b/ircd/m_stats.c Fri Jul 19 22:51:32 2013 +0100
361 * This checks cptr rather than sptr so that a local oper may send
362 * /stats queries to other servers.
364 - if (!IsPrivileged(cptr) &&
365 + if (!(IsPrivileged(cptr) && HasPriv(cptr, PRIV_SERVERINFO)) &&
366 ((sd->sd_flags & STAT_FLAG_OPERONLY) ||
367 - ((sd->sd_flags & STAT_FLAG_OPERFEAT) && feature_bool(sd->sd_control))))
368 + ((sd->sd_flags & STAT_FLAG_OPERFEAT) && feature_bool(sd->sd_control))))
369 return send_reply(sptr, ERR_NOPRIVILEGES);
371 /* Check for extra parameter */
372 diff -r 49deac8a9792 ircd/m_trace.c
373 --- a/ircd/m_trace.c Fri Jul 19 22:50:34 2013 +0100
374 +++ b/ircd/m_trace.c Fri Jul 19 22:51:32 2013 +0100
377 int mo_trace(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
379 - if (feature_bool(FEAT_HIS_TRACE) && !IsAnOper(sptr))
380 - return send_reply(cptr, ERR_NOPRIVILEGES);
381 + if (!HasPriv(sptr, PRIV_ROUTEINFO))
382 + return send_reply(sptr, ERR_NOPRIVILEGES);
383 do_trace(cptr, sptr, parc, parv);
386 diff -r 49deac8a9792 ircd/m_uping.c
387 --- a/ircd/m_uping.c Fri Jul 19 22:50:34 2013 +0100
388 +++ b/ircd/m_uping.c Fri Jul 19 22:51:32 2013 +0100
391 assert(IsAnOper(sptr));
393 + if (!HasPriv(sptr, PRIV_ROUTEINFO))
394 + return send_reply(sptr, ERR_NOPRIVILEGES);
397 send_reply(sptr, ERR_NEEDMOREPARAMS, "UPING");
399 diff -r 49deac8a9792 ircd/m_userhost.c
400 --- a/ircd/m_userhost.c Fri Jul 19 22:50:34 2013 +0100
401 +++ b/ircd/m_userhost.c Fri Jul 19 22:51:32 2013 +0100
403 * of +x. If an oper wants the real host, he should go to
407 + (HasHiddenHost(cptr) || HasSetHost(cptr)) && (sptr != cptr) ?
408 cli_user(cptr)->host : cli_user(cptr)->realhost);
411 diff -r 49deac8a9792 ircd/m_userip.c
412 --- a/ircd/m_userip.c Fri Jul 19 22:50:34 2013 +0100
413 +++ b/ircd/m_userip.c Fri Jul 19 22:51:32 2013 +0100
415 * of +x. If an oper wants the real IP, he should go to
418 - (HasHiddenHost(cptr) || HasSetHost(cptr)) && !IsAnOper(sptr) ?
419 + ((HasHiddenHost(cptr) || HasSetHost(cptr) || feature_bool(FEAT_HIS_USERIP)) && (sptr != cptr)) ?
420 feature_str(FEAT_HIDDEN_IP) :
421 ircd_ntoa(&cli_ip(cptr)));
423 diff -r 49deac8a9792 ircd/m_wallchops.c
424 --- a/ircd/m_wallchops.c Fri Jul 19 22:50:34 2013 +0100
425 +++ b/ircd/m_wallchops.c Fri Jul 19 22:51:32 2013 +0100
428 struct Channel *chptr;
429 struct Membership* member;
433 assert(cptr == sptr);
434 diff -r 49deac8a9792 ircd/m_wallops.c
435 --- a/ircd/m_wallops.c Fri Jul 19 22:50:34 2013 +0100
436 +++ b/ircd/m_wallops.c Fri Jul 19 22:51:32 2013 +0100
441 + if (!HasPriv(sptr, PRIV_WALL))
442 + return send_reply(sptr, ERR_NOPRIVILEGES);
444 message = parc > 1 ? parv[1] : 0;
446 if (EmptyString(message))
447 diff -r 49deac8a9792 ircd/m_wallusers.c
448 --- a/ircd/m_wallusers.c Fri Jul 19 22:50:34 2013 +0100
449 +++ b/ircd/m_wallusers.c Fri Jul 19 22:51:32 2013 +0100
454 + if (!HasPriv(sptr, PRIV_WALL))
455 + return send_reply(sptr, ERR_NOPRIVILEGES);
457 message = parc > 1 ? parv[1] : 0;
459 if (EmptyString(message))
460 diff -r 49deac8a9792 ircd/m_wallvoices.c
461 --- a/ircd/m_wallvoices.c Fri Jul 19 22:50:34 2013 +0100
462 +++ b/ircd/m_wallvoices.c Fri Jul 19 22:51:32 2013 +0100
465 struct Channel *chptr;
466 struct Membership* member;
470 assert(cptr == sptr);
471 diff -r 49deac8a9792 ircd/m_who.c
472 --- a/ircd/m_who.c Fri Jul 19 22:50:34 2013 +0100
473 +++ b/ircd/m_who.c Fri Jul 19 22:51:32 2013 +0100
474 @@ -269,10 +269,10 @@
478 - if (feature_bool(FEAT_HIS_WHO_SERVERNAME) && !IsAnOper(sptr))
479 + if (feature_bool(FEAT_HIS_WHO_SERVERNAME) && !HasPriv(sptr, PRIV_ROUTEINFO))
480 matchsel &= ~WHO_FIELD_SER;
482 - if (feature_bool(FEAT_HIS_WHO_FILTERIP) && !IsAnOper(sptr))
483 + if (feature_bool(FEAT_HIS_WHO_FILTERIP) && !HasPriv(sptr, PRIV_USER_PRIVACY))
484 matchsel &= ~WHO_FIELD_NIP;
486 if (qrt && (fields & WHO_FIELD_QTY))
489 if (!Process(acptr)) /* This can't be moved before other checks */
491 - if (!(isthere || (SHOW_MORE(sptr, counter))))
493 + (IsOper(sptr) && (bitsel & WHOSELECT_EXTRA) && HasPriv(sptr, PRIV_SEE_CHAN)) ||
494 + (SHOW_MORE(sptr, counter))))
496 do_who(sptr, acptr, chptr, fields, qrt);
498 diff -r 49deac8a9792 ircd/m_whois.c
499 --- a/ircd/m_whois.c Fri Jul 19 22:50:34 2013 +0100
500 +++ b/ircd/m_whois.c Fri Jul 19 22:51:32 2013 +0100
503 const struct User* user = cli_user(acptr);
504 const char* name = (!*(cli_name(acptr))) ? "?" : cli_name(acptr);
505 - a2cptr = feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && !IsAnOper(sptr)
506 + a2cptr = feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_ROUTEINFO)))
507 && sptr != acptr ? &his : user->server;
509 send_reply(sptr, RPL_WHOISUSER, name, user->username, user->host,
511 if (IsAccount(acptr))
512 send_reply(sptr, RPL_WHOISACCOUNT, name, user->account);
514 - if ((HasHiddenHost(acptr) || HasSetHost(acptr)) && (IsAnOper(sptr) || acptr == sptr))
515 + if ((HasHiddenHost(acptr) || HasSetHost(acptr)) && ((IsAnOper(sptr) && HasPriv(sptr, PRIV_USER_PRIVACY)) || acptr == sptr))
516 send_reply(sptr, RPL_WHOISACTUALLY, name, user->realusername,
517 user->realhost, ircd_ntoa(&cli_ip(acptr)));
522 if (MyConnect(acptr) &&
524 + ((IsAnOper(sptr) && HasPriv(sptr, PRIV_USER_PRIVACY)) ||
525 (!IsNoIdle(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) ||
526 sptr == acptr || parc >= 3))))
527 send_reply(sptr, RPL_WHOISIDLE, name, CurrentTime - user->last,
528 diff -r 49deac8a9792 ircd/m_whowas.c
529 --- a/ircd/m_whowas.c Fri Jul 19 22:50:34 2013 +0100
530 +++ b/ircd/m_whowas.c Fri Jul 19 22:51:32 2013 +0100
531 @@ -138,10 +138,10 @@
533 send_reply(sptr, RPL_WHOWASUSER, temp->name, temp->username,
534 temp->hostname, temp->realname);
535 - if (IsAnOper(sptr) && temp->realhost)
536 + if ((IsAnOper(sptr) && HasPriv(sptr, PRIV_USER_PRIVACY)) && temp->realhost)
537 send_reply(sptr, RPL_WHOISACTUALLY, temp->name, temp->username, temp->realhost, "<untracked>");
538 send_reply(sptr, RPL_WHOISSERVER, temp->name,
539 - (feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && !IsOper(sptr)) ?
540 + (feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_ROUTEINFO)))) ?
541 feature_str(FEAT_HIS_SERVERNAME) :
543 myctime(temp->logoff));
544 diff -r 49deac8a9792 ircd/parse.c
545 --- a/ircd/parse.c Fri Jul 19 22:50:34 2013 +0100
546 +++ b/ircd/parse.c Fri Jul 19 22:51:32 2013 +0100
549 0, MAXPARA, MFLG_SLOW, 0, NULL,
550 /* UNREG, CLIENT, SERVER, OPER, SERVICE */
551 - { m_unregistered, m_hash, m_hash, m_hash, m_ignore }
552 + { m_unregistered, m_not_oper, m_hash, m_hash, m_ignore }
556 diff -r 49deac8a9792 ircd/s_misc.c
557 --- a/ircd/s_misc.c Fri Jul 19 22:50:34 2013 +0100
558 +++ b/ircd/s_misc.c Fri Jul 19 22:51:32 2013 +0100
560 /* Then remove the client structures */
561 if (IsServer(victim))
562 exit_downlinks(victim, killer, comment1);
563 - exit_one_client(victim, comment);
565 + if (strncmp(comment, "G-lined", 7))
566 + exit_one_client(victim, comment);
568 + exit_one_client(victim, "G-lined");
571 * cptr can only have been killed if it was cptr itself that got killed here,
572 diff -r 49deac8a9792 ircd/s_stats.c
573 --- a/ircd/s_stats.c Fri Jul 19 22:50:34 2013 +0100
574 +++ b/ircd/s_stats.c Fri Jul 19 22:51:32 2013 +0100
577 for (asd = statsinfo; asd->sd_name; asd++)
578 if (asd != sd) /* don't send the help for us */
579 - sendcmdto_one(&me, CMD_NOTICE, to, "%C :%c (%s) - %s", to, asd->sd_c,
580 - asd->sd_name, asd->sd_desc);
581 + if (((asd->sd_flags & STAT_FLAG_OPERFEAT) && !feature_bool(asd->sd_control)) || IsServer(to) || (IsAnOper(to) && HasPriv(to, PRIV_SERVERINFO)))
582 + sendcmdto_one(&me, CMD_NOTICE, to, "%C :%c (%s) - %s", to, asd->sd_c,
583 + asd->sd_name, asd->sd_desc);
586 /** Contains information about all statistics. */
587 diff -r 49deac8a9792 ircd/s_user.c
588 --- a/ircd/s_user.c Fri Jul 19 22:50:34 2013 +0100
589 +++ b/ircd/s_user.c Fri Jul 19 22:51:32 2013 +0100
591 if (parc <= server || EmptyString((to = parv[server])) || IsUnknown(from))
592 return (HUNTED_ISME);
594 - if (MustBeOper && !IsPrivileged(from))
595 + if (MustBeOper && (!IsPrivileged(from) || (IsAnOper(from) && !HasPriv(from, PRIV_SERVERINFO))))
597 send_reply(from, ERR_NOPRIVILEGES);
598 return HUNTED_NOSUCH;
599 @@ -1428,15 +1428,15 @@
600 * new umode; servers can set it, local users cannot;
601 * prevents users from /kick'ing or /mode -o'ing
603 - if (!FlagHas(&setflags, FLAG_CHSERV) && !IsOper(sptr))
604 + if (!FlagHas(&setflags, FLAG_CHSERV) && !(IsOper(sptr) && HasPriv(sptr, PRIV_CHANSERV)))
605 ClearChannelService(sptr);
606 - if (!FlagHas(&setflags, FLAG_XTRAOP) && !IsOper(sptr))
607 + if (!FlagHas(&setflags, FLAG_XTRAOP) && !(IsOper(sptr) && HasPriv(sptr, PRIV_XTRA_OPER)))
609 if (!FlagHas(&setflags, FLAG_NOCHAN) && !(IsOper(sptr) || feature_bool(FEAT_USER_HIDECHANS)))
611 - if (!FlagHas(&setflags, FLAG_NOIDLE) && !(IsOper(sptr) || feature_bool(FEAT_USER_HIDEIDLETIME)))
612 + if (!FlagHas(&setflags, FLAG_NOIDLE) && !((IsOper(sptr) && HasPriv(sptr, PRIV_NOIDLE)) || feature_bool(FEAT_USER_HIDEIDLETIME)))
614 - if (!FlagHas(&setflags, FLAG_PARANOID) && !IsOper(sptr))
615 + if (!FlagHas(&setflags, FLAG_PARANOID) && !(IsOper(sptr) && HasPriv(sptr, PRIV_PARANOID)))
619 diff -r 49deac8a9792 ircd/whocmds.c
620 --- a/ircd/whocmds.c Fri Jul 19 22:50:34 2013 +0100
621 +++ b/ircd/whocmds.c Fri Jul 19 22:51:32 2013 +0100
624 if (fields & WHO_FIELD_NIP)
626 - const char* p2 = (HasHiddenHost(acptr) || HasSetHost(acptr)) && !IsAnOper(sptr) ?
627 + const char* p2 = (HasHiddenHost(acptr) || HasSetHost(acptr) || feature_bool(FEAT_HIS_USERIP)) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_USER_PRIVACY))) ?
628 feature_str(FEAT_HIDDEN_IP) :
629 ircd_ntoa(&cli_ip(acptr));
633 if (!fields || (fields & WHO_FIELD_SER))
635 - const char *p2 = (feature_bool(FEAT_HIS_WHO_SERVERNAME) && !IsAnOper(sptr)) ?
636 + const char *p2 = (feature_bool(FEAT_HIS_WHO_SERVERNAME) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_ROUTEINFO)))) ?
637 feature_str(FEAT_HIS_SERVERNAME) :
638 cli_name(cli_user(acptr)->server);
644 - if (IsAnOper(sptr))
645 + if (IsAnOper(sptr) && HasPriv(sptr, PRIV_USER_PRIVACY))
647 if (IsInvisible(acptr))
652 *p1++ = ':'; /* Place colon here for default reply */
653 - if (feature_bool(FEAT_HIS_WHO_HOPCOUNT) && !IsAnOper(sptr))
654 + if (feature_bool(FEAT_HIS_WHO_HOPCOUNT) && (!IsAnOper(sptr) || (IsAnOper(sptr) && !HasPriv(sptr, PRIV_ROUTEINFO))))
655 *p1++ = (sptr == acptr) ? '0' : '3';
657 /* three digit hopcount maximum */
662 - (IsAnOper(sptr) || !feature_bool(FEAT_HIS_WHO_SERVERNAME) ||
663 + ((IsAnOper(sptr) && HasPriv(sptr, PRIV_ROUTEINFO)) || !feature_bool(FEAT_HIS_WHO_SERVERNAME) ||
665 p1 += ircd_snprintf(0, p1, 11, "%d",
666 CurrentTime - cli_user(acptr)->last);