2 # Parent 82274ef17f3290bcfbea13c35461fc5544a90cdf
4 diff -r 82274ef17f32 include/client.h
5 --- a/include/client.h Sat Jul 20 14:45:57 2013 +0100
6 +++ b/include/client.h Sat Jul 20 14:46:31 2013 +0100
8 #define FlagClr(set,flag) ((set)->bits[FLAGSET_INDEX(flag)] &= ~FLAGSET_MASK(flag))
10 /** String containing valid user modes, in no particular order. */
11 -#define infousermodes "diOoswkgxR"
12 +#define infousermodes "diOoswkgxRXIn"
14 /** Operator privileges. */
17 FLAG_ACCOUNTONLY, /**< ASUKA_R: hide privmsgs/notices if
18 user is not authed or opered */
19 FLAG_HIDDENHOST, /**< user's host is hidden */
20 + FLAG_NOCHAN, /**< user's channels are hidden */
21 + FLAG_NOIDLE, /**< user's idletime is hidden */
22 + FLAG_XTRAOP, /**< oper has special powers */
24 FLAG_LAST_FLAG, /**< number of flags */
25 FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */
26 FLAG_GLOBAL_UMODES = FLAG_OPER /**< First global mode flag */
28 #define IsAccount(x) HasFlag(x, FLAG_ACCOUNT)
29 /** Return non-zero if the client has set mode +x (hidden host). */
30 #define IsHiddenHost(x) HasFlag(x, FLAG_HIDDENHOST)
31 +/** Return non-zero if the client has set mode +X (xtraop) */
32 +#define IsXtraOp(x) HasFlag(x, FLAG_XTRAOP)
33 +/** Return non-zero if the client has set mode +n (hide channels) */
34 +#define IsNoChan(x) HasFlag(x, FLAG_NOCHAN)
35 +/** Return non-zero if the client has set mode +I (hide idletime) */
36 +#define IsNoIdle(x) HasFlag(x, FLAG_NOIDLE)
37 /** Return non-zero if the client has an active PING request. */
38 #define IsPingSent(x) HasFlag(x, FLAG_PINGSENT)
39 /** Return non-zero if the client should not receive privmsgs/notices
41 #define SetAccount(x) SetFlag(x, FLAG_ACCOUNT)
42 /** Mark a client as having mode +x (hidden host). */
43 #define SetHiddenHost(x) SetFlag(x, FLAG_HIDDENHOST)
44 +/** Mark a client as having mode +X (xtraop). */
45 +#define SetXtraOp(x) SetFlag(x, FLAG_XTRAOP)
46 +/** Mark a client as having mode +n (hide channels). */
47 +#define SetNoChan(x) SetFlag(x, FLAG_NOCHAN)
48 +/** Mark a client as having mode +I (hide idletime). */
49 +#define SetNoIdle(x) SetFlag(x, FLAG_NOIDLE)
50 /** Mark a client as having a pending PING. */
51 #define SetPingSent(x) SetFlag(x, FLAG_PINGSENT)
52 /** Mark a client as having mode +R (account only). */
54 #define ClearServNotice(x) ClrFlag(x, FLAG_SERVNOTICE)
55 /** Remove mode +x (hidden host) from the client. */
56 #define ClearHiddenHost(x) ClrFlag(x, FLAG_HIDDENHOST)
57 +/** Remove mode +X (xtraop) from a client. */
58 +#define ClearXtraOp(x) ClrFlag(x, FLAG_XTRAOP)
59 +/** Remove mode +n (hide channels) from a client. */
60 +#define ClearNoChan(x) ClrFlag(x, FLAG_NOCHAN)
61 +/** Remove mode +I (hide idletime) from a client. */
62 +#define ClearNoIdle(x) ClrFlag(x, FLAG_NOIDLE)
63 /** Clear the client's pending PING flag. */
64 #define ClearPingSent(x) ClrFlag(x, FLAG_PINGSENT)
65 /** Clear the client's HUB flag. */
66 diff -r 82274ef17f32 include/ircd_features.h
67 --- a/include/ircd_features.h Sat Jul 20 14:45:57 2013 +0100
68 +++ b/include/ircd_features.h Sat Jul 20 14:46:31 2013 +0100
72 FEAT_CONNEXIT_NOTICES,
73 + FEAT_USER_HIDECHANS,
77 diff -r 82274ef17f32 include/numeric.h
78 --- a/include/numeric.h Sat Jul 20 14:45:57 2013 +0100
79 +++ b/include/numeric.h Sat Jul 20 14:46:31 2013 +0100
81 /* ERR_DESYNC 484 Dalnet,PTlink */
82 /* ERR_ATTACKDENY 484 unreal */
83 /* ERR_RESTRICTED 484 IRCnet extension */
84 +#define ERR_ISREALSERVICE 485 /* QuakeNet/ASUKA extension */
85 /* ERR_UNIQOPRIVSNEEDED 485 IRCnet extension */
86 /* ERR_KILLDENY 485 unreal */
87 /* ERR_CANTKICKADMIN 485 PTlink */
88 diff -r 82274ef17f32 ircd/channel.c
89 --- a/ircd/channel.c Sat Jul 20 14:45:57 2013 +0100
90 +++ b/ircd/channel.c Sat Jul 20 14:46:31 2013 +0100
93 * Servers can always speak on channels.
96 + if (IsServer(cptr) || IsXtraOp(cptr))
99 member = find_channel_member(cptr, chptr);
100 @@ -3119,17 +3119,29 @@
101 if ((state->cli_change[i].flag & (MODE_DEL | MODE_CHANOP)) ==
102 (MODE_DEL | MODE_CHANOP)) {
103 /* prevent +k users from being deopped */
104 - if (IsChannelService(state->cli_change[i].client)) {
107 + * Allow +X'ed users to mess with +k'ed.
110 + if ((IsChannelService(state->cli_change[i].client) && IsService(cli_user(state->cli_change[i].client)->server)) || (IsChannelService(state->cli_change[i].client) && !IsXtraOp(state->sptr))) {
111 if (state->flags & MODE_PARSE_FORCE) /* it was forced */
112 sendto_opmask_butone(0, SNO_HACK4, "Deop of +k user on %H by %s",
114 (IsServer(state->sptr) ? cli_name(state->sptr) :
115 cli_name((cli_user(state->sptr))->server)));
117 - else if (MyUser(state->sptr) && state->flags & MODE_PARSE_SET) {
118 - send_reply(state->sptr, ERR_ISCHANSERVICE,
119 - cli_name(state->cli_change[i].client),
120 - state->chptr->chname);
121 + else if (MyUser(state->sptr) && state->flags & MODE_PARSE_SET && (state->sptr != state->cli_change[i].client)) {
122 + if(IsService(cli_user(state->cli_change[i].client)->server) && IsChannelService(state->cli_change[i].client)){
123 + send_reply(state->sptr, ERR_ISREALSERVICE,
124 + cli_name(state->cli_change[i].client),
125 + state->chptr->chname);
127 + send_reply(state->sptr, ERR_ISCHANSERVICE,
128 + cli_name(state->cli_change[i].client),
129 + state->chptr->chname);
135 diff -r 82274ef17f32 ircd/ircd_features.c
136 --- a/ircd/ircd_features.c Sat Jul 20 14:45:57 2013 +0100
137 +++ b/ircd/ircd_features.c Sat Jul 20 14:46:31 2013 +0100
139 F_S(HIDDEN_IP, 0, "127.0.0.1", 0),
140 F_B(AUTOINVISIBLE, 0, 1, 0),
141 F_B(CONNEXIT_NOTICES, 0, 0, 0),
142 + F_B(USER_HIDECHANS, 0, 0, 0),
143 F_B(OPLEVELS, 0, 1, 0),
144 F_B(ZANNELS, 0, 1, 0),
145 F_B(LOCAL_CHANNELS, 0, 1, 0),
146 diff -r 82274ef17f32 ircd/m_join.c
147 --- a/ircd/m_join.c Sat Jul 20 14:45:57 2013 +0100
148 +++ b/ircd/m_join.c Sat Jul 20 14:46:31 2013 +0100
150 else if (*chptr->mode.key && (!key || strcmp(key, chptr->mode.key)))
151 err = ERR_BADCHANNELKEY;
155 + * Allow XtraOpers to join all channels.
158 + if (IsXtraOp(sptr))
161 /* An oper with WALK_LCHAN privilege can join a local channel
162 * he otherwise could not join by using "OVERRIDE" as the key.
163 * This will generate a HACK(4) notice, but fails if the oper
164 diff -r 82274ef17f32 ircd/m_kick.c
165 --- a/ircd/m_kick.c Sat Jul 20 14:45:57 2013 +0100
166 +++ b/ircd/m_kick.c Sat Jul 20 14:46:31 2013 +0100
168 return 0; /* find_chasing sends the reply for us */
170 /* Don't allow the channel service to be kicked */
171 - if (IsChannelService(who))
174 + * Allow +X'ed users to kick +k'ed, but not U-lined services.
177 + if (IsChannelService(who) && IsService(cli_user(who)->server))
178 + return send_reply(sptr, ERR_ISREALSERVICE, cli_name(who), chptr->chname);
180 + if (IsChannelService(who) && !IsXtraOp(sptr) && (who!=sptr))
181 return send_reply(sptr, ERR_ISCHANSERVICE, cli_name(who), chptr->chname);
183 /* Prevent kicking opers from local channels -DM- */
184 diff -r 82274ef17f32 ircd/m_kill.c
185 --- a/ircd/m_kill.c Sat Jul 20 14:45:57 2013 +0100
186 +++ b/ircd/m_kill.c Sat Jul 20 14:46:31 2013 +0100
189 * if the user is +k, prevent a kill from local user
191 - if (IsChannelService(victim))
194 + * Allow +X'ed users to kill +k'ed, but not U-lined services.
197 + if (IsChannelService(victim) && IsService(cli_user(victim)->server))
198 + return send_reply(sptr, ERR_ISREALSERVICE, "KILL", cli_name(victim));
200 + if (IsChannelService(victim) && !IsXtraOp(sptr) && !(victim==sptr))
201 return send_reply(sptr, ERR_ISCHANSERVICE, "KILL", cli_name(victim));
204 diff -r 82274ef17f32 ircd/m_whois.c
205 --- a/ircd/m_whois.c Sat Jul 20 14:45:57 2013 +0100
206 +++ b/ircd/m_whois.c Sat Jul 20 14:46:31 2013 +0100
210 /* Display the channels this user is on. */
211 - if (!IsChannelService(acptr))
212 + if ((!IsChannelService(acptr) && !IsNoChan(acptr)) || (acptr==sptr))
214 struct Membership* chan;
215 mlen = strlen(cli_name(&me)) + strlen(cli_name(sptr)) + 12 + strlen(name);
217 * probably a good place to add them :)
220 - if (MyConnect(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) ||
221 - (sptr == acptr || IsAnOper(sptr) || parc >= 3)))
222 + if (MyConnect(acptr) &&
224 + (!IsNoIdle(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) ||
225 + sptr == acptr || parc >= 3))))
226 send_reply(sptr, RPL_WHOISIDLE, name, CurrentTime - user->last,
227 cli_firsttime(acptr));
229 diff -r 82274ef17f32 ircd/s_err.c
230 --- a/ircd/s_err.c Sat Jul 20 14:45:57 2013 +0100
231 +++ b/ircd/s_err.c Sat Jul 20 14:46:31 2013 +0100
232 @@ -1000,9 +1000,9 @@
234 { ERR_CANTKILLSERVER, ":You cant kill a server!", "483" },
236 - { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop a network service", "484" },
237 + { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop an IRC operator", "484" },
240 + { ERR_ISREALSERVICE, "%s %s :Cannot kill, kick or deop a network service", "485" },
242 { ERR_ACCOUNTONLY, "%s :You must be authed in order to message this user", "486" },
244 diff -r 82274ef17f32 ircd/s_user.c
245 --- a/ircd/s_user.c Sat Jul 20 14:45:57 2013 +0100
246 +++ b/ircd/s_user.c Sat Jul 20 14:46:31 2013 +0100
249 { FLAG_ACCOUNT, 'r' },
250 { FLAG_HIDDENHOST, 'x' },
251 - { FLAG_ACCOUNTONLY, 'R' }
252 + { FLAG_ACCOUNTONLY, 'R' },
253 + { FLAG_XTRAOP, 'X' },
254 + { FLAG_NOCHAN, 'n' },
255 + { FLAG_NOIDLE, 'I' }
258 /** Length of #userModeList. */
261 const char* channel_name;
262 struct Membership *member;
263 - if ((channel_name = find_no_nickchange_channel(sptr))) {
264 + if ((channel_name = find_no_nickchange_channel(sptr)) && !IsXtraOp(sptr)) {
265 return send_reply(cptr, ERR_BANNICKCHANGE, channel_name);
268 @@ -1072,6 +1075,24 @@
270 ClearChannelService(sptr);
273 + if (what == MODE_ADD)
279 + if (what == MODE_ADD)
285 + if (what == MODE_ADD)
291 if (what == MODE_ADD)
293 @@ -1117,8 +1138,15 @@
294 * new umode; servers can set it, local users cannot;
295 * prevents users from /kick'ing or /mode -o'ing
297 - if (!FlagHas(&setflags, FLAG_CHSERV))
298 + if (!FlagHas(&setflags, FLAG_CHSERV) && !IsOper(sptr))
299 ClearChannelService(sptr);
300 + if (!FlagHas(&setflags, FLAG_XTRAOP) && !IsOper(sptr))
302 + if (!FlagHas(&setflags, FLAG_NOCHAN) && !(IsOper(sptr) || feature_bool(FEAT_USER_HIDECHANS)))
304 + if (!FlagHas(&setflags, FLAG_NOIDLE) && !IsOper(sptr))
308 * only send wallops to opers
310 diff -r 82274ef17f32 ircd/whocmds.c
311 --- a/ircd/whocmds.c Sat Jul 20 14:45:57 2013 +0100
312 +++ b/ircd/whocmds.c Sat Jul 20 14:46:31 2013 +0100
314 chan = find_channel_member(acptr, repchan);
316 else if ((!fields || (fields & (WHO_FIELD_CHA | WHO_FIELD_FLA)))
317 - && !IsChannelService(acptr))
318 + && !IsChannelService(acptr) && !IsNoChan(acptr))
320 for (chan = cli_user(acptr)->channel; chan; chan = chan->next_channel)
321 if (PubChannel(chan->channel) &&