* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
- * $Id: s_user.c 3131 2007-01-21 15:36:31Z jilles $
+ * $Id: s_user.c 3219 2007-02-24 19:34:28Z jilles $
*/
#include "stdinc.h"
#include "monitor.h"
#include "snomask.h"
#include "blacklist.h"
+#include "substitution.h"
static void report_and_set_user_flags(struct Client *, struct ConfItem *);
void user_welcome(struct Client *source_p);
char umodebuf[128];
+static int orphaned_umodes = 0;
int user_modes[256] = {
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */
if(!valid_hostname(source_p->host))
{
- sendto_one(source_p,
- ":%s NOTICE %s :*** Notice -- You have an illegal character in your hostname",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** Notice -- You have an illegal character in your hostname");
strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
if(IsNeedIdentd(aconf))
{
ServerStats->is_ref++;
- sendto_one(source_p,
- ":%s NOTICE %s :*** Notice -- You need to install identd to use this server",
- me.name, client_p->name);
+ sendto_one_notice(source_p, ":*** Notice -- You need to install identd to use this server");
exit_client(client_p, source_p, &me, "Install identd");
return (CLIENT_EXITED);
}
if(IsNeedSasl(aconf) && !*user->suser)
{
ServerStats->is_ref++;
- sendto_one(source_p,
- ":%s NOTICE %s :*** Notice -- You need to identify via SASL to use this server",
- me.name, client_p->name);
+ sendto_one_notice(source_p, ":*** Notice -- You need to identify via SASL to use this server");
exit_client(client_p, source_p, &me, "SASL access only");
return (CLIENT_EXITED);
}
source_p->sockhost, source_p->preClient->dnsbl_listed->host);
else
{
+ dlink_list varlist;
+
+ substitution_append_var(&varlist, "nick", source_p->name);
+ substitution_append_var(&varlist, "ip", source_p->sockhost);
+ substitution_append_var(&varlist, "host", source_p->host);
+ substitution_append_var(&varlist, "dnsbl-host", source_p->preClient->dnsbl_listed->host);
+ substitution_append_var(&varlist, "network-name", ServerInfo.network_name);
+
ServerStats->is_ref++;
+
sendto_one(source_p, form_str(ERR_YOUREBANNEDCREEP),
me.name, source_p->name,
- source_p->preClient->dnsbl_listed->reject_reason);
+ substitution_parse(source_p->preClient->dnsbl_listed->reject_reason, &varlist));
+
+ substitution_free(&varlist);
+
sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s",
source_p->sockhost, source_p->preClient->dnsbl_listed->host);
source_p->preClient->dnsbl_listed->hits++;
add_to_id_hash(source_p->id, source_p);
}
- source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes;
+ source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes & ~orphaned_umodes;
if (source_p->umodes & UMODE_INVISIBLE)
Count.invisi++;
/* If this user is being spoofed, tell them so */
if(IsConfDoSpoofIp(aconf))
{
- sendto_one(source_p,
- ":%s NOTICE %s :*** Spoofing your IP. congrats.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** Spoofing your IP. congrats.");
}
/* If this user is in the exception class, Set it "E lined" */
if(IsConfExemptKline(aconf))
{
SetExemptKline(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from K/D/G/X lines. congrats.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from K/D/G/X lines. congrats.");
}
if(IsConfExemptGline(aconf))
/* dont send both a kline and gline exempt notice */
if(!IsConfExemptKline(aconf))
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from G lines.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from G lines.");
}
if(IsConfExemptDNSBL(aconf))
/* kline exempt implies this, don't send both */
if(!IsConfExemptKline(aconf))
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from DNS blacklists.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from DNS blacklists.");
/* If this user is exempt from user limits set it F lined" */
if(IsConfExemptLimits(aconf))
{
SetExemptLimits(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from user limits. congrats.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, "*** You are exempt from user limits. congrats.");
}
/* If this user is exempt from idle time outs */
if(IsConfIdlelined(aconf))
{
SetIdlelined(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from idle limits. congrats.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from idle limits. congrats.");
}
if(IsConfExemptFlood(aconf))
{
SetExemptFlood(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from flood limits.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from flood limits.");
}
if(IsConfExemptSpambot(aconf))
{
SetExemptSpambot(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from spambot checks.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from spambot checks.");
}
if(IsConfExemptJupe(aconf))
{
SetExemptJupe(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from juped channel warnings.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from juped channel warnings.");
}
if(IsConfExemptResv(aconf))
{
SetExemptResv(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from resvs.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from resvs.");
}
if(IsConfExemptShide(aconf))
{
SetExemptShide(source_p);
- sendto_one(source_p,
- ":%s NOTICE %s :*** You are exempt from serverhiding.",
- me.name, source_p->name);
+ sendto_one_notice(source_p, ":*** You are exempt from serverhiding.");
}
}
if((flag = user_modes[(unsigned char) *pm]))
{
if(MyConnect(source_p)
- && !IsOper(source_p)
- && (ConfigFileEntry.oper_only_umodes & flag))
+ && ((!IsOper(source_p)
+ && (ConfigFileEntry.oper_only_umodes & flag))
+ || (orphaned_umodes & flag)))
{
if (what == MODE_ADD || source_p->umodes & flag)
badflag = YES;
if(MyClient(source_p) && (source_p->snomask & SNO_NCHANGE) && !IsOperN(source_p))
{
- sendto_one(source_p,
- ":%s NOTICE %s :*** You need oper and N flag for +s +n", me.name, parv[0]);
+ sendto_one_notice(source_p, ":*** You need oper and N flag for +s +n");
source_p->snomask &= ~SNO_NCHANGE; /* only tcm's really need this */
}
if(MyClient(source_p) && (source_p->umodes & UMODE_OPERWALL) && !IsOperOperwall(source_p))
{
- sendto_one(source_p,
- ":%s NOTICE %s :*** You need oper and operwall flag for +z", me.name, parv[0]);
+ sendto_one_notice(source_p, ":*** You need oper and operwall flag for +z");
source_p->umodes &= ~UMODE_OPERWALL;
}
if(MyConnect(source_p) && (source_p->umodes & UMODE_ADMIN) &&
(!IsOperAdmin(source_p) || IsOperHiddenAdmin(source_p)))
{
- sendto_one(source_p,
- ":%s NOTICE %s :*** You need oper and A flag for +a", me.name, parv[0]);
+ sendto_one_notice(source_p, ":*** You need oper and A flag for +a");
source_p->umodes &= ~UMODE_ADMIN;
}
if(ConfigFileEntry.short_motd)
{
- sendto_one(source_p,
- "NOTICE %s :*** Notice -- motd was last changed at %s",
- source_p->name, user_motd_changed);
-
- sendto_one(source_p,
- "NOTICE %s :*** Notice -- Please read the motd if you haven't read it",
- source_p->name);
+ sendto_one_notice(source_p, ":*** Notice -- motd was last changed at %s", user_motd_changed);
+ sendto_one_notice(source_p, ":*** Notice -- Please read the motd if you haven't read it");
sendto_one(source_p, form_str(RPL_MOTDSTART),
me.name, source_p->name, me.name);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s (%s@%s) is now an operator", source_p->name,
source_p->username, source_p->host);
+ if(!(old & UMODE_INVISIBLE) && IsInvisible(source_p))
+ ++Count.invisi;
+ if((old & UMODE_INVISIBLE) && !IsInvisible(source_p))
+ --Count.invisi;
send_umode_out(source_p, source_p, old);
sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
construct_snobuf(source_p->snomask));
sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name);
- sendto_one(source_p, ":%s NOTICE %s :*** Oper privs are %s", me.name,
- source_p->name, get_oper_privs(oper_p->flags));
+ sendto_one_notice(source_p, ":*** Oper privs are %s", get_oper_privs(oper_p->flags));
send_oper_motd(source_p);
return (1);
}
+/*
+ * find_umode_slot
+ *
+ * inputs - NONE
+ * outputs - an available umode bitmask or
+ * 0 if no umodes are available
+ * side effects - NONE
+ */
+unsigned int
+find_umode_slot(void)
+{
+ unsigned int all_umodes = 0, my_umode = 0, i;
+
+ for (i = 0; i < 128; i++)
+ all_umodes |= user_modes[i];
+
+ for (my_umode = 1; my_umode && (all_umodes & my_umode);
+ my_umode <<= 1);
+
+ return my_umode;
+}
+
void
construct_umodebuf(void)
{
int i;
char *ptr = umodebuf;
+ static int prev_user_modes[128];
*ptr = '\0';
for (i = 0; i < 128; i++)
+ {
+ if (prev_user_modes[i] != 0 && prev_user_modes[i] != user_modes[i])
+ {
+ if (user_modes[i] == 0)
+ {
+ orphaned_umodes |= prev_user_modes[i];
+ sendto_realops_snomask(SNO_DEBUG, L_ALL, "Umode +%c is now orphaned", i);
+ }
+ else
+ {
+ orphaned_umodes &= ~prev_user_modes[i];
+ sendto_realops_snomask(SNO_DEBUG, L_ALL, "Orphaned umode +%c is picked up by module", i);
+ }
+ user_modes[i] = prev_user_modes[i];
+ }
+ else
+ prev_user_modes[i] = user_modes[i];
if (user_modes[i])
*ptr++ = (char) i;
+ }
*ptr++ = '\0';
}