nick *np;
reguser *rup;
regchanuser *rcup;
- flag_t themodes;
+ flag_t themodes = 0;
/* Skip unregistered channels */
if (!(rcp=cp->index->exts[chanservext]))
}
int checkpassword(reguser *rup, const char *pass) {
+ if (!(*rup->password))
+ return 0;
+
if (!strncmp(rup->password, pass, PASSLEN))
return 1;
return 0;
int checkresponse(reguser *rup, const unsigned char *entropy, const char *response, CRAlgorithm algorithm) {
char usernamel[NICKLEN+1], *dp, *up;
+ if (!(*rup->password))
+ return 0;
+
for(up=rup->username,dp=usernamel;*up;)
*dp++ = ToLower(*up++);
*dp = '\0';
if (IsAccount(np) && np->auth) {
if (np->auth->exts[chanservaext]) {
rup=getreguserfromnick(np);
+
/* safe? */
- if(rup && UHasSuspension(rup)) {
- chanservkillstdmessage(np, QM_SUSPENDKILL);
- return;
+ if(rup) {
+ if (UIsDelayedGline(rup)) {
+ /* delayed-gline - schedule the user's squelching */
+ deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
+ scheduleoneshot(time(NULL)+rand()%900, &chanservdgline, (void*)rup);
+ } else if (UIsGline(rup)) {
+ /* instant-gline - lets be lazy and set a schedule expiring now :) */
+ deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
+ scheduleoneshot(time(NULL), &chanservdgline, (void*)rup);
+ } else if(UHasSuspension(rup)) {
+ chanservkillstdmessage(np, QM_SUSPENDKILL);
+ return;
+ }
}
cs_doallautomodes(np);
} else {
}
}
+/* Slightly misnamed function that checks each USER on the channel against channel
+ * settings. Possible actions are opping/deopping, voicing/devoicing, and banning
+ * for chanflag +k or chanlev flag +b */
void cs_docheckopvoice(channel *cp, modechanges *changes) {
regchan *rcp;
reguser *rup;
continue;
if ((np=getnickbynumeric(cp->users->content[i]))==NULL) {
- Error("chanserv",ERR_ERROR,"Found non-existent numeric %d on channel %s",cp->users->content[i],
+ Error("chanserv",ERR_ERROR,"Found non-existent numeric %lu on channel %s",cp->users->content[i],
cp->index->name->content);
continue;
}
else
rcup=NULL;
- if (rcup && CUIsBanned(rcup) && !IsService(np)) {
- cs_banuser(changes, cp->index, np, NULL);
- continue;
- }
-
- if (!IsService(np) && CIsKnownOnly(rcp) && !(rcup && CUKnown(rcup))) {
- cs_banuser(changes, cp->index, np, "Authorised users only.");
- continue;
+ /* Various things that might ban the user - don't apply these to +o, +k or +X users */
+ if (!IsService(np) && !IsXOper(np) && !IsOper(np)) {
+ if (rcup && CUIsBanned(rcup)) {
+ cs_banuser(changes, cp->index, np, NULL);
+ continue;
+ }
+
+ /* chanflag +k checks; kick them if they "obviously" can't rejoin without a ban */
+ if (CIsKnownOnly(rcp) && !(rcup && CUKnown(rcup))) {
+ if (IsInviteOnly(cp) || (IsRegOnly(cp) && !IsAccount(np))) {
+ localkickuser(chanservnick,cp,np,"Authorised users only.");
+ } else {
+ cs_banuser(NULL, cp->index, np, "Authorised users only.");
+ }
+ continue;
+ }
}
-
+
if ((cp->users->content[i] & CUMODE_OP) && !IsService(np)) {
if ((CIsBitch(rcp) && (!rcup || !CUHasOpPriv(rcup))) ||
(rcup && CUIsDeny(rcup)))
return;
for (rcup=rup->knownon;rcup;rcup=rcup->nextbyuser) {
+ /* Skip suspended channels */
+ if (CIsSuspended(rcup->chan))
+ continue;
+
if (rcup->chan->index->channel) {
/* Channel exists */
if ((lp=getnumerichandlefromchanhash(rcup->chan->index->channel->users, np->numeric))) {
/* User is on channel.. */
+ if (CUKnown(rcup) && rcup->chan->index->channel->users->totalusers >= 3) {
+ /* This meets the channel use criteria, update. */
+ rcup->chan->lastactive=time(NULL);
+
+ /* Don't spam the DB though for channels with lots of joins */
+ if (rcup->chan->lastcountersync < (time(NULL) - COUNTERSYNCINTERVAL)) {
+ csdb_updatechannelcounters(rcup->chan);
+ rcup->chan->lastcountersync=time(NULL);
+ }
+ }
+
/* Update last use time */
rcup->usetime=getnettime();
regchan *rcp;
int i,j;
- if (IsService(np))
+ if (IsService(np) || IsOper(np) || IsXOper(np))
return;
/* Avoid races: memcpy the channel array */
for (j=0;j<i;j++) {
if ((rcp=ca[j]->index->exts[chanservext]) && !CIsSuspended(rcp) &&
- CIsEnforce(rcp) && nickbanned(np, ca[j]))
+ CIsEnforce(rcp) && nickbanned_visible(np, ca[j]))
localkickuser(chanservnick, ca[j], np, "Banned.");
}
continue;
if ((np=getnickbynumeric(cp->users->content[i]))==NULL) {
- Error("chanserv",ERR_ERROR,"Found numeric %d on channel %s who doesn't exist.",
+ Error("chanserv",ERR_ERROR,"Found numeric %lu on channel %s who doesn't exist.",
cp->users->content[i], cp->index->name->content);
continue;
}
- if (IsService(np))
+ if (IsService(np) || IsOper(np) || IsXOper(np))
continue;
for (rbp=rcp->bans;rbp;rbp=rbp->next) {
if (((!rbp->expiry) || (rbp->expiry <= now)) &&
- nickmatchban(np, rbp->cbp)) {
- if (!nickbanned(np, cp)) {
+ nickmatchban_visible(np, rbp->cbp)) {
+ if (!nickbanned_visible(np, cp)) {
localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_ADD);
}
localkickuser(chanservnick,cp,np,rbp->reason?rbp->reason->content:"Banned.");
if (CIsEnforce(rcp)) {
for (cbp=cp->bans;cbp;cbp=cbp->next) {
- if ((cbp->timeset>=rcp->lastbancheck) && nickmatchban(np, cbp))
+ if ((cbp->timeset>=rcp->lastbancheck) && nickmatchban_visible(np, cbp))
localkickuser(chanservnick,cp,np,"Banned.");
}
rcp->lastbancheck=time(NULL);
if (CIsAutoLimit(rcp)) {
if (!rcp->limit || rcp->autoupdate <= now) {
- /* Update limit.. */
- rcp->limit=cp->users->totalusers+rcp->autolimit;
- rcp->status |= QCSTAT_MODECHECK;
+ /* Only update the limit if there are <= (autolimit/2) or
+ * >= (autolimit * 1.5) slots free */
+
+ if ((cp->users->totalusers >= (rcp->limit - rcp->autolimit/2)) ||
+ (cp->users->totalusers <= (rcp->limit - (3 * rcp->autolimit)/2))) {
+ rcp->limit=cp->users->totalusers+rcp->autolimit;
+ rcp->status |= QCSTAT_MODECHECK;
+ }
/* And set the schedule for the next update */
rcp->autoupdate = now + AUTOLIMIT_INTERVAL;
freesstring(rbp->reason);
freechanban(rbp->cbp);
freeregban(rbp);
- } else if (nickmatchban(np,(*rbh)->cbp)) {
+ } else if (nickmatchban_visible(np,(*rbh)->cbp)) {
/* This user matches this ban.. */
- if (!nickbanned(np,cp)) {
+ if (!nickbanned_visible(np,cp)) {
/* Only bother putting the ban on the channel if they're not banned already */
/* (might be covered by this ban or a different one.. doesn't really matter */
localsetmodeinit(&changes, cp, chanservnick);
for (i=0;(cip->channel) && i<cip->channel->users->hashsize;i++) {
if (cip->channel->users->content[i]!=nouser &&
(np=getnickbynumeric(cip->channel->users->content[i])) &&
- !IsService(np) &&
- nickmatchban(np, rbp->cbp))
+ !IsService(np) && !IsOper(np) && !IsXOper(np) &&
+ nickmatchban_visible(np, rbp->cbp))
localkickuser(chanservnick, cip->channel, np, rbp->reason ? rbp->reason->content : "Banned.");
}
if (!cip->channel)
return;
- if (nickbanned(np, cip->channel)) {
+ if (nickbanned_visible(np, cip->channel)) {
localkickuser(chanservnick, cip->channel, np, reason?reason:"Banned.");
return;
}