include ../build.mk
.PHONY: all
-all: control.so
+all: control.so control_commands.so control_management.so
control-lite.so: control-lite.o
-control.so: control.o
+control.so: control.o control_db.o control_policy.o
+
+control_commands.so: control_commands.o
+
+control_management.so: control_management.o
#include "../lib/version.h"
#include "../lib/irc_string.h"
#include "control.h"
+#include "control_policy.h"
#include <stdio.h>
#include <string.h>
nick *mynick;
CommandTree *controlcmds;
-ControlMsg controlreply;
-ControlWall controlwall;
-ControlPermitted controlpermitted;
DestroyExt controldestroyext;
+int noperserv_ext;
+
+const flag no_commandflags[] = {
+ { 'o', __NO_OPER },
+ { 't', __NO_TRUST },
+ { 's', __NO_STAFF },
+ { 'S', __NO_SEC },
+ { 'd', __NO_DEVELOPER },
+ { 'L', __NO_LEGACY },
+ { 'O', __NO_OPERED },
+ { 'r', __NO_AUTHED },
+ { 'R', __NO_ACCOUNT },
+ { 'Y', __NO_RELAY },
+ { '\0', 0 }
+ };
+
+const flag no_userflags[] = {
+ { 'o', __NO_OPER },
+ { 't', __NO_TRUST },
+ { 's', __NO_STAFF },
+ { 'S', __NO_SEC },
+ { 'd', __NO_DEVELOPER },
+ { 'Y', __NO_RELAY },
+ { '\0', 0 }
+ };
+
+const flag no_noticeflags[] = {
+ { 'm', NL_MANAGEMENT }, /* hello, password, userflags, noticeflags */
+ { 't', NL_TRUSTS }, /* trust stuff... */
+ { 'k', NL_KICKKILLS }, /* KICK/KILL commands */
+ { 'I', NL_MISC }, /* misc commands */
+ { 'g', NL_GLINES }, /* GLINE commands */
+ { 'h', NL_HITS }, /* Where a gline or kill is set automatically by the bot */
+ { 'c', NL_CLONING }, /* Clone detection */
+ { 'C', NL_CLEARCHAN }, /* When someone clearchans */
+ { 'f', NL_FAKEUSERS }, /* Fakeuser addition */
+ { 'b', NL_BROADCASTS }, /* Broadcast/mbroadcast/sbroadcast */
+ { 'o', NL_OPERATIONS }, /* insmod/rmmod/etc */
+ { 'O', NL_OPERING }, /* when someone opers */
+ { 'n', NL_NOTICES }, /* turn off to receive notices instead of privmsgs */
+ { 'A', NL_ALL_COMMANDS }, /* all commands sent */
+ { '\0', 0 }
+ };
void controldestroycmdext(void *ext);
void handlemessages(nick *target, int messagetype, void **args);
void controlnoticeopers(flag_t permissionlevel, flag_t noticelevel, char *format, ...);
int controlcheckpermitted(flag_t level, nick *user);
void handlesignal(int hooknum, void *arg);
+void noperserv_oper_detection(int hooknum, void *arg);
+void noperserv_whois_handler(int hooknum, void *arg);
+void noperserv_whois_account_handler(int hooknum, void *arg);
+
+#define HOOK_CONTROL_WHOISREQUEST_AUTHNAME -1
+#define HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER -2
+
+static int init;
void _init() {
+ if(!noperserv_load_db())
+ return;
+
controlcmds=newcommandtree();
- controlreply=&controlmessage;
- controlwall=&controlnoticeopers;
- controlpermitted=&controlcheckpermitted;
controldestroyext=&controldestroycmdext;
registercontrolhelpcmd("status",NO_DEVELOPER,1,&controlstatus,"Usage: status ?level?\nDisplays status information, increasing level gives more verbose information.");
registerhook(HOOK_CORE_REHASH, &handlesignal);
registerhook(HOOK_CORE_SIGINT, &handlesignal);
+ registerhook(HOOK_NICK_MODEOPER, &noperserv_oper_detection);
+ registerhook(HOOK_CONTROL_WHOISREQUEST, &noperserv_whois_handler);
+
+ noperserv_ext = registerauthnameext("noperserv", 1);
+
scheduleoneshot(time(NULL)+1,&controlconnect,NULL);
+
+ init = 1;
}
void _fini() {
+ if (!init)
+ return;
+
deleteallschedules(&controlconnect);
if (mynick) {
deregisterlocaluser(mynick,"Leaving");
deregisterhook(HOOK_CORE_REHASH, &handlesignal);
deregisterhook(HOOK_CORE_SIGINT, &handlesignal);
+ deregisterhook(HOOK_NICK_MODEOPER, &noperserv_oper_detection);
+ deregisterhook(HOOK_CONTROL_WHOISREQUEST, &noperserv_whois_handler);
+
+ releaseauthnameext(noperserv_ext);
+
+ noperserv_cleanup_db();
}
void registercontrolhelpcmd(const char *name, int level, int maxparams, CommandHandler handler, char *helpstr) {
controlreply(hooknick,"%s",(char *)arg);
}
-int controlwhois(void *sender, int cargc, char **cargv) {
+static int controlwhois_plain(void *sender, int cargc, char **cargv) {
nick *target;
channel **channels;
char buf[BUFSIZE];
return CMD_OK;
}
+int controlwhois(void *sender, int cargc, char **cargv) {
+ authname *an;
+ no_autheduser *au;
+ nick *np = (nick *)sender;
+
+ if(cargc < 1)
+ return controlwhois_plain(sender, cargc, cargv);
+
+ if(cargv[0][0] != '#') {
+ if(cargv[0][0] == '*')
+ cargv[0][0] = '#';
+ return controlwhois_plain(sender, cargc, cargv);
+ }
+
+ an = findauthnamebyname(cargv[0] + 1);
+ if(!an) {
+ controlreply(np, "Account not registered.");
+ return CMD_OK;
+ }
+
+ au = noperserv_get_autheduser(an);
+ if(!au) {
+ controlreply(np, "User does not have a NOperserv account.");
+ return CMD_OK;
+ }
+
+ controlreply(np, "Account : %s", au->authname->name);
+
+ hooknick = np;
+
+ registerhook(HOOK_CONTROL_WHOISREPLY, &handlewhois);
+ noperserv_whois_account_handler(HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER, (void *)au);
+ deregisterhook(HOOK_CONTROL_WHOISREPLY, &handlewhois);
+
+ controlreply(np, "Flags : %s", printflags(NOGetAuthLevel(au), no_userflags));
+
+ return CMD_OK;
+}
+
+void noperserv_whois_handler(int hooknum, void *arg) {
+ char message[100];
+ nick *np = (nick *)arg;
+ no_autheduser *au;
+ if(!np)
+ return;
+
+ if(IsAccount(np)) {
+ au = NOGetAuthedUser(np);
+ if(au) {
+ snprintf(message, sizeof(message), "Flags : %s", printflags(NOGetAuthLevel(au), no_userflags));
+ noperserv_whois_account_handler(HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER, (void *)au);
+ } else {
+ snprintf(message, sizeof(message), "Flags : (user not known)");
+ noperserv_whois_account_handler(HOOK_CONTROL_WHOISREQUEST_AUTHNAME, (void *)np->authname);
+ }
+ triggerhook(HOOK_CONTROL_WHOISREPLY, message);
+ }
+}
+
+/* mmm, hacky */
+void noperserv_whois_account_handler(int hooknum, void *arg) {
+ int count = 0, found = 0;
+ char nickbuffer[(NICKLEN + 2) * NO_NICKS_PER_WHOIS_LINE - 1]; /* since we don't need space or comma for the first item we're fine NULL wise */
+ char accountspace[NICKLEN + 3]; /* space, comma, null */
+ char message[1024];
+ nick *np;
+
+ nickbuffer[0] = '\0';
+ if(hooknum == HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER) {
+ /* we can just read out the authed user linked list */
+ no_autheduser *au = (void *)arg;
+
+ if(au->authname->nicks)
+ found = 1;
+
+ for(np=au->authname->nicks;np;np=np->nextbyauthname) {
+ snprintf(accountspace, sizeof(accountspace), "%s%s", count++?", ":"", np->nick);
+ strncat(nickbuffer, accountspace, sizeof(nickbuffer));
+ nickbuffer[sizeof(nickbuffer) - 1] = '\0';
+
+ if(count >= NO_NICKS_PER_WHOIS_LINE) {
+ snprintf(message, sizeof(message), "Authed : %s", nickbuffer);
+ triggerhook(HOOK_CONTROL_WHOISREPLY, message);
+ nickbuffer[0] = '\0';
+ count = 0;
+ }
+ }
+ } else {
+ /* inefficient way */
+ char *authname = (char *)arg;
+ int i = 0;
+ nick *sp;
+
+ for(;i<NICKHASHSIZE;i++)
+ for(sp=nicktable[i];sp;sp=sp->next)
+ if(IsAccount(sp) && !ircd_strcmp(sp->authname, authname)) {
+ found = 1;
+
+ snprintf(accountspace, sizeof(accountspace), "%s%s", count++?", ":"", sp->nick);
+ strncat(nickbuffer, accountspace, sizeof(nickbuffer));
+ nickbuffer[sizeof(nickbuffer) - 1] = '\0';
+
+ if(count >= NO_NICKS_PER_WHOIS_LINE) {
+ snprintf(message, sizeof(message), "Authed : %s", nickbuffer);
+ triggerhook(HOOK_CONTROL_WHOISREPLY, message);
+ nickbuffer[0] = '\0';
+ count = 0;
+ }
+ }
+ }
+
+ if(!found) {
+ snprintf(message, sizeof(message), "Authed : (no nicks authed)");
+ triggerhook(HOOK_CONTROL_WHOISREPLY, message);
+ } else if(nickbuffer[0]) {
+ snprintf(message, sizeof(message), "Authed : %s", nickbuffer);
+ triggerhook(HOOK_CONTROL_WHOISREPLY, message);
+ }
+}
+
+
int controlinsmod(void *sender, int cargc, char **cargv) {
if (cargc<1)
return CMD_USAGE;
}
int controlshowcommands(void *sender, int cargc, char **cargv) {
- nick *np=(nick *)sender;
+ nick *np = (nick *)sender;
Command *cmdlist[100];
- int i,n;
-
- n=getcommandlist(controlcmds,cmdlist,100);
-
- controlreply(np,"The following commands are registered at present:");
-
- for(i=0;i<n;i++) {
- controlreply(np,"%s",cmdlist[i]->command->content);
- }
+ int i, n;
- controlreply(np,"End of list.");
+ n = getcommandlist(controlcmds, cmdlist, 100);
+
+ controlreply(np, "The following commands are registered at present:");
+
+ for(i=0;i<n;i++)
+ if(noperserv_policy_command_permitted(cmdlist[i]->level, np))
+ controlreply(np, " %-25s %s", cmdlist[i]->command->content, printflags(cmdlist[i]->level, no_commandflags));
+
+ controlreply(np, "End of list.");
return CMD_OK;
}
sendnoticetouser(mynick,target,"%s",buf);
}
+void controlreply(nick *np, char *format, ...) {
+ char buf[512];
+ va_list va;
+ no_autheduser *au = NOGetAuthedUser(np);
+
+ va_start(va, format);
+ vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+
+ if(au && !(NOGetNoticeLevel(au) & NL_NOTICES)) {
+ controlmessage(np, "%s", buf);
+ } else {
+ controlnotice(np, "%s", buf);
+ }
+}
+
+void controlwall(flag_t permissionlevel, flag_t noticelevel, char *format, ...) {
+ char buf[512];
+ va_list va;
+ char *flags = printflags(noticelevel, no_noticeflags) + 1;
+ int i;
+ authname *anp;
+ no_autheduser *au;
+ nick *np;
+
+ va_start(va, format);
+ vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+
+ Error("noperserv", ERR_INFO, "$%s$ %s", flags, buf);
+
+ for (i=0;i<AUTHNAMEHASHSIZE;i++) {
+ for (anp=authnametable[i];anp;anp=anp->next) {
+ au = noperserv_get_autheduser(anp);
+ if(!au)
+ continue;
+ if((NOGetNoticeLevel(au) & noticelevel) && !(NOGetAuthLevel(au) & __NO_RELAY)) {
+ for(np=anp->nicks;np;np=np->nextbyauthname)
+ if(noperserv_policy_command_permitted(permissionlevel, np))
+ controlreply(np, "$%s$ %s", flags, buf);
+ }
+ }
+ }
+}
+
void controlspecialrmmod(void *arg) {
struct specialsched *a = (struct specialsched *)arg;
sstring *froo = a->modulename;
Command *cmd;
nick *np = (nick *)sender;
- if (cargc<1)
+ if(cargc < 1)
return CMD_USAGE;
- cmd=findcommandintree(controlcmds,cargv[0],1);
- if (cmd==NULL) {
- controlreply(np,"Unknown command.");
+ cmd = findcommandintree(controlcmds, cargv[0], 1);
+ if(!cmd || !noperserv_policy_command_permitted(cmd->level, np)) {
+ controlreply(np, "Unknown command or access denied.");
return CMD_ERROR;
}
controlwall(NO_OPER, noticelevel, "%s", broadcast);
}
-int controlcheckpermitted(flag_t level, nick *user) {
- return 1;
+int controlpermitted(flag_t level, nick *user) {
+ return noperserv_policy_command_permitted(level, user);
}
void handlesignal(int hooknum, void *arg) {
return buf;
}
+void noperserv_oper_detection(int hooknum, void *arg) {
+ nick *np = (nick *)arg;
+
+ if(np->umodes & UMODE_OPER) {
+ if(np->opername && strcmp(np->opername->content, "-")) {
+ controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just OPERed as %s", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"", np->opername->content);
+ } else {
+ controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just OPERed", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"");
+ }
+ } else {
+ controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just DEOPERed", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"");
+ }
+}
+
#ifndef __CONTROL_H
#define __CONTROL_H
+#include "control_db.h"
+#include "../lib/flags.h"
#include "../parser/parser.h"
#include "../nick/nick.h"
#include "../channel/channel.h"
#define registercontrolcmd(a, b, c, d) registercontrolhelpcmd(a, b, c, d, NULL)
-typedef void (*ControlMsg)(nick *, char *, ... );
-typedef void (*ControlWall)(flag_t, flag_t, char *, ...);
-typedef int (*ControlPermitted)(flag_t, nick *);
-
-extern ControlMsg controlreply;
-extern ControlWall controlwall;
-extern ControlPermitted controlpermitted;
+void controlreply(nick *, char *, ...);
+void controlwall(flag_t, flag_t, char *, ...);
+int controlpermitted(flag_t, nick *);
extern nick *mynick;
#define NL_NOTICES 0x1000 /* turn off to receive privmsgs instead of notices */
#define NL_ALL_COMMANDS 0x2000 /* every single command sent */
+extern int noperserv_ext;
+
+extern const flag no_userflags[];
+extern const flag no_noticeflags[];
+extern const flag no_commandflags[];
+
+#define NO_NICKS_PER_WHOIS_LINE 3
+
+#define NOGetAuthedUser(user) (no_autheduser *)(user->auth ? user->auth->exts[noperserv_ext] : NULL)
+#define NOGetAuthLevel(user) user->authlevel
+#define NOGetNoticeLevel(user) user->noticelevel
+#define NOMax(a, b) (a>b?a:b)
+#define NOMin(a, b) (a<b?b:a)
+
#endif
#include "../core/schedule.h"
#include "../dbapi2/dbapi2.h"
-#include "noperserv.h"
-#include "noperserv_db.h"
+#include "control.h"
#include <stdlib.h>
#ifndef __NOPERSERV_STRUCTS_H
#define __NOPERSERV_STRUCTS_H
+#include "../authext/authext.h"
+
typedef unsigned long no_tableid;
typedef struct no_autheduser {
#include "../lib/strlfunc.h"
#include "../lib/version.h"
#include "../authext/authext.h"
-#include "noperserv.h"
-#include "noperserv_db.h"
-#include "noperserv_hooks.h"
-#include "noperserv_policy.h"
+#include "../control/control.h"
+#include "../control/control_db.h"
+#include "../control/control_policy.h"
#include <stdio.h>
#include <string.h>
#define NO_FOUND_NICKNAME 1
#define NO_FOUND_AUTHNAME 2
-const flag no_commandflags[] = {
- { 'o', __NO_OPER },
- { 't', __NO_TRUST },
- { 's', __NO_STAFF },
- { 'S', __NO_SEC },
- { 'd', __NO_DEVELOPER },
- { 'L', __NO_LEGACY },
- { 'O', __NO_OPERED },
- { 'r', __NO_AUTHED },
- { 'R', __NO_ACCOUNT },
- { 'Y', __NO_RELAY },
- { '\0', 0 }
- };
-
-const flag no_userflags[] = {
- { 'o', __NO_OPER },
- { 't', __NO_TRUST },
- { 's', __NO_STAFF },
- { 'S', __NO_SEC },
- { 'd', __NO_DEVELOPER },
- { 'Y', __NO_RELAY },
- { '\0', 0 }
- };
-
-const flag no_noticeflags[] = {
- { 'm', NL_MANAGEMENT }, /* hello, password, userflags, noticeflags */
- { 't', NL_TRUSTS }, /* trust stuff... */
- { 'k', NL_KICKKILLS }, /* KICK/KILL commands */
- { 'I', NL_MISC }, /* misc commands */
- { 'g', NL_GLINES }, /* GLINE commands */
- { 'h', NL_HITS }, /* Where a gline or kill is set automatically by the bot */
- { 'c', NL_CLONING }, /* Clone detection */
- { 'C', NL_CLEARCHAN }, /* When someone clearchans */
- { 'f', NL_FAKEUSERS }, /* Fakeuser addition */
- { 'b', NL_BROADCASTS }, /* Broadcast/mbroadcast/sbroadcast */
- { 'o', NL_OPERATIONS }, /* insmod/rmmod/etc */
- { 'O', NL_OPERING }, /* when someone opers */
- { 'n', NL_NOTICES }, /* turn off to receive notices instead of privmsgs */
- { 'A', NL_ALL_COMMANDS }, /* all commands sent */
- { '\0', 0 }
- };
-
-int noperserv_hello(void *sender, int cargc, char **cargv);
-int noperserv_noticeflags(void *sender, int cargc, char **cargv);
-int noperserv_userflags(void *sender, int cargc, char **cargv);
-int noperserv_deluser(void *sender, int cargc, char **cargv);
-void noperserv_oper_detection(int hooknum, void *arg);
-void noperserv_reply(nick *np, char *format, ...) __attribute__ ((format (printf, 2, 3)));
-
-int init = 0;
-
-void _init() {
- if(!noperserv_load_db())
- return;
-
- noperserv_ext = registerauthnameext("noperserv", 1);
-
- noperserv_setup_hooks();
-
- registercontrolhelpcmd("hello", NO_OPERED | NO_AUTHED, 1, &noperserv_hello, "Syntax: HELLO ?nickname|#authname?\nCreates an account on the service for the specified nick, or if one isn't supplied, your nickname.");
- registercontrolhelpcmd("userflags", NO_ACCOUNT, 2, &noperserv_userflags,
- "Syntax: USERFLAGS <nickname|#authname> ?modifications?\n"
- " Views and modifies user permissions.\n"
- " If no nickname or authname is supplied, you are substituted for it.\n"
- " If no flags are supplied, flags are just displayed instead of modified."
- " Flags:\n"
- " +o: Operator\n"
- " +s: Staff member\n"
- " +S: Security team member\n"
- " +d: NOperserv developer\n"
- " +t: Trust queue worker\n"
- " +Y: Relay\n"
- " Additional flags may show up in SHOWCOMMANDS but are not userflags as such:\n"
- " +r: Authed user\n"
- " +R: Registered NOperserv user\n"
- " +O: Must be /OPER'ed\n"
- " +L: Legacy command\n"
- );
- registercontrolhelpcmd("noticeflags", NO_ACCOUNT, 1, &noperserv_noticeflags,
- "Syntax: NOTICEFLAGS ?(nickname|#authname)|flags?\n"
- " This command can view and modify your own notice flags, and view that of other users.\n"
- " Flags:\n"
- " +m: Management (hello, password, userflags, noticeflags)\n"
- " +t: Trusts\n"
- " +k: KICK/KILL commands\n"
- " +g: GLINE commands\n"
- " +h: Shows when glines are set by code (hits)\n"
- " +c: Clone information\n"
- " +C: CLEARCHAN command\n"
- " +f: FAKEUSER commands\n"
- " +b: BROADCAST commands\n"
- " +o: Operation commands, such as insmod, rmmod, die, etc\n"
- " +O: /OPER\n"
- " +I: Misc commands (resync, etc)\n"
- " +n: Sends notices instead of privmsgs\n"
- " +A: Every single command sent to the service (spammy)\n"
- );
-
- registercontrolhelpcmd("deluser", NO_OPERED | NO_ACCOUNT, 2, &noperserv_deluser, "Syntax: DELUSER <nickname|#authname>\nDeletes the specified user.");
- registerhook(HOOK_NICK_MODEOPER, &noperserv_oper_detection);
-
- init = 1;
-}
-
-#ifdef BROKEN_DLCLOSE
-void __fini() {
-#else
-void _fini() {
-#endif
- if(!init)
- return;
-
- deregisterhook(HOOK_NICK_MODEOPER, &noperserv_oper_detection);
-
- deregistercontrolcmd("noticeflags", &noperserv_noticeflags);
- deregistercontrolcmd("userflags", &noperserv_userflags);
- deregistercontrolcmd("noticeflags", &noperserv_noticeflags);
- deregistercontrolcmd("hello", &noperserv_hello);
- deregistercontrolcmd("deluser", &noperserv_deluser);
-
- noperserv_cleanup_hooks();
-
- noperserv_cleanup_db();
-
- releaseauthnameext(noperserv_ext);
-}
-
/* @test */
-int noperserv_hello(void *sender, int cargc, char **cargv) {
+static int noperserv_hello(void *sender, int cargc, char **cargv) {
authname *newaccount = NULL;
no_autheduser *au;
nick *np = (nick *)sender, *np2, *target = NULL;
return CMD_OK;
}
-no_autheduser *noperserv_autheduser_from_command(nick *np, char *command, int *typefound, char **returned) {
+static no_autheduser *noperserv_autheduser_from_command(nick *np, char *command, int *typefound, char **returned) {
no_autheduser *au;
authname *anp;
if(command[0] == '#') {
return NULL;
}
-int noperserv_noticeflags(void *sender, int cargc, char **cargv) {
+static int noperserv_noticeflags(void *sender, int cargc, char **cargv) {
nick *np2, *np = (nick *)sender;
no_autheduser *au;
}
/* @test */
-int noperserv_deluser(void *sender, int cargc, char **cargv) {
+static int noperserv_deluser(void *sender, int cargc, char **cargv) {
nick *np2, *np = (nick *)sender;
no_autheduser *target /* target user */, *au = NOGetAuthedUser(np); /* user executing command */
char *userreturned = NULL; /* nickname or authname of the target, pulled from the db */
/* @test */
/* this command needs LOTS of checking */
-int noperserv_userflags(void *sender, int cargc, char **cargv) {
+static int noperserv_userflags(void *sender, int cargc, char **cargv) {
nick *np2, *np = (nick *)sender;
no_autheduser *au = NOGetAuthedUser(np), *target = NULL;
char *flags = NULL, *nicktarget = NULL;
return CMD_OK;
}
-void noperserv_oper_detection(int hooknum, void *arg) {
- nick *np = (nick *)arg;
+void _init() {
+ registercontrolhelpcmd("hello", NO_OPERED | NO_AUTHED, 1, &noperserv_hello, "Syntax: HELLO ?nickname|#authname?\nCreates an account on the service for the specified nick, or if one isn't supplied, your nickname.");
+ registercontrolhelpcmd("userflags", NO_ACCOUNT, 2, &noperserv_userflags,
+ "Syntax: USERFLAGS <nickname|#authname> ?modifications?\n"
+ " Views and modifies user permissions.\n"
+ " If no nickname or authname is supplied, you are substituted for it.\n"
+ " If no flags are supplied, flags are just displayed instead of modified."
+ " Flags:\n"
+ " +o: Operator\n"
+ " +s: Staff member\n"
+ " +S: Security team member\n"
+ " +d: NOperserv developer\n"
+ " +t: Trust queue worker\n"
+ " +Y: Relay\n"
+ " Additional flags may show up in SHOWCOMMANDS but are not userflags as such:\n"
+ " +r: Authed user\n"
+ " +R: Registered NOperserv user\n"
+ " +O: Must be /OPER'ed\n"
+ " +L: Legacy command\n"
+ );
+ registercontrolhelpcmd("noticeflags", NO_ACCOUNT, 1, &noperserv_noticeflags,
+ "Syntax: NOTICEFLAGS ?(nickname|#authname)|flags?\n"
+ " This command can view and modify your own notice flags, and view that of other users.\n"
+ " Flags:\n"
+ " +m: Management (hello, password, userflags, noticeflags)\n"
+ " +t: Trusts\n"
+ " +k: KICK/KILL commands\n"
+ " +g: GLINE commands\n"
+ " +h: Shows when glines are set by code (hits)\n"
+ " +c: Clone information\n"
+ " +C: CLEARCHAN command\n"
+ " +f: FAKEUSER commands\n"
+ " +b: BROADCAST commands\n"
+ " +o: Operation commands, such as insmod, rmmod, die, etc\n"
+ " +O: /OPER\n"
+ " +I: Misc commands (resync, etc)\n"
+ " +n: Sends notices instead of privmsgs\n"
+ " +A: Every single command sent to the service (spammy)\n"
+ );
- if(np->umodes & UMODE_OPER) {
- if(np->opername && strcmp(np->opername->content, "-")) {
- controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just OPERed as %s", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"", np->opername->content);
- } else {
- controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just OPERed", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"");
- }
- } else {
- controlwall(NO_OPER, NL_OPERING, "%s!%s@%s%s%s just DEOPERed", np->nick, np->ident, np->host->name->content, IsAccount(np)?"/":"", IsAccount(np)?np->authname:"");
- }
+ registercontrolhelpcmd("deluser", NO_OPERED | NO_ACCOUNT, 2, &noperserv_deluser, "Syntax: DELUSER <nickname|#authname>\nDeletes the specified user.");
+}
+
+void _fini() {
+ deregistercontrolcmd("noticeflags", &noperserv_noticeflags);
+ deregistercontrolcmd("userflags", &noperserv_userflags);
+ deregistercontrolcmd("noticeflags", &noperserv_noticeflags);
+ deregistercontrolcmd("hello", &noperserv_hello);
+ deregistercontrolcmd("deluser", &noperserv_deluser);
}
+
-#include "../control/control.h"
-#include "noperserv.h"
-#include "noperserv_db.h"
-#include "noperserv_policy.h"
+#include "control.h"
+#include "control_db.h"
+#include "control_policy.h"
/* command access */
int noperserv_policy_command_permitted(flag_t level, nick *user) {
+++ /dev/null
-include ../build.mk
-
-CFLAGS+=$(INCDBAPI)
-LDFLAGS+=$(LIBDBAPI)
-
-.PHONY: all
-all: noperserv.so noperserv_commands.so noperserv_raw.so
-
-noperserv.so: noperserv.o noperserv_db.o noperserv_hooks.o noperserv_policy.o
-
-noperserv_commands.so: noperserv_commands.o
-
-noperserv_raw.so: noperserv_raw.o
+++ /dev/null
-#ifndef __NOPERSERV_H
-#define __NOPERSERV_H
-
-#include "../control/control.h"
-#include "../noperserv/noperserv_db.h"
-#include "../lib/flags.h"
-
-int noperserv_ext;
-
-extern const flag no_userflags[];
-extern const flag no_noticeflags[];
-extern const flag no_commandflags[];
-
-#define NO_NICKS_PER_WHOIS_LINE 3
-
-#define NOGetAuthedUser(user) (no_autheduser *)(user->auth ? user->auth->exts[noperserv_ext] : NULL)
-#define NOGetAuthLevel(user) user->authlevel
-#define NOGetNoticeLevel(user) user->noticelevel
-#define NOMax(a, b) (a>b?a:b)
-#define NOMin(a, b) (a<b?b:a)
-
-#endif
+++ /dev/null
-#include "../control/control.h"
-#include "../localuser/localuser.h"
-#include "../core/schedule.h"
-#include "../core/modules.h"
-#include "../lib/splitline.h"
-#include "../lib/flags.h"
-#include "../lib/irc_string.h"
-#include "../lib/strlfunc.h"
-
-#include "noperserv.h"
-#include "noperserv_db.h"
-#include "noperserv_hooks.h"
-#include "noperserv_policy.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-struct storedhook {
- CommandHandler old;
- sstring *name;
- cmdhelp *oldhelp;
- cmdhelp *newhelp;
- struct storedhook *next;
-} storedhook;
-
-struct storedhook *storedhooks = NULL;
-
-int firsttime = 0;
-nick *replynick = NULL;
-
-UserMessageHandler oldhandler;
-ControlMsg oldreply;
-ControlWall oldwall;
-ControlPermitted oldpermitted;
-
-void noperserv_trap_registration(int hooknum, void *arg);
-int noperserv_showcommands(void *sender, int cargc, char **cargv);
-int noperserv_rmmod(void *sender, int cargc, char **cargv);
-int noperserv_reload(void *sender, int cargc, char **cargv);
-int noperserv_whois(void *sender, int cargc, char **cargv);
-int noperserv_help(void *sender, int cargc, char **cargv);
-void noperserv_whois_handler(int hooknum, void *arg);
-void noperserv_whois_account_handler(int hooknum, void *arg);
-void noperserv_handle_messages(nick *target, int messagetype, void **args);
-void noperserv_reply(nick *np, char *format, ...) __attribute__ ((format (printf, 2, 3)));
-void noperserv_wall(flag_t permissionlevel, flag_t noticelevel, char *format, ...);
-
-struct specialsched special;
-
-#define HOOK_CONTROL_WHOISREQUEST_AUTHNAME -1
-#define HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER -2
-
-void noperserv_setup_hooks(void) {
- oldreply = controlreply;
- controlreply = &noperserv_reply;
-
- oldwall = controlwall;
- controlwall = &noperserv_wall;
-
- oldpermitted = controlpermitted;
- controlpermitted = &noperserv_policy_command_permitted;
-
- memset(&special, 0, sizeof(struct specialsched));
-
- if(!mynick) {
- registerhook(HOOK_CONTROL_REGISTERED, &noperserv_trap_registration);
- } else {
- noperserv_trap_registration(0, (void *)mynick);
- }
-
- registerhook(HOOK_CONTROL_WHOISREQUEST, &noperserv_whois_handler);
-}
-
-int noperserv_hook_command(char *command, CommandHandler newcommand, char *newhelp) {
- struct storedhook *newhook;
- Command *fetchcommand = findcommandintree(controlcmds, command, 1);
-
- if(!fetchcommand)
- return 1;
-
- newhook = (struct storedhook *)malloc(sizeof(struct storedhook));
- if(!newhook)
- return 1;
-
- newhook->name = getsstring(command, strlen(command));
- if(!newhook->name) {
- free(newhook);
- return 1;
- }
-
- newhook->old = fetchcommand->handler;
- if(newhelp) {
- newhook->newhelp = (cmdhelp *)malloc(sizeof(cmdhelp));
- memset(newhook->newhelp,0,sizeof(cmdhelp));
- if(!newhook->newhelp) {
- freesstring(newhook->name);
- free(newhook);
- } else {
- int len = strlen(newhelp) + 1;
- newhook->newhelp->helpstr = (char *)malloc(len);
- if (newhook->newhelp->helpstr) {
- strlcpy(newhook->newhelp->helpstr, newhelp, len);
- }
- newhook->oldhelp = fetchcommand->ext;
- fetchcommand->ext = newhook->newhelp;
- }
- } else {
- newhook->newhelp = NULL;
- }
-
- newhook->next = storedhooks;
- storedhooks = newhook;
-
- fetchcommand->handler = newcommand;
-
- return 0;
-}
-
-void noperserv_unhook_all_commands(void) {
- struct storedhook *nh, *ch = storedhooks;
- Command *fetchcommand;
-
- while(ch) {
- if(ch->old && (fetchcommand = findcommandintree(controlcmds, ch->name->content, 1))) {
- fetchcommand->handler = ch->old;
- if(ch->newhelp) {
- fetchcommand->ext = ch->oldhelp;
- if ( ((cmdhelp *)ch->newhelp)->helpstr)
- free( ((cmdhelp *)ch->newhelp)->helpstr);
- free(ch->newhelp);
- }
- }
- nh = ch->next;
- freesstring(ch->name);
- free(ch);
- ch = nh;
- }
-}
-
-void noperserv_cleanup_hooks(void) {
- deregisterhook(HOOK_CONTROL_WHOISREQUEST, &noperserv_whois_handler);
- deregisterhook(HOOK_CONTROL_REGISTERED, &noperserv_trap_registration);
-
- if(firsttime) {
- noperserv_unhook_all_commands();
- firsttime = 0;
- }
-
- if(oldhandler && mynick)
- hooklocaluserhandler(mynick, oldhandler);
-
- controlwall = oldwall;
- controlreply = oldreply;
- controlpermitted = oldpermitted;
-}
-
-void noperserv_trap_registration(int hooknum, void *arg) {
- nick *np = (nick *)arg;
- if(!np)
- return;
-
- oldhandler = hooklocaluserhandler((nick *)arg, &noperserv_handle_messages);
- if(!oldhandler)
- return;
-
- if(!firsttime) {
- firsttime = 1;
- noperserv_hook_command("rmmod", &noperserv_rmmod, NULL);
- noperserv_hook_command("reload", &noperserv_reload, NULL);
- noperserv_hook_command("showcommands", &noperserv_showcommands, NULL);
- noperserv_hook_command("whois", &noperserv_whois, "Usage: whois <nickname|#authname|*numeric>\nDisplays lots of information about the specified nickname, auth name or numeric.");
- noperserv_hook_command("help", &noperserv_help, NULL);
- }
-}
-
-CommandHandler noperserv_find_hook(char *command) {
- struct storedhook *hh = storedhooks;
- for(;hh;hh=hh->next)
- if(!ircd_strcmp(hh->name->content, command))
- return hh->old;
-
- return NULL;
-}
-
-int noperserv_modules_loaded(char *mask) {
- int i;
- char *ptr;
-
- for(i=0,ptr=lsmod(i,NULL,NULL,NULL);ptr;ptr=lsmod(++i,NULL,NULL,NULL))
- if(match2strings(mask, ptr))
- return 1;
-
- return 0;
-}
-
-int noperserv_specialmod(nick *np, char *command, ScheduleCallback reloadhandler, int cargc, char **cargv) {
- CommandHandler oldcommand = noperserv_find_hook(command);
- if(cargc < 1) {
- if(oldcommand)
- return oldcommand(np, cargc, cargv);
- return CMD_ERROR;
- }
-
- if(!strcmp(cargv[0], "noperserv")) {
- if(special.schedule) {
- controlreply(np, "Previous attempt at un/reload still in progress.");
- return CMD_OK;
- } else {
- special.modulename = getsstring(cargv[0], strlen(cargv[0]));
- if(!special.modulename) {
- controlreply(np, "Unable to copy module name. Seek cow herd to trample on server.");
- return CMD_ERROR;
- } else {
- special.schedule = scheduleoneshot(time(NULL) + 1, reloadhandler, &special);
- if(!special.schedule) {
- freesstring(special.modulename);
- special.modulename = NULL;
- controlreply(np, "Unable to allocate schedule. Seek cow herd to trample on server.");
- return CMD_ERROR;
- }
- controlreply(np, "Special case un/reload in <1 second, no response will be sent, standby. . .");
- return CMD_OK;
- }
- }
- } else {
- if(oldcommand)
- return oldcommand(np, cargc, cargv);
- return CMD_ERROR;
- }
-}
-
-int noperserv_rmmod(void *sender, int cargc, char **cargv) {
- return noperserv_specialmod(sender, "rmmod", &controlspecialrmmod, cargc, cargv);
-}
-
-int noperserv_reload(void *sender, int cargc, char **cargv) {
- return noperserv_specialmod(sender, "reload", &controlspecialreloadmod, cargc, cargv);
-}
-
-void noperserv_whois_hook(int hooknum, void *arg) {
- controlreply(replynick, "%s", (char *)arg);
-}
-
-int noperserv_whois(void *sender, int cargc, char **cargv) {
- authname *an;
- no_autheduser *au;
- nick *np = (nick *)sender;
- CommandHandler oldwhois = noperserv_find_hook("whois");
-
- if(cargc < 1) {
- if(oldwhois)
- return oldwhois(sender, cargc, cargv);
- return CMD_ERROR;
- }
-
- if(cargv[0][0] != '#') {
- if(cargv[0][0] == '*')
- cargv[0][0] = '#';
- if(oldwhois)
- return oldwhois(sender, cargc, cargv);
- return CMD_ERROR;
- }
-
- an = findauthnamebyname(cargv[0] + 1);
- if(!an) {
- controlreply(np, "Account not registered.");
- return CMD_OK;
- }
-
- au = noperserv_get_autheduser(an);
- if(!au) {
- controlreply(np, "User does not have a NOperserv account.");
- return CMD_OK;
- }
-
- controlreply(np, "Account : %s", au->authname->name);
-
- replynick = np;
-
- registerhook(HOOK_CONTROL_WHOISREPLY, &noperserv_whois_hook);
- noperserv_whois_account_handler(HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER, (void *)au);
- deregisterhook(HOOK_CONTROL_WHOISREPLY, &noperserv_whois_hook);
-
- controlreply(np, "Flags : %s", printflags(NOGetAuthLevel(au), no_userflags));
-
- return CMD_OK;
-}
-
-int noperserv_showcommands(void *sender, int cargc, char **cargv) {
- nick *np = (nick *)sender;
- Command *cmdlist[100];
- int i, n;
-
- n = getcommandlist(controlcmds, cmdlist, 100);
-
- controlreply(np, "The following commands are registered at present:");
-
- for(i=0;i<n;i++)
- if(noperserv_policy_command_permitted(cmdlist[i]->level, np))
- controlreply(np, " %-25s %s", cmdlist[i]->command->content, printflags(cmdlist[i]->level, no_commandflags));
-
- controlreply(np, "End of list.");
- return CMD_OK;
-}
-
-void noperserv_whois_handler(int hooknum, void *arg) {
- char message[100];
- nick *np = (nick *)arg;
- no_autheduser *au;
- if(!np)
- return;
-
- if(IsAccount(np)) {
- au = NOGetAuthedUser(np);
- if(au) {
- snprintf(message, sizeof(message), "Flags : %s", printflags(NOGetAuthLevel(au), no_userflags));
- noperserv_whois_account_handler(HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER, (void *)au);
- } else {
- snprintf(message, sizeof(message), "Flags : (user not known)");
- noperserv_whois_account_handler(HOOK_CONTROL_WHOISREQUEST_AUTHNAME, (void *)np->authname);
- }
- triggerhook(HOOK_CONTROL_WHOISREPLY, message);
- }
-}
-
-/* mmm, hacky */
-void noperserv_whois_account_handler(int hooknum, void *arg) {
- int count = 0, found = 0;
- char nickbuffer[(NICKLEN + 2) * NO_NICKS_PER_WHOIS_LINE - 1]; /* since we don't need space or comma for the first item we're fine NULL wise */
- char accountspace[NICKLEN + 3]; /* space, comma, null */
- char message[1024];
- nick *np;
-
- nickbuffer[0] = '\0';
- if(hooknum == HOOK_CONTROL_WHOISREQUEST_AUTHEDUSER) {
- /* we can just read out the authed user linked list */
- no_autheduser *au = (void *)arg;
-
- if(au->authname->nicks)
- found = 1;
-
- for(np=au->authname->nicks;np;np=np->nextbyauthname) {
- snprintf(accountspace, sizeof(accountspace), "%s%s", count++?", ":"", np->nick);
- strlcat(nickbuffer, accountspace, sizeof(nickbuffer));
-
- if(count >= NO_NICKS_PER_WHOIS_LINE) {
- snprintf(message, sizeof(message), "Authed : %s", nickbuffer);
- triggerhook(HOOK_CONTROL_WHOISREPLY, message);
- nickbuffer[0] = '\0';
- count = 0;
- }
- }
- } else {
- /* inefficient way */
- char *authname = (char *)arg;
- int i = 0;
- nick *sp;
-
- for(;i<NICKHASHSIZE;i++)
- for(sp=nicktable[i];sp;sp=sp->next)
- if(IsAccount(sp) && !ircd_strcmp(sp->authname, authname)) {
- found = 1;
-
- snprintf(accountspace, sizeof(accountspace), "%s%s", count++?", ":"", sp->nick);
- strlcat(nickbuffer, accountspace, sizeof(nickbuffer));
-
- if(count >= NO_NICKS_PER_WHOIS_LINE) {
- snprintf(message, sizeof(message), "Authed : %s", nickbuffer);
- triggerhook(HOOK_CONTROL_WHOISREPLY, message);
- nickbuffer[0] = '\0';
- count = 0;
- }
- }
- }
-
- if(!found) {
- snprintf(message, sizeof(message), "Authed : (no nicks authed)");
- triggerhook(HOOK_CONTROL_WHOISREPLY, message);
- } else if(nickbuffer[0]) {
- snprintf(message, sizeof(message), "Authed : %s", nickbuffer);
- triggerhook(HOOK_CONTROL_WHOISREPLY, message);
- }
-}
-
-/* Obviously pinched from control.c */
-void noperserv_handle_messages(nick *target, int messagetype, void **args) {
- Command *cmd;
- char *cargv[50];
- int cargc;
- nick *sender;
-
- switch(messagetype) {
- case LU_PRIVMSG: /* override these two commands only */
- case LU_SECUREMSG:
- /* If it's a message, first arg is nick and second is message */
- sender = (nick *)args[0];
-
- controlwall(NO_DEVELOPER, NL_ALL_COMMANDS, "From: %s!%s@%s%s%s: %s", sender->nick, sender->ident, sender->host->name->content, IsAccount(sender)?"/":"", IsAccount(sender)?sender->authname:"", (char *)args[1]);
-
- /* Split the line into params */
- cargc = splitline((char *)args[1], cargv, 50, 0);
-
- if(!cargc) /* Blank line */
- return;
-
- cmd = findcommandintree(controlcmds,cargv[0],1);
- if(!cmd) {
- controlreply(sender, "Unknown command or access denied.");
- return;
- }
-
- /* If we were doing "authed user tracking" here we'd put a check in for authlevel */
- /* Here it is! */
- if (!noperserv_policy_command_permitted(cmd->level, sender)) {
- controlreply(sender, "Unknown command or access denied.");
- return;
- }
-
- /* Check the maxargs */
- if(cmd->maxparams < (cargc - 1)) {
- /* We need to do some rejoining */
- rejoinline(cargv[cmd->maxparams], cargc - (cmd->maxparams));
- cargc = (cmd->maxparams) + 1;
- }
-
- if((cmd->handler)((void *)sender,cargc-1,&(cargv[1])) == CMD_USAGE)
- controlhelp(sender, cmd);
-
- break;
- default:
- if(oldhandler)
- oldhandler(target, messagetype, args);
- break;
- }
-}
-
-void noperserv_reply(nick *np, char *format, ...) {
- char buf[512];
- va_list va;
- no_autheduser *au = NOGetAuthedUser(np);
-
- va_start(va, format);
- vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-
- if(au && !(NOGetNoticeLevel(au) & NL_NOTICES)) {
- controlmessage(np, "%s", buf);
- } else {
- controlnotice(np, "%s", buf);
- }
-}
-
-int noperserv_help(void *sender, int cargc, char **cargv) {
- Command *cmd;
- nick *np = (nick *)sender;
-
- if(cargc < 1)
- return CMD_USAGE;
-
- cmd = findcommandintree(controlcmds, cargv[0], 1);
- if(!cmd || !noperserv_policy_command_permitted(cmd->level, np)) {
- controlreply(np, "Unknown command or access denied.");
- return CMD_ERROR;
- }
-
- controlhelp(np, cmd);
- return CMD_OK;
-}
-
-void noperserv_wall(flag_t permissionlevel, flag_t noticelevel, char *format, ...) {
- char buf[512];
- va_list va;
- char *flags = printflags(noticelevel, no_noticeflags) + 1;
- int i;
- authname *anp;
- no_autheduser *au;
- nick *np;
-
- va_start(va, format);
- vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-
- Error("noperserv", ERR_INFO, "$%s$ %s", flags, buf);
-
- for (i=0;i<AUTHNAMEHASHSIZE;i++) {
- for (anp=authnametable[i];anp;anp=anp->next) {
- au = noperserv_get_autheduser(anp);
- if(!au)
- continue;
- if((NOGetNoticeLevel(au) & noticelevel) && !(NOGetAuthLevel(au) & __NO_RELAY)) {
- for(np=anp->nicks;np;np=np->nextbyauthname)
- if(noperserv_policy_command_permitted(permissionlevel, np))
- controlreply(np, "$%s$ %s", flags, buf);
- }
- }
- }
-}
+++ /dev/null
-void noperserv_setup_hooks(void);\r
-void noperserv_cleanup_hooks(void);\r
--- /dev/null
+include ../build.mk
+
+.PHONY: all
+all: raw.so
+
+raw.so: raw.o