/* ircd allows forwards to existing channels; the target channel must be * +F or the setter must have ops in it */ static bool check_forward(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu) { channel_t *target_c; mychan_t *target_mc; chanuser_t *target_cu; if (!VALID_GLOBAL_CHANNEL_PFX(value) || strlen(value) > 50) return false; if (u == NULL && mu == NULL) return true; target_c = channel_find(value); target_mc = mychan_from(target_c); if (target_c == NULL && target_mc == NULL) return false; if (target_c != NULL && target_c->modes & CMODE_FTARGET) return true; if (target_mc != NULL && target_mc->mlock_on & CMODE_FTARGET) return true; if (u != NULL) { target_cu = chanuser_find(target_c, u); if (target_cu != NULL && target_cu->modes & CSTATUS_OP) return true; if (chanacs_user_flags(target_mc, u) & CA_SET) return true; } else if (mu != NULL) if (chanacs_entity_has_flag(target_mc, entity(mu), CA_SET)) return true; return false; }
static struct chanacs * chanacs_ext_match_user(struct chanacs *ca, struct user *u) { struct this_exttarget *ent; struct mychan *mc; unsigned int flags; ent = (struct this_exttarget *) ca->entity; if (ent->checking > 4) // arbitrary recursion limit? return NULL; if (!(mc = mychan_find(ent->channel))) return NULL; ent->checking++; flags = chanacs_user_flags(mc, u); ent->checking--; if (flags & CA_AKICK) return NULL; if (flags) return ca; return NULL; }
static chanacs_t *chanacs_ext_match_user(chanacs_t *ca, user_t *u) { chanacs_exttarget_t *ent; mychan_t *mc; unsigned int flags; ent = (chanacs_exttarget_t *) ca->entity; if (ent->checking > 4) /* arbitrary recursion limit? */ return NULL; if (!(mc = mychan_find(ent->channel))) return NULL; ent->checking++; flags = chanacs_user_flags(mc, u); ent->checking--; if (flags & CA_AKICK) return NULL; if (flags) return ca; return NULL; }
static void cs_cmd_up(sourceinfo_t *si, int parc, char *parv[]) { chanuser_t *cu; mychan_t *mc; char *name = parv[0]; char *chan = parv[0]; int fl; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "UP"); command_fail(si, fault_needmoreparams, "Syntax: UP <#channel>"); return; } if (!(mc = mychan_find(name))) { command_fail(si, fault_nosuch_target, "\2%s\2 is not registered.", name); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, "\2%s\2 is closed.", name); return; } if (metadata_find(mc, "private:frozen:freezer")) { command_fail(si, fault_noprivs, _("\2%s\2 is frozen."), chan); return; } if (!mc->chan) { command_fail(si, fault_nosuch_target, "\2%s\2 does not exist.", name); return; } if (!si->su) return; // needs to be done over IRC if (chanacs_source_has_flag(mc, si, CA_SUSPENDED)) { command_fail(si, fault_noprivs, _("Your access in %s is \2suspended\2."), chan); return; } cu = chanuser_find(mc->chan, si->su); if (!cu) { command_fail(si, fault_nosuch_target, "You are not on \2%s\2.", mc->name); return; } fl = chanacs_user_flags(mc, cu->user); // Don't check NOOP, because they are explicitly requesting status if (ircd->uses_owner) { if (fl & CA_USEOWNER) { if (fl & CA_AUTOOP && !(ircd->owner_mode & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->owner_mchar[1], CLIENT_NAME(cu->user)); cu->modes |= ircd->owner_mode; } } } if (ircd->uses_protect) { if (fl & CA_USEPROTECT) { if (fl & CA_AUTOOP && !(ircd->protect_mode & cu->modes) && !(ircd->uses_owner && cu->modes & ircd->owner_mode)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->protect_mchar[1], CLIENT_NAME(cu->user)); cu->modes |= ircd->protect_mode; } } } if (fl & (CA_AUTOOP | CA_OP)) { if (fl & CA_AUTOOP && !(CSTATUS_OP & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, 'o', CLIENT_NAME(cu->user)); cu->modes |= CSTATUS_OP; } } if (ircd->uses_halfops) { if (fl & (CA_AUTOHALFOP | CA_HALFOP)) { if (fl & CA_AUTOHALFOP && !(ircd->halfops_mode & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->halfops_mchar[1], CLIENT_NAME(cu->user)); cu->modes |= ircd->halfops_mode; } } } if (fl & (CA_AUTOVOICE | CA_VOICE)) { if (fl & CA_AUTOVOICE && !(CSTATUS_VOICE & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, 'v', CLIENT_NAME(cu->user)); cu->modes |= CSTATUS_VOICE; } } command_success_nodata(si, "Upped successfully on \2%s\2.", mc->name); }
static void cs_cmd_down(sourceinfo_t *si, int parc, char *parv[]) { chanuser_t *cu; mychan_t *mc; char *name = parv[0]; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DOWN"); command_fail(si, fault_needmoreparams, "Syntax: DOWN <#channel>"); return; } if (!(mc = mychan_find(name))) { command_fail(si, fault_nosuch_target, "\2%s\2 is not registered.", name); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, "\2%s\2 is closed.", name); return; } if (!mc->chan) { command_fail(si, fault_nosuch_target, "\2%s\2 does not exist.", name); return; } if (!si->su) return; // needs to be done over IRC cu = chanuser_find(mc->chan, si->su); if (!cu) { command_fail(si, fault_nosuch_target, "You are not on \2%s\2.", mc->name); return; } chanacs_user_flags(mc, cu->user); // Don't check NOOP, because they are explicitly requesting status if (ircd->uses_owner) { if (ircd->owner_mode & cu->modes) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->owner_mchar[1], CLIENT_NAME(cu->user)); cu->modes &= ~ircd->owner_mode; } } if (ircd->uses_protect) { if (ircd->protect_mode & cu->modes) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->protect_mchar[1], CLIENT_NAME(cu->user)); cu->modes &= ~ircd->protect_mode; } } if ((CSTATUS_OP & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, 'o', CLIENT_NAME(cu->user)); cu->modes &= ~CSTATUS_OP; } if (ircd->uses_halfops) { if (ircd->halfops_mode & cu->modes) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->halfops_mchar[1], CLIENT_NAME(cu->user)); cu->modes &= ~ircd->halfops_mode; } } if ((CSTATUS_VOICE & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, 'v', CLIENT_NAME(cu->user)); cu->modes &= ~CSTATUS_VOICE; } command_success_nodata(si, "Downed successfully on \2%s\2.", mc->name); }