X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fs_user.c;h=e5d17b975d1d594ae7a0a066a319702bb7c0aaf8;hp=87c006d77396183992b008a34489a1fbf9e86520;hb=1179dc8a73104eb97bfa78a5edd147c2be570b32;hpb=c3727b053aa20cecf3984cc0c9c23b0140edf52c diff --git a/ircd/s_user.c b/ircd/s_user.c index 87c006d..e5d17b9 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -485,13 +485,21 @@ int register_user(struct Client *cptr, struct Client *sptr) * account assignment causes a numeric reply during registration. */ if (HasHiddenHost(sptr)) - hide_hostmask(sptr, FLAG_HIDDENHOST); + hide_hostmask(sptr, HIDE_HOSTMASK_FLAG_HIDDENHOST); if (IsInvisible(sptr)) ++UserStats.inv_clients; if (IsOper(sptr)) ++UserStats.opers; if (MyUser(sptr)) - client_set_uprivs(sptr, cli_confs(sptr)->value.aconf); + { + if(IsOper(sptr)) { + FlagSet(&cli_confs(sptr)->value.aconf->conn_class->privs_dirty, PRIV_PROPAGATE); + client_set_privs(sptr, cli_confs(sptr)->value.aconf); + cli_handler(sptr) = OPER_HANDLER; + } + else + client_set_uprivs(sptr, cli_confs(sptr)->value.aconf); + } if (MyUser(sptr) && HasPriv(sptr, PRIV_SEE_IDLETIME)) SetSeeIdletime(sptr); @@ -531,13 +539,10 @@ int register_user(struct Client *cptr, struct Client *sptr) if(IsOper(sptr)) { send_reply(sptr, RPL_YOUREOPER); - FlagSet(&cli_confs(sptr)->value.aconf->conn_class->privs_dirty, PRIV_PROPAGATE); - client_set_privs(sptr, cli_confs(sptr)->value.aconf); sendto_opmask_butone(0, SNO_OLDSNO, "%s (%s@%s) is now operator (%c)", cli_name(sptr), cli_user(sptr)->username, cli_sockhost(sptr), IsOper(sptr) ? 'O' : 'o'); log_write(LS_OPER, L_INFO, 0, "OPER () by (%#C)", sptr); - cli_handler(sptr) = OPER_HANDLER; } if(*cli_connclass(sptr)) @@ -584,7 +589,9 @@ static const struct UserMode { { FLAG_WEBIRC, 'W' }, { FLAG_SEE_IDLETIME,'t' }, { FLAG_SECURITY_SERV,'D' }, - { FLAG_HIDDENHOST, 'x' } + { FLAG_KEEPCONN_ENABLED, 'K' }, + { FLAG_HIDDENHOST, 'x' }, + { FLAG_NOTCONN, 'Z' } }; /** Length of #userModeList. */ @@ -662,7 +669,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr, if (MyUser(sptr)) { const char* channel_name; struct Membership *member; - if (!force && !IsXtraOp(sptr) && (channel_name = find_no_nickchange_channel(sptr))) { + if (!force && !IsXtraOp(sptr) && (channel_name = find_no_nickchange_channel(sptr, nick))) { return send_reply(cptr, ERR_BANNICKCHANGE, channel_name); } /* @@ -722,31 +729,29 @@ int set_nick_name(struct Client* cptr, struct Client* sptr, } else { /* Local client setting NICK the first time */ - strcpy(cli_name(sptr), nick); + if(!force) + strcpy(cli_name(sptr), nick); + else { + /* use a "temponary" nick here (we'll switch later) */ + char tmpnick[NICKLEN + 2]; + int tmpnickend; + strcpy(tmpnick, nick); + /* we need at least 10 characters */ + if (strlen(tmpnick) > IRCD_MIN(NICKLEN, feature_int(FEAT_NICKLEN)) - 10) + tmpnick[IRCD_MIN(NICKLEN, feature_int(FEAT_NICKLEN))-10] = '\0'; + tmpnickend = strlen(tmpnick); + + do { /* get a non-used nick... */ + sprintf(tmpnick + tmpnickend, "[rz%d]", ircrandom() % 10000); + } while(FindClient(tmpnick)); + strcpy(cli_name(sptr), tmpnick); + } hAddClient(sptr); return auth_set_nick(cli_auth(sptr), nick); } return 0; } -/* Refreshs the users host to the current fakehost. If no fakehost - * is set, the account-host is created. If no Account is set, - * nothing is done. - * Returns 1 if the host changed and 0 if not. - */ -int apply_fakehost(struct Client *cptr) { - char buf[HOSTLEN]; - if(IsFakeHost(cptr)) { - ircd_strncpy(buf, cli_user(cptr)->fakehost, HOSTLEN); - } - else if (IsAccount(cptr)) { - ircd_snprintf(0, buf, HOSTLEN, "%s.%s", cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); - } - if(strncmp(buf, cli_user(cptr)->host, HOSTLEN) == 0) return 0; - ircd_strncpy(cli_user(cptr)->host, buf, HOSTLEN); - return 1; -} - /** Calculate the hash value for a target. * @param[in] target Pointer to target, cast to unsigned int. * @return Hash value constructed from the pointer. @@ -943,6 +948,8 @@ void send_umode_out(struct Client *cptr, struct Client *sptr, } if (cptr && MyUser(cptr)) send_umode(cptr, sptr, old, ALL_UMODES, 0); + if (sptr && sptr != cptr && MyUser(sptr)) + send_umode(sptr, sptr, old, ALL_UMODES, 0); } @@ -985,40 +992,54 @@ void send_user_info(struct Client* sptr, char* names, int rpl, InfoFormatter fmt * @param[in] flag Some flag that affects host-hiding (FLAG_HIDDENHOST, FLAG_ACCOUNT, FLAG_FAKEHOST). * @return Zero. */ + int hide_hostmask(struct Client *cptr, unsigned int flag) { struct Membership *chan; char buf[HOSTLEN]; - switch (flag) { - case FLAG_HIDDENHOST: + if (flag & HIDE_HOSTMASK_FLAG_HIDDENHOST) { /* Local users cannot set +x unless FEAT_HOST_HIDING is true. */ if (MyConnect(cptr) && !feature_bool(FEAT_HOST_HIDING)) return 0; - break; - case FLAG_ACCOUNT: - case FLAG_FAKEHOST: + } + if (flag & (HIDE_HOSTMASK_FLAG_ACCOUNT | HIDE_HOSTMASK_FLAG_FAKEHOST | HIDE_HOSTMASK_FLAG_FAKEIDENT)) { /* Invalidate all bans against the user so we check them again */ for (chan = (cli_user(cptr))->channel; chan; chan = chan->next_channel) ClearBanValid(chan); - break; - default: - /* default: no special handling */ - break; } /* Set flags and stop if no fakehost has to be applied. */ - SetFlag(cptr, flag); + if(flag & HIDE_HOSTMASK_FLAG_HIDDENHOST) + SetFlag(cptr, FLAG_HIDDENHOST); + if(flag & HIDE_HOSTMASK_FLAG_ACCOUNT) + SetFlag(cptr, FLAG_ACCOUNT); + if(flag & HIDE_HOSTMASK_FLAG_FAKEHOST) + SetFlag(cptr, FLAG_FAKEHOST); + if(flag & HIDE_HOSTMASK_FLAG_FAKEIDENT) + SetFlag(cptr, FLAG_FAKEIDENT); + if(!HasHiddenHost(cptr)) return 0; /* Generate new fakehost. */ - if(IsFakeHost(cptr)) ircd_strncpy(buf, cli_user(cptr)->fakehost, HOSTLEN); - else if (IsAccount(cptr)) ircd_snprintf(0, buf, HOSTLEN, "%s.%s", cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); - else return 0; - if(strncmp(buf, cli_user(cptr)->host, HOSTLEN) == 0) return 0; + unsigned int reregister = 0; + if(IsFakeHost(cptr) || IsAccount(cptr)) { + if(IsFakeHost(cptr)) + ircd_strncpy(buf, cli_user(cptr)->fakehost, HOSTLEN); + else + ircd_snprintf(0, buf, HOSTLEN, "%s.%s", cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); + if(strncmp(buf, cli_user(cptr)->host, HOSTLEN)) + reregister |= HIDE_HOSTMASK_FLAG_FAKEHOST; + } + if(IsFakeIdent(cptr)) { + if(strncmp(cli_user(cptr)->fakeuser, cli_user(cptr)->username, USERLEN)) + reregister |= HIDE_HOSTMASK_FLAG_FAKEIDENT; + } + + if (!reregister) return 0; /* Remove all "valid" marks on the bans. This forces them to be * rechecked if the ban is accessed again. @@ -1029,11 +1050,19 @@ hide_hostmask(struct Client *cptr, unsigned int flag) /* Quit user and set the previously generated fakehost. */ sendcmdto_common_channels_butone(cptr, CMD_QUIT, cptr, ":Registered"); - ircd_strncpy(cli_user(cptr)->host, buf, HOSTLEN); + if(reregister & HIDE_HOSTMASK_FLAG_FAKEHOST) + ircd_strncpy(cli_user(cptr)->host, buf, HOSTLEN); + if(reregister & HIDE_HOSTMASK_FLAG_FAKEIDENT) + ircd_strncpy(cli_user(cptr)->username, cli_user(cptr)->fakeuser, USERLEN); + /* ok, the client is now fully hidden, so let them know -- hikari */ - if (MyConnect(cptr)) - send_reply(cptr, RPL_HOSTHIDDEN, cli_user(cptr)->host); + if(MyConnect(cptr)) { + if (IsFakeIdent(cptr)) + send_reply(cptr, RPL_HOSTUSERHIDDEN, cli_user(cptr)->username, cli_user(cptr)->host); + else + send_reply(cptr, RPL_HOSTHIDDEN, cli_user(cptr)->host); + } /* * Go through all channels the client was on, rejoin him @@ -1060,6 +1089,25 @@ hide_hostmask(struct Client *cptr, unsigned int flag) else { SetDelayedJoin(chan); } + + /* + * Check if the client is actually overriding a ban with the + * mask change, if so, kick him out of the channel. + * We have to proceed that way to ensure data consistency (join + kick) + */ + if (find_ban(cptr, chan->channel->banlist)) { + /* Silentely kick in case of delayed join */ + if (chan->channel->mode.mode & MODE_DELJOINS) { + sendcmdto_one(&his, CMD_KICK, cptr, "%H %C :Ban override", chan->channel, cptr); + CheckDelayedJoins(chan->channel); + + } else { + /* Otherwise publicly kick */ + sendcmdto_serv_butone(&me, CMD_KICK, NULL, "%H %C :Ban override", chan->channel, cptr); + sendcmdto_channel_butserv_butone(&his, CMD_KICK, chan->channel, NULL, 0, "%H %C :Ban override", chan->channel, cptr); + make_zombie(chan, cptr, &me, &me, chan->channel); + } + } } return 0; } @@ -1090,7 +1138,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char buf[BUFSIZE]; int prop = 0; int do_host_hiding = 0; - char* account = NULL, *fakehost = NULL; + char* account = NULL, *fakehost = NULL, *keepconn = NULL; struct Membership *chan; what = MODE_ADD; @@ -1262,6 +1310,16 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, else ClearWebIRC(sptr); break; + case 'K': + if (what == MODE_ADD) { + if(*(p + 1) == 0) + break; + keepconn = *(++p); + SetKeepConnEnabled(sptr); + } else { + ClearKeepConnEnabled(sptr); + } + break; case 'r': if (*(p + 1) && (what == MODE_ADD)) { account = *(++p); @@ -1290,6 +1348,12 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, case 'z': /* Formerly SSL mode; we ignore it. */ break; #endif + case 'Z': + if (what == MODE_ADD) + SetNotConn(sptr); + else + ClearNotConn(sptr); + break; default: send_reply(sptr, ERR_UMODEUNKNOWNFLAG, *m); break; @@ -1312,6 +1376,8 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, ClrFlag(sptr, FLAG_FAKEHOST); if (!FlagHas(&setflags, FLAG_SEE_IDLETIME) && IsSeeIdletime(sptr)) ClrFlag(sptr, FLAG_SEE_IDLETIME); + if (!FlagHas(&setflags, FLAG_NOTCONN) && IsNotConn(sptr)) + ClrFlag(sptr, FLAG_NOTCONN); /* * new umode; servers and privileged opers can set it, local users cannot; * prevents users from /kick'ing or /mode -o'ing @@ -1330,6 +1396,10 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, ClearHiddenOper(sptr); if (!FlagHas(&setflags, FLAG_OVERRIDECC) && IsOverrideCC(sptr) && !HasPriv(sptr, PRIV_UMODE_OVERRIDECC)) ClearOverrideCC(sptr); + if (!FlagHas(&setflags, FLAG_KEEPCONN_ENABLED) && IsKeepConnEnabled(sptr) && !HasPriv(sptr, PRIV_SET_KEEPCONN)) + ClearKeepConnEnabled(sptr); + if(keepconn && !HasPriv(sptr, PRIV_SET_KEEPCONN)) + keepconn = NULL; /* Opers are able to fake the webirc usermode only if FEAT_FAKE_WEBIRC is true. */ if (!FlagHas(&setflags, FLAG_WEBIRC) && IsWebIRC(sptr) && !(feature_bool(FEAT_FAKE_WEBIRC) && IsOper(sptr))) ClearWebIRC(sptr); @@ -1390,6 +1460,12 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, if (!FlagHas(&setflags, FLAG_FAKEHOST) && IsFakeHost(sptr)) { ircd_strncpy(cli_user(sptr)->fakehost, fakehost, HOSTLEN); } + if (!FlagHas(&setflags, FLAG_KEEPCONN_ENABLED) && IsKeepConnEnabled(sptr)) { + sptr->keepconn = atoi(keepconn); + } else if(keepconn && sptr->keepconn != atoi(keepconn)) { + FlagClr(&setflags, FLAG_KEEPCONN_ENABLED); + sptr->keepconn = atoi(keepconn); + } if (IsRegistered(sptr)) { if(do_host_hiding) @@ -1517,7 +1593,7 @@ int send_umode(struct Client *cptr, struct Client *sptr, struct Flags *old, int flag; char *m; int what = MODE_NULL; - int add_fakehost = 0, add_account = 0; + int add_fakehost = 0, add_account = 0, add_keepconn = 0; /* * Build a string in umodeBuf to represent the change in the user's @@ -1544,6 +1620,10 @@ int send_umode(struct Client *cptr, struct Client *sptr, struct Flags *old, if(!serv_modes || FlagHas(old, flag)) continue; add_fakehost = 1; } + + if(flag == FLAG_KEEPCONN_ENABLED) { + add_keepconn = 1; + } switch (sendset) { @@ -1609,6 +1689,11 @@ int send_umode(struct Client *cptr, struct Client *sptr, struct Flags *old, while((*m++ = *t++)) ; /* Empty loop */ --m; /* back up over previous nul-termination */ } + + if(add_keepconn) { + *m++ = ' '; + m += sprintf(m, "%u", sptr->keepconn); + } *m = '\0'; if (*umodeBuf && cptr)