void ns_sdrop(IRC_User *s, IRC_User *u) { u_int32_t source_snid; u_int32_t snid; char *nick; nick = strtok(NULL, " "); CHECK_IF_IDENTIFIED_NICK if(!is_sadmin(source_snid)) send_lang(u, s, ONLY_FOR_SADMINS); else if(IsNull(nick)) send_lang(u, s, NICK_SDROP_SYNTAX); else if((snid = nick2snid(nick)) == 0) send_lang(u, s, NICK_X_NOT_REGISTERED, nick); else { IRC_User *target = irc_FindUser(nick); drop_nick(snid, nick); if(target && target->snid) { target->snid = 0; target->status = 0; target->flags = 0; irc_SvsMode(target, s, "-r"); } log_log(ns_log, mod_info.name, "%s SDROPPED nick: %s", u->nick, nick); send_lang(u, s, NICK_SDROPPED, nick); } }
/* s = service the command was sent to u = user the command was sent from */ void ns_group(IRC_User *s, IRC_User *u) { u_int32_t source_snid; u_int32_t snid; char *cmd; char *gname; char *nick; int memberc = 0; u_int32_t master_sgid; u_int32_t sgid; CHECK_IF_IDENTIFIED_NICK cmd = strtok(NULL, " "); gname = strtok(NULL, " "); /* base syntax validation */ if(IsNull(cmd)) send_lang(u, s, NS_GROUP_SYNTAX); else if(strcasecmp(cmd,"CREATE") == 0) { char *master; char *gdesc; char *umodes = NULL; master = strtok(NULL, " "); gdesc = strtok(NULL, ""); if(gname) /* first check if the name contains umodes */ { char *pumodes; char *eumodes; pumodes = strchr(gname,'['); if(pumodes && pumodes[0]) { *(pumodes++) = '\0'; eumodes = strchr(pumodes,']'); if(eumodes) { *eumodes = '\0'; umodes = pumodes; } } } /* syntax validation */ if(IsNull(gname) || IsNull(master)) send_lang(u, s, NS_GROUP_CREATE_SYNTAX); /* permissions validation */ else if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); /* check requirements */ else if((master_sgid = find_group(master)) == 0) send_lang(u, s, NS_GROUP_MASTER_NOT_FOUND, master); /* avoid duplicates */ else if((sgid = find_group(gname)) != 0) send_lang(u, s, NS_GROUP_ALREADY_EXISTS, gname); /* execute operation */ else if(group_create(gname, master_sgid, gdesc, umodes) > 0) /* report operation status */ send_lang(u, s, NS_GROUP_CREATE_OK, gname); else send_lang(u, s, UPDATE_FAIL); } else if(strcasecmp(cmd,"ADD") == 0) { u_int32_t duration = 0; time_t master_expire = 0; u_int32_t is_master_sgid; char *duration_str; nick = strtok(NULL, " "); duration_str = strtok(NULL, " "); if(duration_str) duration = time_str(duration_str); /* syntax validation */ if(IsNull(gname) || IsNull(nick)) send_lang(u, s, NS_GROUP_ADD_SYNTAX); /* check requirements */ else if((snid = nick2snid(nick)) == 0) send_lang(u, s, NO_SUCH_NICK_X, nick); else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); /* privileges validation */ else if(group_is_full(sgid)) send_lang(u, s, NS_GROUP_IS_FULL_X); else if(((is_master_sgid = is_master(source_snid, sgid))== 0) && !is_sroot(source_snid)) send_lang(u, s, NOT_MASTER_OF_X, gname); /* avoid duplicates */ else if(sql_singlequery("SELECT t_expire FROM ns_group_users " " WHERE sgid=%d AND snid=%d", is_master_sgid, source_snid) && (master_expire = sql_field_i(0)) && duration) send_lang(u, s, NS_GROUP_CANT_DEFINE_TIME_X, gname); else if(is_member_of(snid, sgid)) send_lang(u, s, NICK_X_ALREADY_ON_X, nick, gname); /* execute operation */ else { time_t t_expire = 0; if(master_expire) t_expire = master_expire; else if(duration) t_expire = irc_CurrentTime + duration; if(add_to_group(sgid, snid, t_expire) > 0) /* report operation status */ { char *server = strchr(gname, '@'); IRC_User *user = irc_FindUser(nick); send_lang(u, s, NICK_ADDED_X_X, nick, gname); if(server) /* we have a server rule to be validated */ ++server; if(user && (!server || (strcasecmp(server,u->server->sname) == 0))) { if(user->extra[ED_GROUPS] == NULL) { user->extra[ED_GROUPS] = malloc(sizeof(darray)); array_init(user->extra[ED_GROUPS], 1, DA_INT); } array_add_int(user->extra[ED_GROUPS], sgid); } } else send_lang(u, s, UPDATE_FAIL); } } else if(strcasecmp(cmd,"DEL") == 0) { nick = strtok(NULL, " "); /* syntax validation */ if(IsNull(gname) || IsNull(nick)) send_lang(u, s, NS_GROUP_DEL_SYNTAX); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); else if((snid = nick2snid(nick)) == 0) send_lang(u, s, NO_SUCH_NICK_X, nick); /* privileges validation */ else if(!is_sroot(source_snid) && !is_master(source_snid, sgid)) send_lang(u, s, NOT_MASTER_OF_X, gname); else if(!is_member_of(snid, sgid)) send_lang(u, s, NICK_X_NOT_ON_GROUP_X, nick, gname); /* execute operation */ else if(del_from_group(sgid, snid) > 0) /* report operation status */ { IRC_User *user = irc_FindUser(nick); send_lang(u, s, NICK_DEL_X_X, nick, gname); if(user) array_del_int(user->extra[ED_GROUPS], sgid); } else send_lang(u, s, UPDATE_FAIL); } else if(strcasecmp(cmd,"INFO") == 0) { /* syntax validation */ if(IsNull(gname)) send_lang(u, s, NS_GROUP_INFO_SYNTAX); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); /* check privileges */ else if(!is_master(source_snid, sgid) && !is_member_of(source_snid, sgid)) send_lang(u, s, NOT_MASTER_OR_MEMBER_X, gname); else if((sgid = find_group(gname))) /* we need to get the group description */ { /* execute operation */ MYSQL_RES* res; master_sgid = 0; sql_singlequery("SELECT gdesc, master_sgid FROM ns_group WHERE sgid=%d", sgid); send_lang(u, s, NS_GROUP_INFO_X, gname); if(sql_field(0)) send_lang(u, s, NS_GROUP_INFO_DESC_X, sql_field(0)); master_sgid = sql_field_i(1); if(master_sgid != 0) { if(sql_singlequery("SELECT name FROM ns_group WHERE sgid=%d", master_sgid) > 0) { send_lang(u, s, NS_GROUP_INFO_MASTER_X, sql_field(0)); } } res = sql_query("SELECT n.nick, gm.t_expire FROM " "nickserv n, ns_group_users gm WHERE gm.sgid=%d AND n.snid=gm.snid", sgid); if(sql_next_row(res) == NULL) send_lang(u, s, NS_GROUP_EMPTY); else { do { char buf[64]; struct tm *tm; time_t t_expire = sql_field_i(1); buf[0] = '\0'; if(t_expire) { tm = localtime(&t_expire); strftime(buf, sizeof(buf), format_str(u, DATE_FORMAT), tm); send_lang(u,s, NS_GROUP_ITEM_X_X, sql_field(0), buf); } else send_lang(u,s, NS_GROUP_ITEM_X, sql_field(0)); ++memberc; } while(sql_next_row(res)); send_lang(u, s, NS_GROUP_MEMBERS_TAIL_X, memberc); } sql_free(res); } } else if(strcasecmp(cmd,"DROP") == 0) { /* syntax validation */ if(IsNull(gname)) send_lang(u, s, NS_GROUP_DROP_SYNTAX); /* privileges validation */ else if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); /* NOTE: The following sql_field( depends on previous find_group( */ else if(!sql_field(2) || (master_sgid = atoi(sql_field(2))) == 0) send_lang(u, s, CANT_DROP_ROOT); /* execute operation */ else if(drop_group(sgid)>0) /* report operation status */ send_lang(u, s, NS_GROUP_DROPPED_X, gname); else send_lang(u, s, UPDATE_FAIL); } else if(strcasecmp(cmd,"LIST") == 0) /* List groups */ { MYSQL_RES* res; MYSQL_ROW row; /* privileges validation */ if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); else { res = sql_query("SELECT name, master_sgid, gdesc FROM ns_group"); send_lang(u, s, NS_GROUP_LIST_HEADER); while((row = sql_next_row(res))) { char* mname = ""; if(row[1] && sql_singlequery("SELECT name FROM ns_group WHERE sgid=%d", atoi(row[1])) > 0) mname = sql_field(0); send_lang(u, s, NS_GROUP_LIST_X_X_X, row[0], mname, row[2] ? row[2] : ""); } send_lang(u, s, NS_GROUP_LIST_TAIL); sql_free(res); } } else if(strcasecmp(cmd,"SHOW") == 0) /* Show groups we belong to */ { /* groups count */ int gc = array_count(u->extra[ED_GROUPS]); if(gc == 0) send_lang(u, s, NO_GROUPS); else { MYSQL_RES *res; MYSQL_ROW row; char buf[64]; struct tm *tm; time_t t_expire; #if 0 int i; u_int32_t* data = array_data_int(u->extra[ED_GROUPS]); #endif send_lang(u, s, NS_GROUP_SHOW_HEADER); #if 0 for(i = 0; i < gc; ++i) { if(sql_singlequery("SELECT name,gdesc FROM ns_group WHERE sgid=%d", data[i]) > 0 ) send_lang(u, s, NS_GROUP_SHOW_X_X, sql_field(0), sql_field(1) ? sql_field(1) : ""); } #endif res = sql_query("SELECT g.name, g.gdesc, gu.t_expire FROM ns_group g, ns_group_users gu" " WHERE gu.snid=%d AND g.sgid=gu.sgid ORDER BY g.master_sgid", source_snid); while((row = sql_next_row(res))) { t_expire = sql_field_i(2); buf[0] = '\0'; if(t_expire) { tm = localtime(&t_expire); strftime(buf, sizeof(buf), format_str(u, DATE_FORMAT), tm); send_lang(u,s, NS_GROUP_SHOW_X_X_X, row[0], row[1] ? row[1] : "", buf); } else send_lang(u, s, NS_GROUP_SHOW_X_X, row[0], row[1] ? row[1] : ""); } send_lang(u, s, NS_GROUP_SHOW_TAIL); sql_free(res); } } else if(strcasecmp(cmd,"SET") == 0) { char *option; char *value ; option = strtok(NULL, " "); value = strtok(NULL, " "); /* syntax validation */ if(IsNull(gname) || IsNull(option)) send_lang(u, s, NS_GROUP_SET_SYNTAX); /* privileges validation */ else if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); else { if(strcasecmp(option,"AUTOMODES") == 0) STRING_SET("autoumodes", AUTOMODES_X_UNSET, AUTOMODES_X_CHANGED_TO_X) else if(strcasecmp(option,"DESC") == 0) STRING_SET("gdesc", DESC_X_UNSET, DESC_X_CHANGED_TO_X) else if(strcasecmp(option, "MAXUSERS") == 0) INT_SET("maxusers", NS_GROUP_SET_MAXUSERS_SET_X_X) else send_lang(u, s, SET_INVALID_OPTION_X, option); } }
/** internal functions implementation starts here **/ void os_sendpass(IRC_User *s, IRC_User *u) { u_int32_t source_snid; u_int32_t snid; char *target; char *email; int lang; /* status validation */ CHECK_IF_IDENTIFIED_NICK /* syntax validation */ target = strtok(NULL, " "); if (!is_soper(u->snid)) { send_lang(u, s, PERMISSION_DENIED); return; } if(!irc_IsUMode(u, UMODE_OPER)) /* extra security */ return; else if(IsNull(target)) send_lang(u, s, SENDPASS_SYNTAX); else if( (snid = nick2snid(target)) == 0 ) send_lang(u, s, NICK_X_NOT_REGISTERED, target); /* sub-command */ else if(is_sadmin(snid) || is_sroot(snid)) { log_log(os_log, mod_info.name, "Nick %s trying SENDPASS on sadmin/soper %s", s->nick, target); irc_SendSanotice(s, "Nick %s trying SENDPASS on sadmin/soper %s", s->nick, target); } else if((sql_singlequery("SELECT email, lang FROM nickserv WHERE snid=%d", snid) < 1) || ((email = sql_field(0)) == NULL)) send_lang(u, s, OS_SENDPASS_NO_EMAIL_X, target); else { char buf[512]; char pbuf[PASSLEN+1]; lang = sql_field_i(1); rand_string(pbuf, PASSLEN, PASSLEN); pbuf[2] = '0'+ (random() % 10); sql_execute("UPDATE nickserv_security SET pass=%s WHERE snid=%d", sql_str(hex_str(encrypted_password(pbuf), 16)), snid); snprintf(buf, sizeof(buf), "From: \"%%from_name%%\" <%%from%%>\r\nTo:\"%s\" <%s>\r\nSubject:%s\r\n\r\n%s", target, email, "Nick Password", lang_str_l(lang, SENDPASS_X_X, target, pbuf) ); email_init_symbols(); email_add_symbol("email", email); email_send(buf); memset(pbuf, 0, PASSLEN); send_lang(u, s, SENDPASS_X_SENT_X, target, email); log_log(os_log, mod_info.name, "SENDPASS for %s requested by %s", target, u->nick); irc_SendSanotice(s, "SENDPASS for %s requested by %s", target, u->nick); } }
/** internal functions implementation starts here **/ void ms_send(IRC_User *s, IRC_User *u) { u_int32_t source_snid; u_int32_t snid; u_int32_t id; char* target; char* message; int mcount = 0; int maxmemos; int bquota; u_int32_t flags; u_int32_t memo_flags = 0; /* status validation */ CHECK_IF_IDENTIFIED_NICK target = strtok(NULL, " "); message = strtok(NULL, ""); if(target && (snid = nick2snid(target)) == 0) { send_lang(u, s, NICK_X_NOT_REGISTERED, target); return; } /* we need to read memo options first */ memoserv_get_options(snid, &maxmemos, &bquota, &flags); if(flags && MOFL_AUTOSAVE) memo_flags = MFL_SAVED; if(NickSecurityCode && !IsAuthenticated(u)) send_lang(u, s, NEEDS_AUTH_NICK); else /* syntax validation */ if(IsNull(target) || IsNull(message)) send_lang(u, s, SEND_SYNTAX); /* check maxmemos */ else if(flags & MOFL_NOMEMOS) send_lang(u, s, MS_SEND_NOMEMOS); else if((mcount = memos_count(snid)) >= maxmemos) send_lang(u, s, MAX_MEMOS_REACHED_X_X, target, maxmemos); #if 0 /* check buddy quota for non buddies */ else if(is_buddy && (maxmemos-mcount <= bquota) && !is_buddy(snid, source_snid)) send_lang(u, s, MAX_MEMOS_REACHED_X_X, target, maxmemos-bquota); #endif /* execute operation */ else if((id = insert_memo(u->nick, source_snid, snid, message, memo_flags)) > 0) { IRC_User* tu; send_lang(u, s, SENT_MEMO_TO_X, target); tu = irc_FindUser(target); if(tu && tu->snid) /* target is online and identified */ { char memoprev[MEMOPREVMAX+1]; snprintf(memoprev, MEMOPREVMAX, "%s", message); send_lang(tu, s, YOU_GOT_MEMO_FROM_X_X_NUM_X, u->nick, memoprev, id); } if(flags & MOFL_FORWARD) { MYSQL_RES *res; MYSQL_ROW row; res = sql_query("SELECT email, lang FROM nickserv WHERE snid=%d", snid); if(res && (row = sql_next_row(res))) { char* email = row[0]; int lang = atoi(row[1]); email_init_symbols(); email_add_symbol("nick",target); email_add_symbol("email", email); email_add_symbol("message", message); email_add_symbol("subject", lang_str_l(lang, MS_SEND_SUBJECT_X, u->nick)); if(email_send(forward_email) < 0) { log_log(ms_log, mod_info.name, "Error sending forward email to %s by %s", email, irc_UserMask(u)); } } sql_free(res); } } else send_lang(u, s, UPDATE_FAIL); }
/* s = service the command was sent to u = user the command was sent from */ void bs_create(IRC_User *s, IRC_User *u) { char *bot_owner, *bot_nick, *bot_username, *bot_hostname, *bot_info; char *bot_time; int expire_time; u_int32_t owner_snid; u_int32_t source_snid; CHECK_IF_IDENTIFIED_NICK if (!is_member_of(u, bs_group) && !is_sadmin(u->snid)) { send_lang(u, s, PERMISSION_DENIED); return; } bot_owner = strtok(NULL, " "); bot_time = strtok(NULL, " "); if(bot_time) expire_time = ftime_str(bot_time); bot_nick = strtok(NULL, " "); bot_username = strtok(NULL, " "); bot_hostname = strtok(NULL, " "); bot_info = strtok(NULL, ""); if (!bot_owner || !bot_time || !bot_nick || !bot_username || !bot_hostname || !bot_info || (expire_time==-1)) send_lang(u, s, BS_CREATE_SYNTAX_INV); else /* check if the nickname is valid */ if(!irc_IsValidNick(bot_nick)) send_lang(u, s, BS_CREATE_INVALID_NICK_X, bot_nick); else /* check if the username is valid */ if(!irc_IsValidUsername(bot_username)) send_lang(u, s, BS_CREATE_INVALID_USER_X, bot_username); else /* check if the hostname is valid */ if(!irc_IsValidHostname(bot_hostname)) send_lang(u, s, BS_CREATE_INVALID_HOST_X, bot_hostname); else /* check if bot already exists */ if (sql_singlequery("SELECT bid FROM botserv WHERE nick=%s", sql_str(irc_lower_nick(bot_nick))) > 0) send_lang(u, s, BS_CREATE_X_EXISTS, bot_nick); else /* this should never happen, bot in mem but not on the db */ if(irc_FindLocalUser(bot_nick)) { send_lang(u, s, BS_CREATE_X_EXISTS, bot_nick); log_log(bs_log, mod_info.name, "Bot %s was found in mem but not on the db !", bot_nick); } else /* check if the nick is registered */ /* need to fix this, we should not access tables from other modules */ if(nick2snid(bot_nick)) send_lang(u, s, BS_CREATE_NICK_X_IS_REG_X, bot_nick); else /* check if the owner exists */ if((owner_snid = nick2snid(bot_owner)) == 0) send_lang(u, s, NICK_X_NOT_REGISTERED, bot_owner); else /* all conditions were checked, lets proceed */ { sqlb_init("botserv"); sqlb_add_int("owner_snid", owner_snid); sqlb_add_str("nick", bot_nick); sqlb_add_str("username", bot_username); sqlb_add_str("publichost", bot_hostname); sqlb_add_str("realname", bot_info); sqlb_add_int("t_create", irc_CurrentTime); sqlb_add_int("t_expire", expire_time ? irc_CurrentTime+expire_time : 0); if(sql_execute("%s", sqlb_insert()) < 0) send_lang(u, s, UPDATE_FAIL); else { log_log(bs_log, mod_info.name, "%s created bot %s %s %s %s", u->nick, bot_nick, bot_username, bot_hostname, bot_info); irc_CreateLocalUser(bot_nick, bot_username, bot_hostname, bot_hostname, bot_info, "+r"); send_lang(u, s, BS_CREATE_CREATED_X, bot_nick); } } }