int whois_access(struct userrec *user, struct userrec *whois_user) { if (user == whois_user) return 1; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 }, whois = { FR_GLOBAL | FR_CHAN, 0, 0, 0}; get_user_flagrec(user, &fr, NULL); get_user_flagrec(whois_user, &whois, NULL); /* Don't show hub bots from leaf bots. */ if (!conf.bot->hub && whois_user->bot && bot_hublevel(whois_user) < 999) return 0; if ( (isowner(whois_user->handle) && !isowner(user->handle)) || (glob_admin(whois) && !glob_admin(fr)) || (glob_owner(whois) && !glob_owner(fr)) || (glob_master(whois) && !glob_master(fr)) || (glob_bot(whois) && !glob_master(fr)) ) return 0; return 1; }
static void cmd_mns_chrec(int idx, char *par) { char *nick = NULL, *chn = NULL; struct userrec *u1 = NULL; struct chanuserrec *chanrec = NULL; if (!par[0]) { dprintf(idx, "Usage: -chrec <user> [channel]\n"); return; } nick = newsplit(&par); u1 = get_user_by_handle(userlist, nick); if (!u1) { dprintf(idx, "No such user.\n"); return; } if (!par[0]) { struct chanset_t *chan; chan = findchan_by_dname(dcc[idx].u.chat->con_chan); if (chan) chn = chan->dname; else { dprintf(idx, "Invalid console channel.\n"); return; } } else chn = newsplit(&par); get_user_flagrec(dcc[idx].user, &user, chn); get_user_flagrec(u1, &victim, chn); if (privchan(user, findchan_by_dname(chn), PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } if ((!glob_master(user) && !chan_master(user)) || /* drummer */ (chan_owner(victim) && !chan_owner(user) && !glob_owner(user)) || (glob_owner(victim) && !glob_owner(user))) { dprintf(idx, "You have no permission to do that.\n"); return; } chanrec = get_chanrec(u1, chn); if (!chanrec) { dprintf(idx, "User %s doesn't have a channel record for %s.\n", nick, chn); return; } putlog(LOG_CMDS, "*", "#%s# -chrec %s %s", dcc[idx].nick, nick, chn); del_chanrec(u1, chn); dprintf(idx, "Removed %s channel record from %s.\n", chn, nick); if (conf.bot->hub) write_userfile(idx); }
static void set_display(int idx, struct user_entry *e, struct userrec *u) { if (conf.bot->hub) { struct xtra_key *xk = (struct xtra_key *) e->u.extra; struct flag_record fr = {FR_GLOBAL, 0, 0, 0 }; get_user_flagrec(dcc[idx].user, &fr, NULL); /* scan thru xtra field, searching for matches */ for (; xk; xk = xk->next) { /* ok, it's a valid xtra field entry */ if (glob_owner(fr)) dprintf(idx, " %s: %s\n", xk->key, xk->data ? xk->data : ""); } } }
/* private returns 0 if user has access, and 1 if they dont because of +private * This function does not check if the user has "op" access, it only checks if the user is * restricted by +private for the channel */ int privchan(struct flag_record fr, struct chanset_t *chan, int type) { if (!chan || !channel_privchan(chan) || glob_bot(fr) || glob_owner(fr)) return 0; /* user is implicitly not restricted by +private, they may however be lacking other flags */ if (type == PRIV_OP) { /* |o implies all flags above. n| has access to all +private. Bots are exempt. */ if (chan_op(fr)) return 0; } else if (type == PRIV_VOICE) { if (chan_voice(fr) || chan_op(fr)) return 0; } return 1; /* user is restricted by +private */ }
/* Get icon symbol for a user (depending on access level) * * (*) owner on any channel * (+) master on any channel * (%) botnet master * (@) op on any channel * (^) halfop on any channel * (-) other */ char geticon(int idx) { struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; if (!dcc[idx].user) return '-'; get_user_flagrec(dcc[idx].user, &fr, 0); if (glob_owner(fr) || chan_owner(fr)) return '*'; if (glob_master(fr) || chan_master(fr)) return '+'; if (glob_botmast(fr)) return '%'; if (glob_op(fr) || chan_op(fr)) return '@'; if (glob_halfop(fr) || chan_halfop(fr)) return '^'; return '-'; }
static void cmd_chinfo(int idx, char *par) { if (!use_info) { dprintf(idx, "Info storage is turned off.\n"); return; } char *handle = newsplit(&par); if (!handle[0]) { dprintf(idx, "Usage: chinfo <handle> [channel] <new-info>\n"); return; } struct userrec *u1 = get_user_by_handle(userlist, handle); if (!u1 || (u1 && !whois_access(dcc[idx].user, u1))) { dprintf(idx, "No such user.\n"); return; } char *chname = NULL; if (par[0] && strchr(CHANMETA, par[0])) { chname = newsplit(&par); if (!findchan_by_dname(chname)) { dprintf(idx, "No such channel.\n"); return; } } else chname = 0; if (u1->bot && !(dcc[idx].user->flags & USER_MASTER)) { dprintf(idx, "You have to be master to change bots info.\n"); return; } if ((u1->flags & USER_OWNER) && !(dcc[idx].user->flags & USER_OWNER)) { dprintf(idx, "You can't change info for the bot owner.\n"); return; } if (chname) { get_user_flagrec(dcc[idx].user, &user, chname); get_user_flagrec(u1, &victim, chname); if ((chan_owner(victim) || glob_owner(victim)) && !(glob_owner(user) || chan_owner(user))) { dprintf(idx, "You can't change info for the channel owner.\n"); return; } } putlog(LOG_CMDS, "*", "#%s# chinfo %s %s %s", dcc[idx].nick, handle, chname ? chname : par, chname ? par : ""); if (!strcasecmp(par, "none")) par[0] = 0; if (chname) { set_handle_chaninfo(userlist, handle, chname, par); if (par[0] == '@') dprintf(idx, "New info (LOCKED) for %s on %s: %s\n", handle, chname, &par[1]); else if (par[0]) dprintf(idx, "New info for %s on %s: %s\n", handle, chname, par); else dprintf(idx, "Wiped info for %s on %s\n", handle, chname); if (conf.bot->hub) write_userfile(idx); } else { set_user(&USERENTRY_INFO, u1, par[0] ? par : NULL); if (par[0] == '@') dprintf(idx, "New default info (LOCKED) for %s: %s\n", handle, &par[1]); else if (par[0]) dprintf(idx, "New default info for %s: %s\n", handle, par); else dprintf(idx, "Wiped default info for %s\n", handle); if (conf.bot->hub) write_userfile(idx); } }
static void cmd_chanset(int idx, char *par) { char *chname = NULL, result[RESULT_LEN] = ""; struct chanset_t *chan = NULL; int all = 0; if (!par[0]) { putlog(LOG_CMDS, "*", "#%s# chanset %s", dcc[idx].nick, par); dprintf(idx, "Usage: chanset [%schannel|*|default] <settings>\n", CHANMETA); return; } // Determine channel name if (strchr(CHANMETA, par[0]) || !strncasecmp(par, "default", 7) || !strncmp(par, "*", 1)) chname = newsplit(&par); else { if (strncmp(dcc[idx].u.chat->con_chan, "*", 1) && !(chan = findchan_by_dname(chname = dcc[idx].u.chat->con_chan))) { dprintf(idx, "Invalid console channel.\n"); return; } chname = dcc[idx].u.chat->con_chan; } if (chname && chname[0]) { if (!strncmp(chname, "*", 1)) { all = 1; get_user_flagrec(dcc[idx].user, &user, chanset ? chanset->dname : ""); if (!glob_owner(user)) { dprintf(idx, "You need to be a global owner to use '%schanset *'.\n", (dcc[idx].u.chat->channel >= 0) ? settings.dcc_prefix : ""); return; } } else if (!strcasecmp(chname, "default")) { chan = chanset_default; } else chan = findchan_by_dname(chname); } if (!all && !chan && chname && chname[0]) { dprintf(idx, "No such channel.\n"); return; } if (!par[0]) { dprintf(idx, "Usage: chanset [%schannel|*|default] <settings>\n", CHANMETA); return; } if (!all) { get_user_flagrec(dcc[idx].user, &user, chan->dname); if (privchan(user, chan, PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } if (!glob_master(user) && !chan_master(user)) { dprintf(idx, "You don't have access to %s. \n", chan->dname); return; } else if ((strstr(par, "+private") || strstr(par, "-private")) && (!glob_owner(user))) { dprintf(idx, "You don't have access to set +/-private on %s (halting command).\n", chan->dname); return; } else if ((strstr(par, "+backup") || strstr(par, "-backup")) && (!glob_owner(user))) { dprintf(idx, "You don't have access to set +/-backup on %s (halting command).\n", chan->dname); return; } else if ((strstr(par, "+inactive") || strstr(par, "-inactive")) && (!glob_owner(user))) { dprintf(idx, "You don't have access to set +/-inactive on %s (halting command).\n", chan->dname); return; } } putlog(LOG_CMDS, "*", "#%s# chanset (%s) %s", dcc[idx].nick, all ? "*" : chan->dname, par); if (do_chanset(result, all ? NULL : chan, par, DO_LOCAL | DO_NET | CMD) == ERROR) { dprintf(idx, "Error trying to set { %s } on %s: %s\n", par, all ? "all channels" : chan->dname, result); return; } if (all) dprintf(idx, "Successfully set modes { %s } on all channels (Including the default).\n", par); else dprintf(idx, "Successfully set modes { %s } on %s\n", par, chan->dname); if (conf.bot->hub) write_userfile(idx); }