#include "module.h" #define AUTHOR "SGR" #define VERSION "1.03" /* ----------------------------------------------------------- * Name: cs_HASACCESSTO * Author: SGR * Date: 26/08/2003 * ----------------------------------------------------------- * Functions: m_has_access * Limitations: Target user must be online and NickServ * registered. * Tested: Ultimate(2.8.x), Unreal(3.2), Viagra. * ----------------------------------------------------------- * This version has been tested on Ultimate2.8.6, Viagra and * Unreal. PTLINK and Bahamut have NOT been tested so are not * officially supported. * * For help regarding this module load it and refer to to the * in IRC help found @ /ChanServ HASACCESSTOTO HELP. * * This modules has 0 configurable options * * I will endeavour to make it so that the target user does not * need to be online for this command to function for a future * version, if one is coded. * * * Thanks to dengel for the idea for this module. * * ----------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* START OF CONFIGURATION BLOCK - please read the comments :) */ /* ---------------------------------------------------------------------- */ /* This modules has 0 configurable options */ /* ---------------------------------------------------------------------- */ /* DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING */ /* ---------------------------------------------------------------------- */ int check_access_for_chaccm(NickAlias * user, ChannelInfo * ci, int what); int m_has_access(User * u); /*typedef struct { int16 in_use; * 1 if this entry is in use, else 0 * int16 level; NickCore *nc; * Guaranteed to be non-NULL if in use, NULL if not * time_t last_seen; } ChanAccessforchaccm;*/ int AnopeInit(int argc, char **argv) { Command *c; alog("Loading module cs_hasaccessto.so"); c = createCommand("HASACCESSTO",m_has_access,NULL,-1,-1,-1,-1,-1); moduleAddCommand(CHANSERV, c, MOD_HEAD); alog("[cs_hasaccessto] New command: /msg %s HASACCESSTO", s_ChanServ); alog("[cs_hasaccessto] For information see: /msg %s HASSACCESS HELP", s_ChanServ); alog("[cs_hasaccessto] Yayness!(tm) - MODULE LOADED AND ACTIVE"); moduleAddAuthor(AUTHOR); moduleAddVersion(VERSION); return MOD_CONT; } void AnopeFini(void) { alog("Unloading module cs_hasaccessto.so"); } int m_has_access(User * u) { char *chan = strtok(NULL, " "); char *possnick = strtok(NULL, ""); ChannelInfo *ci; Channel *c=NULL; NickAlias *na=NULL; User *K; if ((!chan) || (stricmp(chan,"help") == 0)) { notice(s_ChanServ, u->nick, "-----------------------------------------------------------------------"); notice(s_ChanServ, u->nick, " Syntax: HASACCESSTO #chan nick"); notice(s_ChanServ, u->nick, " "); notice(s_ChanServ, u->nick, " This command allows users with the ability to view a channels access"); notice(s_ChanServ, u->nick, " list to see excatly what commands that user can perform on that"); notice(s_ChanServ, u->nick, " channel. Currently the user must be online for the check be made."); notice(s_ChanServ, u->nick, " "); notice(s_ChanServ, u->nick, " Commands the user cannot peform (as listed in /%s HELP LEVELS", s_ChanServ); notice(s_ChanServ, u->nick, " DESC) are not shown."); notice(s_ChanServ, u->nick, "-----------------------------------------------------------------------"); return MOD_STOP; } if (!possnick) { notice(s_ChanServ, u->nick, " Syntax: HASACCESSTO #Chan text"); return MOD_STOP; } K = finduser(possnick); if (!K) { if (possnick) { notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, possnick); return MOD_STOP; } else { notice_lang(s_NickServ, u, NICK_NOT_REGISTERED); return MOD_STOP; } return MOD_STOP; } if (!(na = K->na)) { notice_lang(s_ChanServ, u, NICK_X_NOT_REGISTERED, possnick); return MOD_CONT; } else if (na->status & NS_VERBOTEN) { notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, na->nick); return MOD_CONT; } if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); return MOD_STOP; } if (!(ci = c->ci)) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name); return MOD_STOP; } if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name); return MOD_STOP; } if (!is_services_admin(u) && !check_access(u, ci, CA_ACCESS_LIST)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); return MOD_STOP; } else { ci = c->ci; notice(s_ChanServ, u->nick, "--- %s's access to %s ---", na->nick, chan); /* NoJOIN and AUTODEOP */ if (check_access_for_chaccm(na, ci, CA_NOJOIN)) { notice(s_ChanServ, u->nick, "%s CANNOT join %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_AUTODEOP)) { notice(s_ChanServ, u->nick, "%s CANNOT be a channel operator on %s", na->nick, chan); } /* The 'me' commands - voiceme, kickme, etc.. */ if (check_access_for_chaccm(na, ci, CA_UNBAN)) { notice(s_ChanServ, u->nick, "%s can UNBAN themselves from %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_INVITE)) { notice(s_ChanServ, u->nick, "%s can INVITE themselves to %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_GETKEY)) { notice(s_ChanServ, u->nick, "%s can use the GETKEY command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_VOICEME)) { notice(s_ChanServ, u->nick, "%s can use the VOICEME command on %s", na->nick, chan); } #ifdef HAS_HALFOP if (check_access_for_chaccm(na, ci, CA_HALFOPME)) { notice(s_ChanServ, u->nick, "%s can use the HALFOPME command on %s", na->nick, chan); } #endif if (check_access_for_chaccm(na, ci, CA_OPDEOPME)) { notice(s_ChanServ, u->nick, "%s can OP/DEOP themselves on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_PROTECTME)) { notice(s_ChanServ, u->nick, "%s can use the PROTECTME command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_KICKME)) { notice(s_ChanServ, u->nick, "%s can use the KICKME command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_BANME)) { notice(s_ChanServ, u->nick, "%s can use the BANME command on %s", na->nick, chan); } /* Op/Voice/Deop/Halfop etc.. etc */ if (check_access_for_chaccm(na, ci, CA_VOICE)) { notice(s_ChanServ, u->nick, "%s can use the VOICE command on %s", na->nick, chan); } #ifdef HAS_HALFOP if (check_access_for_chaccm(na, ci, CA_HALFOP)) { notice(s_ChanServ, u->nick, "%s can use the HALFOP command on %s", na->nick, chan); } #endif if (check_access_for_chaccm(na, ci, CA_TOPIC)) { notice(s_ChanServ, u->nick, "%s can use the TOPIC command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_OPDEOP)) { notice(s_ChanServ, u->nick, "%s can use the OP and DEOP commands on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_KICK)) { notice(s_ChanServ, u->nick, "%s can use the KICK command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_SIGNKICK)) { notice(s_ChanServ, u->nick, "%s can use the KICK command on %s (secretly)", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_BAN)) { notice(s_ChanServ, u->nick, "%s can use the BAN command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_PROTECT)) { notice(s_ChanServ, u->nick, "%s can use the PROTECT command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_AKICK)) { notice(s_ChanServ, u->nick, "%s can use the AKICK command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_SET)) { notice(s_ChanServ, u->nick, "%s can use the SET command on %s's %s SET options", possnick, s_ChanServ, chan); } if (check_access_for_chaccm(na, ci, CA_CLEAR)) { notice(s_ChanServ, u->nick, "%s can use the CLEAR command on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_ACCESS_LIST)) { notice(s_ChanServ, u->nick, "%s can view the access list for %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_ACCESS_CHANGE)) { notice(s_ChanServ, u->nick, "%s can view the modify list for %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_MEMO)) { notice(s_ChanServ, u->nick, "%s can view memo's set to %s by %s", na->nick, chan, s_MemoServ); } if (check_access_for_chaccm(na, ci, CA_ASSIGN)) { notice(s_ChanServ, u->nick, "%s can ASSIGN a %s bot to %s", possnick, s_BotServ, chan); } if (check_access_for_chaccm(na, ci, CA_BADWORDS)) { notice(s_ChanServ, u->nick, "%s can modify a %s bot's BADWORDS list on %s", possnick, s_BotServ, chan); } if (check_access_for_chaccm(na, ci, CA_FANTASIA)) { notice(s_ChanServ, u->nick, "%s can use FANTASY commands (from a %s bot) on %s",possnick, s_BotServ, chan); } if (check_access_for_chaccm(na, ci, CA_SAY)) { notice(s_ChanServ, u->nick, "%s can use the %s 'SAY' command on %s", possnick, s_BotServ, chan); } if (check_access_for_chaccm(na, ci, CA_GREET)) { notice(s_ChanServ, u->nick, "%s can be 'greeted' by a %s bot on %s", possnick, s_BotServ, chan); } if (check_access_for_chaccm(na, ci, CA_NOKICK)) { notice(s_ChanServ, u->nick, "%s will not be kicked by %s kickers on %s", possnick, s_BotServ, chan); } if (check_access_for_chaccm(na, ci, CA_AUTOPROTECT)) { notice(s_ChanServ, u->nick, "%s can be automatically be given protected status on %s", na->nick, chan); } if (check_access_for_chaccm(na, ci, CA_AUTOOP)) { notice(s_ChanServ, u->nick, "%s can be automatically be given operator status on %s", na->nick, chan); notice(s_ChanServ, u->nick, "--- End of List ---"); return MOD_STOP; } if (check_access_for_chaccm(na, ci, CA_AUTOHALFOP)) { notice(s_ChanServ, u->nick, "%s can be automatically be given half-operator status on %s", na->nick, chan); notice(s_ChanServ, u->nick, "--- End of List ---"); return MOD_STOP; } if (check_access_for_chaccm(na, ci, CA_AUTOVOICE)) { notice(s_ChanServ, u->nick, "%s can be automatically be given voice status on %s", na->nick, chan); notice(s_ChanServ, u->nick, "--- End of List ---"); return MOD_STOP; } notice(s_ChanServ, u->nick, "--- End of List ---"); } return MOD_STOP; } /* --------------------------------------------------- */ /* --------------------------------------------------- */ /* --------------------------------------------------- */ /* Most of the code below has been ripped and modified * from ChanServ.c to make compatible with NickAlias * not User input, (so lookups on users not currently on the * net can be made). Since it all comes back to the DB's * [& NickCore/NickAliases structures] anyway some minor mods of * functions to allow them to take this data directly * and to not have to convert *should* work. * * Not to metion I really can't stand it when people * don't make sure *EVERY* IF statement has a corrosponding * set of {} to go with it. * * if (something) // This is bloody anoying * return 0; // Stop doing it :P * * * if (something) { // This is IMO the Right * return 0; // way to do it. * } // with a full set of {}'s * * */ /* --------------------------------------------------- */ /* --------------------------------------------------- */ /* --------------------------------------------------- */ int check_access_for_chaccm(NickAlias * user, ChannelInfo * ci, int what) { int level = get_access(user->u, ci); int limit = ci->levels[what]; if (level > 0) { ci->last_used = time(NULL); } if (level == ACCESS_FOUNDER) { return (what == CA_AUTODEOP || what == CA_NOJOIN) ? 0 : 1; } /* Hacks to make flags work */ if (what == CA_AUTODEOP && (ci->flags & CI_SECUREOPS) && level == 0) { return 1; } if (limit == ACCESS_INVALID) { return 0; } if (what == CA_AUTODEOP || what == CA_NOJOIN) { return level <= ci->levels[what]; } else { return level >= ci->levels[what]; } return 0; } ChanAccess *get_access_entry_for_chaccm(NickCore * nc, ChannelInfo * ci) { ChanAccess *access = NULL; int i; for ((access = ci->access, i = 0); (i < ci->accesscount); (access++, i++)) { if (access->in_use && access->nc == nc) { return access; } } return NULL; } int get_access_for_chaccm(NickAlias *na, ChannelInfo * ci) { ChanAccess *access; if (!ci) { return MOD_STOP; } if ((access = get_access_entry_for_chaccm(na->nc, ci))) { return access->level; } return MOD_CONT; } int is_founder_for_chaccm(NickAlias * na, ChannelInfo * ci) { if (na->u->isSuperAdmin) { return 1; } if (na && na->nc == ci->founder) { return 1; } return 0; }