2 # Parent 5440fc22cc1d524bb5bca9cfc1a8a7b6bf9dd0f3
4 diff -r 5440fc22cc1d include/client.h
5 --- a/include/client.h Sat Jul 20 14:48:02 2013 +0100
6 +++ b/include/client.h Sat Jul 20 14:48:06 2013 +0100
8 /** String containing valid user modes, in no particular order. */
9 #define infousermodes "diOoswkgxRXInP"
11 +/** Character to indicate no oper name available */
12 +#define NOOPERNAMECHARACTER '-'
14 /** Operator privileges. */
18 FLAG_NOCHAN, /**< user's channels are hidden */
19 FLAG_NOIDLE, /**< user's idletime is hidden */
20 FLAG_XTRAOP, /**< oper has special powers */
21 + FLAG_OPERNAME, /**< Server sends oper name in mode string */
23 FLAG_LAST_FLAG, /**< number of flags */
24 FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */
26 /** Return non-zero if the client should receive notices when someone
27 * does a whois on it. */
28 #define IsParanoid(x) HasFlag(x, FLAG_PARANOID)
29 +/** Return non-zero if the server should send opername information */
30 +#define IsSendOperName(x) HasFlag(x, FLAG_OPERNAME)
32 /** Return non-zero if the client has operator or server privileges. */
33 #define IsPrivileged(x) (IsAnOper(x) || IsServer(x))
35 #define SetHub(x) SetFlag(x, FLAG_HUB)
36 /** Mark a client as being an IPv6-grokking server. */
37 #define SetIPv6(x) SetFlag(x, FLAG_IPV6)
38 +/** Mark a server as sending opername */
39 +#define SetOperName(x) SetFlag(x, FLAG_OPERNAME)
40 /** Mark a client as being a services server. */
41 #define SetService(x) SetFlag(x, FLAG_SERVICE)
42 /** Mark a client as having an account stamp. */
43 diff -r 5440fc22cc1d include/numeric.h
44 --- a/include/numeric.h Sat Jul 20 14:48:02 2013 +0100
45 +++ b/include/numeric.h Sat Jul 20 14:48:06 2013 +0100
47 #define RPL_USERIP 340 /* Undernet extension */
48 #define RPL_INVITING 341
49 /* RPL_SUMMONING 342 removed from RFC1459 */
50 +#define RPL_WHOISOPERNAME 343 /* QuakeNet Extension */
52 #define RPL_ISSUEDINVITE 345 /* Undernet extension */
53 #define RPL_INVITELIST 346 /* IRCnet, Undernet extension */
54 diff -r 5440fc22cc1d include/s_user.h
55 --- a/include/s_user.h Sat Jul 20 14:48:02 2013 +0100
56 +++ b/include/s_user.h Sat Jul 20 14:48:06 2013 +0100
58 int MustBeOper, const char *pattern,
59 int server, int parc, char *parv[]);
60 extern struct Client* next_client(struct Client* next, const char* ch);
61 -extern char *umode_str(struct Client *cptr);
62 +extern char *umode_str(struct Client *cptr, int type);
63 extern void send_umode(struct Client *cptr, struct Client *sptr,
64 - struct Flags *old, int sendset);
65 + struct Flags *old, int sendset, int opernames);
66 extern void set_snomask(struct Client *, unsigned int, int);
67 extern int is_snomask(char *);
68 extern int check_target_limit(struct Client *sptr, void *target, const char *name,
69 diff -r 5440fc22cc1d include/send.h
70 --- a/include/send.h Sat Jul 20 14:48:02 2013 +0100
71 +++ b/include/send.h Sat Jul 20 14:48:06 2013 +0100
73 int require, int forbid,
74 const char *pattern, ...);
76 +/* Send command to servers by flag arrays except one */
77 +void sendcmdto_flagarray_serv_butone(struct Client *from, const char *cmd,
78 + const char *tok, struct Client *one,
79 + int *require, unsigned int requiresize,
80 + int *forbid, unsigned int forbidsize,
81 + const char *pattern, ...);
83 /* Send command to all servers except one */
84 extern void sendcmdto_serv_butone(struct Client *from, const char *cmd,
85 const char *tok, struct Client *one,
86 diff -r 5440fc22cc1d include/struct.h
87 --- a/include/struct.h Sat Jul 20 14:48:02 2013 +0100
88 +++ b/include/struct.h Sat Jul 20 14:48:06 2013 +0100
90 #include "ircd_defs.h" /* sizes */
94 +#ifndef INCLUDED_stdint_h
96 +#define INCLUDED_stdint_h
104 char realhost[HOSTLEN + 1]; /**< actual hostname */
105 char account[ACCOUNTLEN + 1]; /**< IRC account name */
106 time_t acc_create; /**< IRC account timestamp */
107 + unsigned long acc_id; /**< IRC account unique id */
108 + uint64_t acc_flags; /**< IRC account flags */
109 + char* opername; /**< IRC Oper Account name */
112 #endif /* INCLUDED_struct_h */
113 diff -r 5440fc22cc1d ircd/ircd_parser.y
114 --- a/ircd/ircd_parser.y Sat Jul 20 14:48:02 2013 +0100
115 +++ b/ircd/ircd_parser.y Sat Jul 20 14:48:06 2013 +0100
119 parse_error("Missing name in operator block");
120 + else if (strlen(name) > ACCOUNTLEN)
121 + parse_error("Operator name in operator block is too long");
122 + else if ((name[0] == NOOPERNAMECHARACTER) && (name[1] == '\0'))
123 + parse_error("Operator name can not be '%c'",NOOPERNAMECHARACTER);
124 else if (pass == NULL)
125 parse_error("Missing password in operator block");
126 /* Do not check password length because it may be crypted. */
127 diff -r 5440fc22cc1d ircd/ircd_reslib.c
128 --- a/ircd/ircd_reslib.c Sat Jul 20 14:48:02 2013 +0100
129 +++ b/ircd/ircd_reslib.c Sat Jul 20 14:48:06 2013 +0100
138 #include "ircd_reslib.h"
139 diff -r 5440fc22cc1d ircd/m_account.c
140 --- a/ircd/m_account.c Sat Jul 20 14:48:02 2013 +0100
141 +++ b/ircd/m_account.c Sat Jul 20 14:48:06 2013 +0100
148 /* #include <assert.h> -- Now using assert in ircd_log.h */
150 @@ -101,13 +102,19 @@
151 * parv[0] = sender prefix
152 * parv[1] = numeric of client to act on
153 * parv[2] = account name (12 characters or less)
154 + * parv[3] = account timestamp
155 + * parv[4] = account id
156 + * parv[5] = account flags (optional)
158 int ms_account(struct Client* cptr, struct Client* sptr, int parc,
161 struct Client *acptr;
163 + unsigned long acc_id;
164 + unsigned long long acc_flags;
168 return need_more_params(sptr, "ACCOUNT");
171 @@ -117,10 +124,35 @@
172 if (!(acptr = findNUser(parv[1])))
173 return 0; /* Ignore ACCOUNT for a user that QUIT; probably crossed */
175 - if (IsAccount(acptr))
176 - return protocol_violation(cptr, "ACCOUNT for already registered user %s "
177 - "(%s -> %s)", cli_name(acptr),
178 - cli_user(acptr)->account, parv[2]);
179 + acc_create = atoi(parv[3]);
180 + acc_id = strtoul(parv[4], NULL, 10);
182 + acc_flags = strtoull(parv[5], NULL, 10);
187 + /* this section is used for updating acc_flags when
188 + * all other elements match
190 + if (IsAccount(acptr)) {
191 + if (strcmp(cli_user(acptr)->account, parv[2]) ||
192 + (cli_user(acptr)->acc_create != acc_create) ||
193 + (cli_user(acptr)->acc_id != acc_id))
194 + return protocol_violation(cptr, "ACCOUNT for already registered user %s "
195 + "(%s -> %s)", cli_name(acptr),
196 + cli_user(acptr)->account, parv[2]);
198 + cli_user(acptr)->acc_flags = acc_flags;
200 + sendcmdto_serv_butone(sptr, CMD_ACCOUNT, cptr, "%C %s %Tu %lu %"PRIu64,
201 + acptr, cli_user(acptr)->account,
202 + cli_user(acptr)->acc_create,
203 + cli_user(acptr)->acc_id,
204 + cli_user(acptr)->acc_flags);
209 assert(0 == cli_user(acptr)->account[0]);
211 @@ -129,20 +161,19 @@
212 "Received account (%s) longer than %d for %s; "
214 parv[2], ACCOUNTLEN, cli_name(acptr));
217 - cli_user(acptr)->acc_create = atoi(parv[3]);
218 - Debug((DEBUG_DEBUG, "Received timestamped account: account \"%s\", "
219 - "timestamp %Tu", parv[2], cli_user(acptr)->acc_create));
222 + cli_user(acptr)->acc_create = acc_create;
223 + cli_user(acptr)->acc_id = acc_id;
224 + cli_user(acptr)->acc_flags = acc_flags;
226 ircd_strncpy(cli_user(acptr)->account, parv[2], ACCOUNTLEN);
227 hide_hostmask(acptr, FLAG_ACCOUNT);
229 - sendcmdto_serv_butone(sptr, CMD_ACCOUNT, cptr,
230 - cli_user(acptr)->acc_create ? "%C %s %Tu" : "%C %s",
231 - acptr, cli_user(acptr)->account,
232 - cli_user(acptr)->acc_create);
233 + sendcmdto_serv_butone(sptr, CMD_ACCOUNT, cptr, "%C %s %Tu %lu %"PRIu64,
234 + acptr, cli_user(acptr)->account,
235 + cli_user(acptr)->acc_create,
236 + cli_user(acptr)->acc_id,
237 + cli_user(acptr)->acc_flags);
241 diff -r 5440fc22cc1d ircd/m_check.c
242 --- a/ircd/m_check.c Sat Jul 20 14:48:02 2013 +0100
243 +++ b/ircd/m_check.c Sat Jul 20 14:48:06 2013 +0100
245 struct Membership *lp;
246 struct irc_sockaddr sin;
247 char outbuf[BUFSIZE];
252 diff -r 5440fc22cc1d ircd/m_oper.c
253 --- a/ircd/m_oper.c Sat Jul 20 14:48:02 2013 +0100
254 +++ b/ircd/m_oper.c Sat Jul 20 14:48:06 2013 +0100
256 if (!aconf || IsIllegal(aconf))
258 send_reply(sptr, ERR_NOOPERHOST);
259 - sendto_opmask_butone(0, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s)",
260 - parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
261 + sendto_opmask_butone(0, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) as %s",
262 + parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr), name);
265 assert(0 != (aconf->status & CONF_OPERATOR));
267 if (ACR_OK != attach_conf(sptr, aconf)) {
268 send_reply(sptr, ERR_NOOPERHOST);
269 sendto_opmask_butone(0, SNO_OLDREALOP, "Failed OPER attempt by %s "
270 - "(%s@%s)", parv[0], cli_user(sptr)->realusername,
271 - cli_sockhost(sptr));
272 + "(%s@%s) as %s", parv[0], cli_user(sptr)->realusername,
273 + cli_sockhost(sptr), aconf->name);
279 cli_handler(cptr) = OPER_HANDLER;
281 + if (cli_user(sptr)->opername)
282 + MyFree(cli_user(sptr)->opername);
283 + cli_user(sptr)->opername = (char*) MyMalloc(strlen(name) + 1);
284 + assert(0 != cli_user(sptr)->opername);
285 + ircd_strncpy(cli_user(sptr)->opername,aconf->name,ACCOUNTLEN);
287 SetFlag(sptr, FLAG_WALLOP);
288 SetFlag(sptr, FLAG_SERVNOTICE);
289 SetFlag(sptr, FLAG_DEBUG);
290 @@ -186,17 +192,17 @@
291 send_umode_out(cptr, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
292 send_reply(sptr, RPL_YOUREOPER);
294 - sendto_opmask_butone(0, SNO_OLDSNO, "%s (%s@%s) is now operator (%c)",
295 + sendto_opmask_butone(0, SNO_OLDSNO, "%s (%s@%s) is now operator (%c) as %s",
296 parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr),
297 - IsOper(sptr) ? 'O' : 'o');
298 + IsOper(sptr) ? 'O' : 'o', cli_user(sptr)->opername);
300 log_write(LS_OPER, L_INFO, 0, "OPER (%s) by (%#R)", name, sptr);
304 send_reply(sptr, ERR_PASSWDMISMATCH);
305 - sendto_opmask_butone(0, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s)",
306 - parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
307 + sendto_opmask_butone(0, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) as %s",
308 + parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr), aconf->name);
315 SetFlag(sptr, FLAG_OPER);
316 - sendcmdto_serv_butone(sptr, CMD_MODE, cptr, "%s :+o", parv[0]);
317 + sendcmdto_flag_serv_butone(sptr, CMD_MODE, cptr, FLAG_LAST_FLAG, FLAG_OPERNAME, "%s :+o", parv[0]);
318 + sendcmdto_flag_serv_butone(sptr, CMD_MODE, cptr, FLAG_OPERNAME, FLAG_LAST_FLAG, "%s :+o %c", parv[0], NOOPERNAMECHARACTER);
322 diff -r 5440fc22cc1d ircd/m_server.c
323 --- a/ircd/m_server.c Sat Jul 20 14:48:02 2013 +0100
324 +++ b/ircd/m_server.c Sat Jul 20 14:48:06 2013 +0100
326 case 'h': SetHub(cptr); break;
327 case 's': SetService(cptr); break;
328 case '6': SetIPv6(cptr); break;
329 + case 'n': SetOperName(cptr); break;
333 @@ -776,10 +777,11 @@
335 if (0 == match(cli_name(&me), cli_name(acptr)))
337 - sendcmdto_one(sptr, CMD_SERVER, bcptr, "%s %d 0 %s %s %s%s +%s%s%s :%s",
338 + sendcmdto_one(sptr, CMD_SERVER, bcptr, "%s %d 0 %s %s %s%s +%s%s%s%s :%s",
339 cli_name(acptr), hop + 1, parv[4], parv[5],
340 NumServCap(acptr), IsHub(acptr) ? "h" : "",
341 IsService(acptr) ? "s" : "", IsIPv6(acptr) ? "6" : "",
342 + IsSendOperName(acptr) ? "n" : "",
346 diff -r 5440fc22cc1d ircd/m_whois.c
347 --- a/ircd/m_whois.c Sat Jul 20 14:48:02 2013 +0100
348 +++ b/ircd/m_whois.c Sat Jul 20 14:48:06 2013 +0100
351 send_reply(sptr, RPL_AWAY, name, user->away);
353 - if (SeeOper(sptr,acptr))
354 + if (SeeOper(sptr,acptr)) {
355 send_reply(sptr, RPL_WHOISOPERATOR, name);
356 + if (IsAnOper(sptr) && user->opername)
357 + send_reply(sptr, RPL_WHOISOPERNAME, name, user->opername);
360 if (IsAccount(acptr))
361 send_reply(sptr, RPL_WHOISACCOUNT, name, user->account);
362 diff -r 5440fc22cc1d ircd/memdebug.c
363 --- a/ircd/memdebug.c Sat Jul 20 14:48:02 2013 +0100
364 +++ b/ircd/memdebug.c Sat Jul 20 14:48:06 2013 +0100
366 #include <sys/types.h>
369 #include "ircd_alloc.h"
370 #include "ircd_log.h"
371 diff -r 5440fc22cc1d ircd/s_auth.c
372 --- a/ircd/s_auth.c Sat Jul 20 14:48:02 2013 +0100
373 +++ b/ircd/s_auth.c Sat Jul 20 14:48:06 2013 +0100
374 @@ -1975,10 +1975,17 @@
375 /* If account has a creation timestamp, use it. */
376 assert(cli_user(cli) != NULL);
377 if (params[0][len] == ':') {
378 - cli_user(cli)->acc_create = strtoul(params[0] + len + 1, NULL, 10);
379 - params[0][len] = '\0';
381 + cli_user(cli)->acc_create = strtoul(params[0] + len + 1, &end, 10);
384 + cli_user(cli)->acc_id = strtoul(end + 1, &end2, 10);
386 + cli_user(cli)->acc_flags = strtoull(end2 + 1, NULL, 10);
391 /* Copy account name to User structure. */
392 ircd_strncpy(cli_user(cli)->account, params[0], ACCOUNTLEN);
394 diff -r 5440fc22cc1d ircd/s_bsd.c
395 --- a/ircd/s_bsd.c Sat Jul 20 14:48:02 2013 +0100
396 +++ b/ircd/s_bsd.c Sat Jul 20 14:48:06 2013 +0100
398 cli_lasttime(cptr) = CurrentTime;
401 - sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s",
402 + sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6n :%s",
403 cli_name(&me), cli_serv(&me)->timestamp, newts,
404 MAJOR_PROTOCOL, NumServCap(&me),
405 feature_bool(FEAT_HUB) ? "h" : "", cli_info(&me));
406 diff -r 5440fc22cc1d ircd/s_err.c
407 --- a/ircd/s_err.c Sat Jul 20 14:48:02 2013 +0100
408 +++ b/ircd/s_err.c Sat Jul 20 14:48:06 2013 +0100
414 + { RPL_WHOISOPERNAME, "%s %s :is opered as", "343" },
418 diff -r 5440fc22cc1d ircd/s_serv.c
419 --- a/ircd/s_serv.c Sat Jul 20 14:48:02 2013 +0100
420 +++ b/ircd/s_serv.c Sat Jul 20 14:48:06 2013 +0100
423 * Pass my info to the new server
425 - sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s",
426 + sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6n :%s",
427 cli_name(&me), cli_serv(&me)->timestamp,
428 cli_serv(cptr)->timestamp, MAJOR_PROTOCOL, NumServCap(&me),
429 feature_bool(FEAT_HUB) ? "h" : "",
430 @@ -184,10 +184,10 @@
431 if (!match(cli_name(&me), cli_name(cptr)))
433 sendcmdto_one(&me, CMD_SERVER, acptr,
434 - "%s 2 0 %Tu J%02u %s%s +%s%s%s :%s", cli_name(cptr),
435 + "%s 2 0 %Tu J%02u %s%s +%s%s%s%s :%s", cli_name(cptr),
436 cli_serv(cptr)->timestamp, Protocol(cptr), NumServCap(cptr),
437 IsHub(cptr) ? "h" : "", IsService(cptr) ? "s" : "",
438 - IsIPv6(cptr) ? "6" : "", cli_info(cptr));
439 + IsIPv6(cptr) ? "6" : "", IsSendOperName(cptr) ? "n" : "", cli_info(cptr));
442 /* Send these as early as possible so that glined users/juped servers can
443 @@ -227,11 +227,11 @@
444 if (0 == match(cli_name(&me), cli_name(acptr)))
446 sendcmdto_one(cli_serv(acptr)->up, CMD_SERVER, cptr,
447 - "%s %d 0 %Tu %s%u %s%s +%s%s%s :%s", cli_name(acptr),
448 + "%s %d 0 %Tu %s%u %s%s +%s%s%s%s :%s", cli_name(acptr),
449 cli_hopcount(acptr) + 1, cli_serv(acptr)->timestamp,
450 protocol_str, Protocol(acptr), NumServCap(acptr),
451 IsHub(acptr) ? "h" : "", IsService(acptr) ? "s" : "",
452 - IsIPv6(acptr) ? "6" : "", cli_info(acptr));
453 + IsIPv6(acptr) ? "6" : "", IsSendOperName(cptr) ? "n" : "", cli_info(acptr));
461 - char *s = umode_str(acptr);
463 + if (IsSendOperName(cptr))
464 + s = umode_str(acptr, UMODE_ALL_PARAMS);
466 + s = umode_str(acptr, UMODE_ALL_PARAMS_BUT_OPERID);
467 sendcmdto_one(cli_user(acptr)->server, CMD_NICK, cptr,
468 "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
469 cli_name(acptr), cli_hopcount(acptr) + 1, cli_lastnick(acptr),
470 diff -r 5440fc22cc1d ircd/s_stats.c
471 --- a/ircd/s_stats.c Sat Jul 20 14:48:02 2013 +0100
472 +++ b/ircd/s_stats.c Sat Jul 20 14:48:06 2013 +0100
473 @@ -493,12 +493,12 @@
475 if (sd->sd_funcdata) {
476 send_reply(sptr, SND_EXPLICIT | RPL_STATSVERBOSE,
477 - "%-20s %-20s Flags Hops Numeric Lag RTT Up Down "
478 + "%-20s %-20s Flags Hops Numeric Lag RTT Up Down "
479 "Clients/Max Proto %-10s :Info", "Servername", "Uplink",
481 - fmt = "%-20s %-20s %c%c%c%c%c %4i %s %-4i %5i %4i %4i %4i %5i %5i P%-2i %Tu :%s";
482 + fmt = "%-20s %-20s %c%c%c%c%c%c %4i %s %-4i %5i %4i %4i %4i %5i %5i P%-2i %Tu :%s";
484 - fmt = "%s %s %c%c%c%c%c %i %s %i %i %i %i %i %i %i P%i %Tu :%s";
485 + fmt = "%s %s %c%c%c%c%c%c %i %s %i %i %i %i %i %i %i P%i %Tu :%s";
488 for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr))
490 IsHub(acptr) ? 'H' : '-',
491 IsService(acptr) ? 'S' : '-',
492 IsIPv6(acptr) ? '6' : '-',
493 + IsSendOperName(acptr) ? 'n' : '-',
496 base64toint(cli_yxx(acptr)),
497 diff -r 5440fc22cc1d ircd/s_user.c
498 --- a/ircd/s_user.c Sat Jul 20 14:48:02 2013 +0100
499 +++ b/ircd/s_user.c Sat Jul 20 14:48:06 2013 +0100
501 if (--user->refcnt == 0) {
504 + if (user->opername)
505 + MyFree(user->opername);
511 struct User* user = cli_user(sptr);
513 + int ipv6andopername[] = {FLAG_IPV6,FLAG_OPERNAME};
515 user->last = CurrentTime;
516 parv[0] = cli_name(sptr);
517 @@ -458,10 +461,11 @@
521 - tmpstr = umode_str(sptr);
522 - /* Send full IP address to IPv6-grokking servers. */
523 + tmpstr = umode_str(sptr, UMODE_ALL_PARAMS_BUT_OPERID);
525 + /* Do not send oper name and send full IP address to IPv6-grokking servers. */
526 sendcmdto_flag_serv_butone(user->server, CMD_NICK, cptr,
527 - FLAG_IPV6, FLAG_LAST_FLAG,
528 + FLAG_IPV6, FLAG_OPERNAME,
529 "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
530 cli_name(sptr), cli_hopcount(sptr) + 1,
533 *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "",
534 iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64), 1),
535 NumNick(sptr), cli_info(sptr));
536 - /* Send fake IPv6 addresses to pre-IPv6 servers. */
537 + /* Do not send oper name and send fake IPv6 addresses to pre-IPv6 servers. */
538 + sendcmdto_flagarray_serv_butone(user->server, CMD_NICK, cptr,
539 + NULL, 0, ipv6andopername, 2,
540 + "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
541 + cli_name(sptr), cli_hopcount(sptr) + 1,
542 + cli_lastnick(sptr),
543 + user->realusername, user->realhost,
544 + *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "",
545 + iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64), 0),
546 + NumNick(sptr), cli_info(sptr));
548 + tmpstr = umode_str(sptr, UMODE_ALL_PARAMS);
549 + /* Send oper name and full IP address to IPv6-grokking servers. */
550 + sendcmdto_flagarray_serv_butone(user->server, CMD_NICK, cptr,
551 + ipv6andopername, 2, NULL, 0,
552 + "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
553 + cli_name(sptr), cli_hopcount(sptr) + 1,
554 + cli_lastnick(sptr),
555 + user->realusername, user->realhost,
556 + *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "",
557 + iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64), 1),
558 + NumNick(sptr), cli_info(sptr));
559 + /* Send oper name and fake IPv6 addresses to pre-IPv6 servers. */
560 sendcmdto_flag_serv_butone(user->server, CMD_NICK, cptr,
561 - FLAG_LAST_FLAG, FLAG_IPV6,
562 + FLAG_OPERNAME, FLAG_IPV6,
563 "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
564 cli_name(sptr), cli_hopcount(sptr) + 1,
568 FlagClr(&flags, FLAG_ACCOUNT);
569 client_set_privs(sptr, NULL);
570 - send_umode(cptr, sptr, &flags, ALL_UMODES);
571 + send_umode(cptr, sptr, &flags, ALL_UMODES, 0);
572 if ((cli_snomask(sptr) != SNO_DEFAULT) && HasFlag(sptr, FLAG_SERVNOTICE))
573 send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
575 @@ -845,16 +871,26 @@
577 struct Client *acptr;
579 - send_umode(NULL, sptr, old, prop ? SEND_UMODES : SEND_UMODES_BUT_OPER);
580 + send_umode(NULL, sptr, old, prop ? SEND_UMODES : SEND_UMODES_BUT_OPER, 0);
582 for (i = HighestFd; i >= 0; i--)
584 if ((acptr = LocalClientArray[i]) && IsServer(acptr) &&
585 - (acptr != cptr) && (acptr != sptr) && *umodeBuf)
586 - sendcmdto_one(sptr, CMD_MODE, acptr, "%s %s", cli_name(sptr), umodeBuf);
587 + (acptr != cptr) && (acptr != sptr) && !IsSendOperName(acptr) && *umodeBuf)
588 + sendcmdto_one(sptr, CMD_MODE, acptr, "%s %s", cli_name(sptr), umodeBuf);
591 + send_umode(NULL, sptr, old, prop ? SEND_UMODES : SEND_UMODES_BUT_OPER, 1);
593 + for (i = HighestFd; i >= 0; i--)
595 + if ((acptr = LocalClientArray[i]) && IsServer(acptr) &&
596 + (acptr != cptr) && (acptr != sptr) && IsSendOperName(acptr) && *umodeBuf)
597 + sendcmdto_one(sptr, CMD_MODE, acptr, "%s %s", cli_name(sptr), umodeBuf);
600 if (cptr && MyUser(cptr))
601 - send_umode(cptr, sptr, old, ALL_UMODES);
602 + send_umode(cptr, sptr, old, ALL_UMODES, 0);
606 @@ -1230,9 +1266,29 @@
610 - if (what == MODE_ADD)
611 + if (what == MODE_ADD) {
614 + if (IsServer(cptr) && IsSendOperName(cptr)) {
617 + if (cli_user(sptr)->opername)
618 + MyFree(cli_user(sptr)->opername);
619 + if ((opername[0] == NOOPERNAMECHARACTER) && (opername[1] == '\0')) {
620 + cli_user(sptr)->opername = NULL;
622 + opernamelen = strlen(opername);
623 + if (opernamelen > ACCOUNTLEN) {
624 + protocol_violation(cptr, "Received opername (%s) longer than %d for %s; ignoring.", opername, ACCOUNTLEN, cli_name(sptr));
625 + cli_user(sptr)->opername = NULL;
627 + cli_user(sptr)->opername = (char*) MyMalloc(opernamelen + 1);
628 + assert(0 != cli_user(sptr)->opername);
629 + ircd_strncpy(cli_user(sptr)->opername,opername,ACCOUNTLEN);
635 ClrFlag(sptr, FLAG_OPER);
636 ClrFlag(sptr, FLAG_LOCOP);
638 @@ -1420,13 +1476,16 @@
640 if (!FlagHas(&setflags, FLAG_ACCOUNT) && IsAccount(sptr)) {
641 int len = ACCOUNTLEN;
644 if ((ts = strchr(account, ':'))) {
645 len = (ts++) - account;
646 cli_user(sptr)->acc_create = atoi(ts);
647 - Debug((DEBUG_DEBUG, "Received timestamped account in user mode; "
648 - "account \"%s\", timestamp %Tu", account,
649 - cli_user(sptr)->acc_create));
650 + if ((pts = strchr(ts, ':'))) {
652 + cli_user(sptr)->acc_id = strtoul(pts + 1, &pflags, 10);
653 + if (*pflags == ':')
654 + cli_user(sptr)->acc_flags = strtoull(pflags + 1, NULL, 10);
657 ircd_strncpy(cli_user(sptr)->account, account, len);
659 @@ -1447,7 +1506,23 @@
660 /* user no longer oper */
661 assert(UserStats.opers > 0);
664 + /* notify my operators an operator has deOPERed on the network - wiebe */
665 + if (MyConnect(sptr)) {
666 + sendto_opmask_butone(0, SNO_OLDSNO, "%s (%s@%s) is no longer operator (O) as %s",
667 + cli_name(sptr), cli_user(sptr)->realusername, cli_user(sptr)->realhost,
668 + cli_user(sptr)->opername ? cli_user(sptr)->opername : "<unknown>");
670 + sendto_opmask_butone(0, SNO_OLDSNO, "%s (%s@%s) is no longer operator (O) as %s on %s",
671 + cli_name(sptr), cli_user(sptr)->realusername, cli_user(sptr)->realhost,
672 + cli_user(sptr)->opername ? cli_user(sptr)->opername : "<unknown>", cli_name(cli_user(sptr)->server));
675 client_set_privs(sptr, NULL); /* will clear propagate privilege */
676 + if (cli_user(sptr)->opername) {
677 + MyFree(cli_user(sptr)->opername);
678 + cli_user(sptr)->opername = NULL;
681 if (FlagHas(&setflags, FLAG_INVISIBLE) && !IsInvisible(sptr)) {
682 assert(UserStats.inv_clients > 0);
683 @@ -1468,7 +1543,7 @@
684 * @param[in] cptr Some user.
685 * @return Pointer to a static buffer.
687 -char *umode_str(struct Client *cptr)
688 +char *umode_str(struct Client *cptr, int type)
690 /* Maximum string size: "owidgrx\0" */
692 @@ -1485,30 +1560,40 @@
693 *m++ = userModeList[i].c;
696 + /* OperID is wanted */
697 + if (type == UMODE_ALL_PARAMS && IsOper(cptr))
700 + if (cli_user(cptr)->opername) {
701 + char* t = cli_user(cptr)->opername;
702 + while ((*m++ = *t++))
704 + m--; /* Step back over the '\0' */
706 + *m++ = NOOPERNAMECHARACTER;
712 - char* t = cli_user(cptr)->account;
713 + char *t, nbuf[64+ACCOUNTLEN];
716 + if ( type == UMODE_AND_ACCOUNT_SHORT)
717 + ircd_snprintf(0, t = nbuf, sizeof(nbuf), " %s", cli_user(cptr)->account);
719 + ircd_snprintf(0, t = nbuf, sizeof(nbuf), " %s:%Tu:%lu:%"PRIu64,
720 + cli_user(cptr)->account, cli_user(cptr)->acc_create,
721 + cli_user(cptr)->acc_id, cli_user(cptr)->acc_flags);
724 while ((*m++ = *t++))
727 - if (cli_user(cptr)->acc_create) {
729 - Debug((DEBUG_DEBUG, "Sending timestamped account in user mode for "
730 - "account \"%s\"; timestamp %Tu", cli_user(cptr)->account,
731 - cli_user(cptr)->acc_create));
732 - ircd_snprintf(0, t = nbuf, sizeof(nbuf), ":%Tu",
733 - cli_user(cptr)->acc_create);
734 - m--; /* back up over previous nul-termination */
735 - while ((*m++ = *t++))
738 m--; /* Step back over the '\0' */
741 /* sethost parameter is wanted */
742 - if (type != UMODE_AND_ACCOUNT && IsSetHost(cptr)) {
743 + if ((type != UMODE_AND_ACCOUNT && type != UMODE_AND_ACCOUNT_SHORT) && IsSetHost(cptr)) {
745 ircd_snprintf(0, m, USERLEN + HOSTLEN + 2, "%s@%s", cli_user(cptr)->username,
746 cli_user(cptr)->host);
747 @@ -1526,11 +1611,12 @@
748 * SEND_UMODES, to select which changed user modes to send.
750 void send_umode(struct Client *cptr, struct Client *sptr, struct Flags *old,
752 + int sendset, int opernames)
759 int what = MODE_NULL;
761 @@ -1560,6 +1646,12 @@
765 + /* Special case for OPER.. */
766 + if (flag == FLAG_OPER) {
767 + /* If we're setting +o, add the opername later */
768 + if (!FlagHas(old, flag))
771 /* Special case for SETHOST.. */
772 if (flag == FLAG_SETHOST) {
773 /* Don't send to users */
774 @@ -1593,6 +1685,16 @@
778 + if (opernames && needoper) {
780 + if (cli_user(sptr)->opername) {
781 + char* t = cli_user(sptr)->opername;
782 + while ((*m++ = *t++))
785 + *m++ = NOOPERNAMECHARACTER;
790 ircd_snprintf(0, m, USERLEN + HOSTLEN + 1, "%s@%s", cli_user(sptr)->username,
791 diff -r 5440fc22cc1d ircd/send.c
792 --- a/ircd/send.c Sat Jul 20 14:48:02 2013 +0100
793 +++ b/ircd/send.c Sat Jul 20 14:48:06 2013 +0100
798 + * Send a (prefixed) command to all servers matching or not matching a
800 + * @param[in] from Client sending the command.
801 + * @param[in] cmd Long name of command (ignored).
802 + * @param[in] tok Short name of command.
803 + * @param[in] one Client direction to skip (or NULL).
804 + * @param[in] require Only send to servers with all Flag bits in the array set.
805 + * @param[in] requiresize Size of require flag array
806 + * @param[in] forbid Do not send to servers with any Flag bits in the array set.
807 + * @param[in] forbidsize Size of forbid flag array
808 + * @param[in] pattern Format string for command arguments.
810 +void sendcmdto_flagarray_serv_butone(struct Client *from, const char *cmd,
811 + const char *tok, struct Client *one,
812 + int *require, unsigned int requiresize,
813 + int *forbid, unsigned int forbidsize,
814 + const char *pattern, ...)
819 + unsigned int i, skip;
821 + vd.vd_format = pattern; /* set up the struct VarData for %v */
822 + va_start(vd.vd_args, pattern);
825 + mb = msgq_make(&me, "%C %s %v", from, tok, &vd);
826 + va_end(vd.vd_args);
828 + /* send it to our downlinks */
829 + for (lp = cli_serv(&me)->down; lp; lp = lp->next) {
830 + if (one && lp->value.cptr == cli_from(one))
835 + for (i = 0; i < requiresize; i++) {
836 + if ((require[i] < FLAG_LAST_FLAG) && !HasFlag(lp->value.cptr, require[i])) {
845 + for (i = 0; i < forbidsize; i++) {
846 + if ((forbid[i] < FLAG_LAST_FLAG) && HasFlag(lp->value.cptr, forbid[i])) {
855 + send_buffer(lp->value.cptr, mb, 0);
862 * Send a (prefixed) command to all servers but one.
863 * @param[in] from Client sending the command.
864 * @param[in] cmd Long name of command (ignored).