From 40b41a3c91b3f1c67ddd63fc5dc6338ce88b17b4 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 25 Aug 2011 12:23:00 +0200 Subject: [PATCH] modified modcmd to give the possibility for dynamic access (modcmd) --- DATABASE.txt | 4 + bot_NeonServ.c | 57 ++++++----- cmd_neonserv_adduser.c | 4 - cmd_neonserv_clvl.c | 4 - cmd_neonserv_deluser.c | 4 - cmd_neonserv_suspend.c | 4 - cmd_neonserv_unsuspend.c | 4 - modcmd.c | 215 ++++++++++++++++++++++++++++++--------- modcmd.h | 15 ++- 9 files changed, 213 insertions(+), 98 deletions(-) diff --git a/DATABASE.txt b/DATABASE.txt index 783469e..e07d1cc 100644 --- a/DATABASE.txt +++ b/DATABASE.txt @@ -26,3 +26,7 @@ INDEX ( `owner_history_cid` ) ALTER TABLE `chanusers` ADD INDEX ( `chanuser_cid` ) ; ALTER TABLE `chanusers` ADD INDEX ( `chanuser_uid` ) ; +ALTER TABLE `bot_binds` ADD `chan_access` VARCHAR( 256 ) NOT NULL AFTER `parameters` + +ALTER TABLE `bot_binds` CHANGE `chan_access` `chan_access` VARCHAR( 256 ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL , +CHANGE `global_access` `global_access` INT( 3 ) NULL diff --git a/bot_NeonServ.c b/bot_NeonServ.c index 7d966aa..e843bf5 100644 --- a/bot_NeonServ.c +++ b/bot_NeonServ.c @@ -226,15 +226,18 @@ static void start_bots() { client->botid = BOTID; client->clientid = atoi(row[7]); connect_socket(client); - printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access` FROM `bot_binds` WHERE `botid` = '%d'", client->clientid); + printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `channel_access` FROM `bot_binds` WHERE `botid` = '%d'", client->clientid); res2 = mysql_use(); while ((row = mysql_fetch_row(res2)) != NULL) { if(bind_cmd_to_command(BOTID, row[0], row[1])) { if(row[2] && strcmp(row[2], "")) { bind_set_parameters(BOTID, row[0], row[2]); } - if(atoi(row[3]) > 0) { - bind_set_gaccess(BOTID, row[0], atoi(row[3])); + if(row[3]) { + bind_set_global_access(BOTID, row[0], atoi(row[3])); + } + if(row[4]) { + bind_set_global_access(BOTID, row[0], row[4]); } } } @@ -246,30 +249,30 @@ void init_NeonServ() { register_command(BOTID, "modes", neonserv_cmd_modes, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "adduser", neonserv_cmd_adduser, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "deluser", neonserv_cmd_deluser, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "clvl", neonserv_cmd_clvl, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "a", neonserv_cmd_a, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN); - register_command(BOTID, "users", neonserv_cmd_users, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN); - register_command(BOTID, "suspend", neonserv_cmd_suspend, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "unsuspend", neonserv_cmd_unsuspend, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "delme", neonserv_cmd_delme, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "myaccess", neonserv_cmd_myaccess, 0, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "up", neonserv_cmd_up, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN); - register_command(BOTID, "down", neonserv_cmd_down, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN); - register_command(BOTID, "upall", neonserv_cmd_upall, 0, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "downall", neonserv_cmd_downall, 0, 0); - register_command(BOTID, "mdeluser", neonserv_cmd_mdeluser, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "trim", neonserv_cmd_trim, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "giveowner", neonserv_cmd_giveowner, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "op", neonserv_cmd_op, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "deop", neonserv_cmd_deop, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "voice", neonserv_cmd_voice, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "devoice", neonserv_cmd_devoice, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "opall", neonserv_cmd_opall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "deopall", neonserv_cmd_deopall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "voiceall", neonserv_cmd_voiceall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); - register_command(BOTID, "devoiceall", neonserv_cmd_devoiceall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); + register_command(BOTID, "adduser", neonserv_cmd_adduser, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canadd", 0); + register_command(BOTID, "deluser", neonserv_cmd_deluser, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_candel", 0); + register_command(BOTID, "clvl", neonserv_cmd_clvl, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canclvl", 0); + register_command(BOTID, "a", neonserv_cmd_a, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN, NULL, 0); + register_command(BOTID, "users", neonserv_cmd_users, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN, NULL, 0); + register_command(BOTID, "suspend", neonserv_cmd_suspend, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_cansuspend", 0); + register_command(BOTID, "unsuspend", neonserv_cmd_unsuspend, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_cansuspend", 0); + register_command(BOTID, "delme", neonserv_cmd_delme, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "1", 0); + register_command(BOTID, "myaccess", neonserv_cmd_myaccess, 0, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, NULL, 0); + register_command(BOTID, "up", neonserv_cmd_up, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_CHECK_AUTH, "#channel_getop", 0); + register_command(BOTID, "down", neonserv_cmd_down, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN, NULL, 0); + register_command(BOTID, "upall", neonserv_cmd_upall, 0, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, NULL, 0); + register_command(BOTID, "downall", neonserv_cmd_downall, 0, 0, NULL, 0); + register_command(BOTID, "mdeluser", neonserv_cmd_mdeluser, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_candel", 0); + register_command(BOTID, "trim", neonserv_cmd_trim, 2, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, NULL, 0); + register_command(BOTID, "giveowner", neonserv_cmd_giveowner, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "500", 0); + register_command(BOTID, "op", neonserv_cmd_op, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canop", 0); + register_command(BOTID, "deop", neonserv_cmd_deop, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canop", 0); + register_command(BOTID, "voice", neonserv_cmd_voice, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canvoice", 0); + register_command(BOTID, "devoice", neonserv_cmd_devoice, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canvoice", 0); + register_command(BOTID, "opall", neonserv_cmd_opall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canop", 0); + register_command(BOTID, "deopall", neonserv_cmd_deopall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canop", 0); + register_command(BOTID, "voiceall", neonserv_cmd_voiceall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canvoice", 0); + register_command(BOTID, "devoiceall", neonserv_cmd_devoiceall, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canvoice", 0); start_bots(); bind_bot_ready(neonserv_bot_ready); diff --git a/cmd_neonserv_adduser.c b/cmd_neonserv_adduser.c index a0b5e7e..80a9043 100644 --- a/cmd_neonserv_adduser.c +++ b/cmd_neonserv_adduser.c @@ -20,10 +20,6 @@ static CMD_BIND(neonserv_cmd_adduser) { MYSQL_RES *res; MYSQL_ROW row; check_mysql(); - if(!checkChannelAccess(user, chan, "channel_canadd", 1, 0)) { - reply(getTextBot(), user, "NS_ACCESS_DENIED"); - return; - } caccess = atoi(argv[1]); if(caccess <= 0 || caccess > 500) { reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess); diff --git a/cmd_neonserv_clvl.c b/cmd_neonserv_clvl.c index d0ce7a4..1aa00aa 100644 --- a/cmd_neonserv_clvl.c +++ b/cmd_neonserv_clvl.c @@ -17,10 +17,6 @@ struct neonserv_cmd_clvl_cache { static CMD_BIND(neonserv_cmd_clvl) { int caccess; check_mysql(); - if(!checkChannelAccess(user, chan, "channel_canclvl", 1, 0)) { - reply(getTextBot(), user, "NS_ACCESS_DENIED"); - return; - } caccess = atoi(argv[1]); if(caccess <= 0 || caccess > 500) { reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess); diff --git a/cmd_neonserv_deluser.c b/cmd_neonserv_deluser.c index 7eda8e4..806a253 100644 --- a/cmd_neonserv_deluser.c +++ b/cmd_neonserv_deluser.c @@ -14,10 +14,6 @@ struct neonserv_cmd_deluser_cache { static CMD_BIND(neonserv_cmd_deluser) { check_mysql(); - if(!checkChannelAccess(user, chan, "channel_candel", 1, 0)) { - reply(getTextBot(), user, "NS_ACCESS_DENIED"); - return; - } if(argv[0][0] == '*') { //we've got an auth argv[0]++; diff --git a/cmd_neonserv_suspend.c b/cmd_neonserv_suspend.c index 8c991ad..bb6db50 100644 --- a/cmd_neonserv_suspend.c +++ b/cmd_neonserv_suspend.c @@ -14,10 +14,6 @@ struct neonserv_cmd_suspend_cache { static CMD_BIND(neonserv_cmd_suspend) { check_mysql(); - if(!checkChannelAccess(user, chan, "channel_cansuspend", 1, 0)) { - reply(getTextBot(), user, "NS_ACCESS_DENIED"); - return; - } if(argv[0][0] == '*') { //we've got an auth argv[0]++; diff --git a/cmd_neonserv_unsuspend.c b/cmd_neonserv_unsuspend.c index 3c5a0c1..dabe1aa 100644 --- a/cmd_neonserv_unsuspend.c +++ b/cmd_neonserv_unsuspend.c @@ -14,10 +14,6 @@ struct neonserv_cmd_unsuspend_cache { static CMD_BIND(neonserv_cmd_unsuspend) { check_mysql(); - if(!checkChannelAccess(user, chan, "channel_cansuspend", 1, 0)) { - reply(getTextBot(), user, "NS_ACCESS_DENIED"); - return; - } if(argv[0][0] == '*') { //we've got an auth argv[0]++; diff --git a/modcmd.c b/modcmd.c index 37b0fee..33e6284 100644 --- a/modcmd.c +++ b/modcmd.c @@ -21,7 +21,7 @@ struct trigger_callback { struct command_check_user_cache { struct ClientSocket *client, *textclient; struct UserNode *user; - struct ChanNode *chan; + struct ChanNode *chan, *sent_chan; char **argv; int argc; char *message; @@ -37,9 +37,9 @@ static const struct default_language_entry msgtab[] = { {"MODCMD_LESS_PARAM_COUNT", "This command requires more parameters."}, {"MODCMD_CHAN_REQUIRED", "You must provide the name of a channel that exists."}, {"MODCMD_AUTH_REQUIRED", "You need to be authenticated with AuthServ to use this command."}, - {"MODCMD_PRIVILEGED", "§b%s§b is a privileged command."}, - - + {"MODCMD_PRIVILEGED", "\002%s\002 is a privileged command."}, + {"MODCMD_PUBCMD", "Public commands in \002%s\002 are restricted."}, + {"MODCMD_ACCESS_DENIED", "Access denied."}, {NULL, NULL} }; @@ -87,26 +87,18 @@ static char* get_channel_trigger(int botid, struct ChanNode *chan) { return trigger->trigger; } +static void handle_command_async(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct ChanNode *sent_chan struct cmd_binding *cbind, char **argv, int argc); + static USERAUTH_CALLBACK(command_checked_auth) { struct command_check_user_cache *cache = data; - int execute_cmd = 1; tmp_text_client = cache->textclient; - if((cache->cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { - reply(tmp_text_client, user, "MODCMD_AUTH_REQUIRED"); - execute_cmd = 0; - } - else if((cache->cbind->func->flags & CMDFLAG_REQUIRE_GOD) && !isGodMode(user)) { - reply(tmp_text_client, user, "MODCMD_PRIVILEGED", cache->cbind->cmd); - execute_cmd = 0; - } - if(execute_cmd) { - cache->cbind->func->func(cache->client, user, cache->chan, cache->argv, cache->argc); - } + handle_command_async(cache->client, user, cache->chan, cache->sent_chan, cache->cbind, cache->argv, cache->argc) free(cache->message); free(cache); } static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) { + struct ChanNode *sent_chan = chan; if(message[0] == '#') { char *chanName = message; message = strstr(message, " "); @@ -200,22 +192,6 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED"); break; } - if((cbind->func->flags & CMDFLAG_REGISTERED_CHAN)) { - loadChannelSettings(chan); - if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) { - reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED"); - break; - } - check_mysql(); - MYSQL_RES *res; - MYSQL_ROW row; - printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, client->botid); - res = mysql_use(); - if ((row = mysql_fetch_row(res)) == NULL) { - reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED"); - break; - } - } if((cbind->func->flags & CMDFLAG_CHECK_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { //check auth... struct command_check_user_cache *data = malloc(sizeof(*data)); @@ -230,25 +206,136 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s data->client = client; data->user = user; data->chan = chan; + data->sent_chan = sent_chan; data->message = message; data->cbind = cbind; data->textclient = tmp_text_client; get_userauth(user, command_checked_auth, data); return; + } else + handle_command_async(client, user, chan, sent_chan, cbind, argv, argc); + break; + } + } + free(message); +} + +static void handle_command_async(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct ChanNode *sent_chan, struct cmd_binding *cbind, char **argv, int argc) { + MYSQL_RES *res; + MYSQL_ROW row; + int uaccess; + if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { + reply(tmp_text_client, user, "MODCMD_AUTH_REQUIRED"); + return; + } + if(sent_chan && sent_chan != chan) { + //check pubcmd of this channel + printf_mysql_query("SELECT `channel_pubcmd` FROM `channels` WHERE `channel_name` = '%s'", escape_string(sent_chan->name)); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) != NULL) { + uaccess = getChannelAccess(user, sent_chan, 1); + if(row[0] && uaccess < atoi(row[0])) { //NOTE: HARDCODED DEFAULT: pubcmd = 0 + reply(tmp_text_client, user, "MODCMD_PUBCMD", sent_chan->name); + return; } - if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { - reply(tmp_text_client, user, "MODCMD_AUTH_REQUIRED"); - break; - } - if((cbind->func->flags & CMDFLAG_REQUIRE_GOD) && !isGodMode(user)) { + } + } + int global_access = ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access); + if(global_access > 0) { + int user_global_access = 0; + printf_mysql_query("SELECT `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth)); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) != NULL) { + user_global_access = atoi(row[0]); + } + if(user_global_access < global_access) { + if(!user_global_access) reply(tmp_text_client, user, "MODCMD_PRIVILEGED", cbind->cmd); - break; + else + reply(tmp_text_client, user, "MODCMD_ACCESS_DENIED"); + return; + } + } + if((cbind->func->flags & CMDFLAG_REGISTERED_CHAN)) { + check_mysql(); + MYSQL_ROW defaults = NULL; + char access_list[256]; + int access_pos = 0; + int access_count = 0; + int minaccess = 0; + char *str_a, *str_b = cbind->func->channel_access; + if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS) + str_b = cbind->channel_access; + if(str_b) { + while((str_a = strstr(str_b, ","))) { + *str_a = '\0'; + if(*str_b[0] == '#') { + access_pos += sprintf(access_list+access_pos, ", `%s`", str_b); + access_count++; + } else { + if(atoi(str_b) > minaccess) + minaccess = atoi(str_b); + } + *str_a = ','; + str_b = str_a+1; } - cbind->func->func(client, user, chan, argv, argc); - break; + access_pos += sprintf(access_list+access_pos, ", `%s`", str_b); + access_count++; + } else + access_list[0] = '\0'; + if(!(chan->flags & CHANFLAG_REQUESTED_CHANINFO) || (sent_chan && sent_chan == chan) || access_count || minaccess) { + printf_mysql_query("SELECT `channel_id`, `channel_pubcmd` %s FROM `channels` WHERE `channel_name` = '%s'", access_list, escape_string(chan->name)); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) != NULL) { + chan->flags |= CHANFLAG_CHAN_REGISTERED; + chan->channel_id = atoi(row[0]); + if((sent_chan && sent_chan == chan) || access_count || minaccess) { + uaccess = getChannelAccess(user, chan, 1); + if(uaccess < minaccess) { + //ACCESS DENIED + reply(tmp_text_client, user, "MODCMD_ACCESS_DENIED"); + return; + } + if(!row[1] && !defaults) { + printf_mysql_query("SELECT `channel_id`, `channel_pubcmd` %s FROM `channels` WHERE `channel_name` = 'defaults'", access_list); + defaults = mysql_fetch_row(mysql_use()); + } + if(sent_chan && (sent_chan == chan) && uaccess < (row[1] ? atoi(row[1]) : atoi(defaults[1]))) { + //PUBCMD + reply(tmp_text_client, user, "MODCMD_PUBCMD", chan->name); + return; + } + int i; + for(i = 0; i < access_count; i++) { + if(!row[2+i] && !defaults) { + printf_mysql_query("SELECT `channel_id`, `channel_pubcmd` %s FROM `channels` WHERE `channel_name` = 'defaults'", access_list); + defaults = mysql_fetch_row(mysql_use()); + } + if(uaccess < (row[2+i] ? atoi(row[2+i]) : atoi(defaults[2+i]))) { + reply(tmp_text_client, user, "MODCMD_ACCESS_DENIED"); + return; + } + } + } + } + chan->flags |= CHANFLAG_REQUESTED_CHANINFO; + } + if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) { + reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED"); + return; + } + printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, client->botid); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) == NULL) { + reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED"); + return; } } - free(message); + if((cbind->func->flags & CMDFLAG_REQUIRE_GOD) && !isGodMode(user)) { + reply(tmp_text_client, user, "MODCMD_PRIVILEGED", cbind->cmd); + return; + } + cbind->func->func(client, user, chan, argv, argc); } static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) { @@ -285,7 +372,7 @@ static void got_privmsg(struct UserNode *user, struct UserNode *target, char *me } } -int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags) { +int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags, char *channel_access, int global_access) { struct cmd_function *cmdfunc; for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) { if(cmdfunc->botid == botid && strcmp(cmdfunc->name, name) == 0) @@ -301,6 +388,8 @@ int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, un cmdfunc->func = func; cmdfunc->flags = flags; cmdfunc->paramcount = paramcount; + cmdfunc->channel_access = channel_access; + cmdfunc->global_access = global_access; cmdfunc->next = cmd_functions; cmd_functions = cmdfunc; return 1; @@ -354,7 +443,8 @@ int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) { cbind->cmd = strdup(cmd); cbind->func = func; cbind->parameters = NULL; - cbind->gaccess = 0; + cbind->global_access = 0; + cbind->channel_access = NULL; cbind->flags = 0; cbind->next = cmd_binds[bind_index]; cmd_binds[bind_index] = cbind; @@ -384,7 +474,8 @@ int bind_cmd_to_command(int botid, char *cmd, char *func) { cbind->func = cmdfunc; cbind->next = cmd_binds[bind_index]; cbind->parameters = NULL; - cbind->gaccess = 0; + cbind->global_access = 0; + cbind->channel_access = NULL; cbind->flags = 0; cmd_binds[bind_index] = cbind; return 1; @@ -430,6 +521,8 @@ void free_modcmd() { free(cbind->cmd); if(cbind->parameters) free(cbind->parameters); + if(cbind->channel_access) + free(cbind->channel_access); free(cbind); } } @@ -462,7 +555,37 @@ void bind_set_parameters(int botid, char *cmd, char *parameters) { } } -void bind_set_gaccess(int botid, char *cmd, int gaccess) { - +void bind_set_global_access(int botid, char *cmd, int gaccess) { + int bind_index = get_binds_index(cmd[0]); + struct cmd_binding *cbind; + for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { + if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(gaccess > -1) { + cbind->global_access = gaccess; + cbind->flags |= CMDFLAG_OVERRIDE_GLOBAL_ACCESS; + } else { + cbind->flags &= ~CMDFLAG_OVERRIDE_GLOBAL_ACCESS; + } + return; + } + } } +void bind_set_channel_access(int botid, char *cmd, char *chanaccess) { + int bind_index = get_binds_index(cmd[0]); + struct cmd_binding *cbind; + for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { + if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(cbind->channel_access) + free(cbind->channel_access); + if(chanaccess) { + cbind->channel_access = strdup(chanaccess); + cbind->flags |= CMDFLAG_OVERRIDE_CHANNEL_ACCESS; + } else { + cbind->channel_access = NULL; + cbind->flags &= ~CMDFLAG_OVERRIDE_CHANNEL_ACCESS; + } + return; + } + } +} diff --git a/modcmd.h b/modcmd.h index 932fc10..2afdfe4 100644 --- a/modcmd.h +++ b/modcmd.h @@ -6,8 +6,9 @@ #define CMDFLAG_REQUIRE_AUTH 0x02 #define CMDFLAG_REQUIRE_GOD 0x04 #define CMDFLAG_CHECK_AUTH 0x08 -#define CMDFLAG_OVERRIDE_ACCESS 0x10 -#define CMDFLAG_REGISTERED_CHAN 0x20 +#define CMDFLAG_REGISTERED_CHAN 0x10 +#define CMDFLAG_OVERRIDE_GLOBAL_ACCESS 0x20 +#define CMDFLAG_OVERRIDE_CHANNEL_ACCESS 0x40 struct ClientSocket; struct UserNode; @@ -23,6 +24,8 @@ struct cmd_function { cmd_bind_t *func; unsigned int flags; int paramcount; + int global_access; + char *channel_access; struct cmd_function *next; }; @@ -33,7 +36,8 @@ struct cmd_binding { struct cmd_function *func; unsigned int flags; char *parameters; - int gaccess; + int global_access; + char *channel_access; struct cmd_binding *next; }; @@ -48,7 +52,7 @@ struct trigger_cache { void init_modcmd(); void free_modcmd(); struct ClientSocket* get_prefered_bot(int botid); -int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags); +int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags, char *channel_access, int global_access); int set_trigger_callback(int botid, trigger_callback_t *func); int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger); int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func); @@ -56,6 +60,7 @@ int bind_cmd_to_command(int botid, char *cmd, char *func); int unbind_cmd(int botid, char *cmd); struct ClientSocket *getTextBot(); void bind_set_parameters(int botid, char *cmd, char *parameters); -void bind_set_gaccess(int botid, char *cmd, int gaccess); +void bind_set_global_access(int botid, char *cmd, int gaccess); +void bind_set_channel_access(int botid, char *cmd, char *chanaccess); #endif \ No newline at end of file -- 2.20.1