Ejemplo n.º 1
0
/**
 * The /os admin command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_admin(User * u)
{
    char *cmd = strtok(NULL, " ");
    char *nick = strtok(NULL, " ");
    NickAlias *na;
    int res = 0;

    if (skeleton) {
        notice_lang(s_OperServ, u, OPER_ADMIN_SKELETON);
        return MOD_CONT;
    }

    if (!cmd || (!nick && stricmp(cmd, "LIST") && stricmp(cmd, "CLEAR"))) {
        syntax_error(s_OperServ, u, "ADMIN", OPER_ADMIN_SYNTAX);
    } else if (!stricmp(cmd, "ADD")) {
        if (!is_services_root(u)) {
            notice_lang(s_OperServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }

        if (!(na = findnick(nick))) {
            notice_lang(s_OperServ, u, NICK_X_NOT_REGISTERED, nick);
            return MOD_CONT;
        }

        if (na->status & NS_VERBOTEN) {
            notice_lang(s_OperServ, u, NICK_X_FORBIDDEN, nick);
            return MOD_CONT;
        }

        if (na->nc->flags & NI_SERVICES_ADMIN
            || slist_indexof(&servadmins, na->nc) != -1) {
            notice_lang(s_OperServ, u, OPER_ADMIN_EXISTS, nick);
            return MOD_CONT;
        }

        res = slist_add(&servadmins, na->nc);
        if (res == -2) {
            notice_lang(s_OperServ, u, OPER_ADMIN_REACHED_LIMIT, nick);
            return MOD_CONT;
        } else {
            if (na->nc->flags & NI_SERVICES_OPER
                && (res = slist_indexof(&servopers, na->nc)) != -1) {
                slist_delete(&servopers, res);
                na->nc->flags |= NI_SERVICES_ADMIN;
                notice_lang(s_OperServ, u, OPER_ADMIN_MOVED, nick);
	    } else if (na->nc->flags & NI_SERVICES_HELPOP && (res = slist_indexof(&servhelpops, na->nc)) != -1) {
	    	slist_delete(&servhelpops, res);
		na->nc->flags |= NI_SERVICES_ADMIN;
		notice_lang(s_OperServ, u, OPER_ADMIN_MOVED, nick);
            } else {
                na->nc->flags |= NI_SERVICES_ADMIN;
                notice_lang(s_OperServ, u, OPER_ADMIN_ADDED, nick);
            }

	    LogStaffAction(STAFFLOG_CHANNEL | STAFFLOG_OPERGLOBAL, "OperServ",
            	"%s!%s@%s added %s to the services admin list",
                u->nick, u->username, u->host, nick);

        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);
    } else if (!stricmp(cmd, "DEL")) {
        if (!is_services_root(u)) {
            notice_lang(s_OperServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }

        if (servadmins.count == 0) {
            notice_lang(s_OperServ, u, OPER_ADMIN_LIST_EMPTY);
            return MOD_CONT;
        }

        if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick)) {
            /* Deleting a range */
            res = slist_delete_range(&servadmins, nick, NULL);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_ADMIN_NO_MATCH);
                return MOD_CONT;
            } else if (res == 1) {
                notice_lang(s_OperServ, u, OPER_ADMIN_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_ADMIN_DELETED_SEVERAL,
                            res);
            }
        } else {
            if (!(na = findnick(nick))) {
                notice_lang(s_OperServ, u, NICK_X_NOT_REGISTERED, nick);
                return MOD_CONT;
            }

            if (na->status & NS_VERBOTEN) {
                notice_lang(s_OperServ, u, NICK_X_FORBIDDEN, nick);
                return MOD_CONT;
            }

            if (!(na->nc->flags & NI_SERVICES_ADMIN)
                || (res = slist_indexof(&servadmins, na->nc)) == -1) {
                notice_lang(s_OperServ, u, OPER_ADMIN_NOT_FOUND, nick);
                return MOD_CONT;
            }

            slist_delete(&servadmins, res);
            notice_lang(s_OperServ, u, OPER_ADMIN_DELETED, nick);
        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);
    } else if (!stricmp(cmd, "LIST")) {
        int sent_header = 0;

        if (servadmins.count == 0) {
            notice_lang(s_OperServ, u, OPER_ADMIN_LIST_EMPTY);
            return MOD_CONT;
        }

        if (!nick || (isdigit(*nick)
                      && strspn(nick, "1234567890,-") == strlen(nick))) {
            res =
                slist_enum(&servadmins, nick, &admin_list_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_ADMIN_NO_MATCH);
                return MOD_CONT;
            } else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Admin");
            }
        } else {
            int i;

            for (i = 0; i < servadmins.count; i++)
                if (!stricmp
                    (nick, ((NickCore *) servadmins.list[i])->display)
                    || match_wild_nocase(nick,
                                         ((NickCore *) servadmins.
                                          list[i])->display))
                    admin_list(i + 1, servadmins.list[i], u, &sent_header);

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_ADMIN_NO_MATCH);
            else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Admin");
            }
        }
    } else if (!stricmp(cmd, "CLEAR")) {
        if (!is_services_root(u)) {
            notice_lang(s_OperServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }

        if (servadmins.count == 0) {
            notice_lang(s_OperServ, u, OPER_ADMIN_LIST_EMPTY);
            return MOD_CONT;
        }

        slist_clear(&servadmins, 1);
        notice_lang(s_OperServ, u, OPER_ADMIN_CLEAR);
    } else {
        syntax_error(s_OperServ, u, "ADMIN", OPER_ADMIN_SYNTAX);
    }
    return MOD_CONT;
}
Ejemplo n.º 2
0
static int do_akill(User * u)
{
    char *cmd = strtok(NULL, " ");
    char breason[BUFSIZE];

    if (!cmd)
        cmd = "";

    if (!stricmp(cmd, "ADD")) {
        int deleted = 0;
        char *expiry, *mask, *reason;
        time_t expires, now = time(NULL);

        mask = strtok(NULL, " ");
        if (mask && *mask == '+') {
            expiry = mask;
            mask = strtok(NULL, " ");
        } else {
            expiry = NULL;
        }

        expires = expiry ? dotime(expiry) : AutokillExpiry;
        /* If the expiry given does not contain a final letter, it's in days,
         * said the doc. Ah well.
         */
        if (expiry && isdigit(expiry[strlen(expiry) - 1]))
            expires *= 86400;
        /* Do not allow less than a minute expiry time */
        if (expires != 0 && expires < 60) {
            notice_lang(s_OperServ, u, BAD_EXPIRY_TIME);
            return MOD_CONT;
        } else if (expires > 0) {
            expires += time(NULL);
        }

        if (mask && (reason = strtok(NULL, ""))) {
            /* We first do some sanity check on the proposed mask. */
            if (strchr(mask, '!')) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_NICK);
                return MOD_CONT;
            }

            if (!strchr(mask, '@')) {
                notice_lang(s_OperServ, u, BAD_USERHOST_MASK);
                return MOD_CONT;
            }

            if (mask && strspn(mask, "~@.*?") == strlen(mask)) {
                notice_lang(s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
                return MOD_CONT;
            }

            /**
             * Changed sprintf() to snprintf()and increased the size of
             * breason to match bufsize
             * -Rob
             **/
            if (AddAkiller) {
                snprintf(breason, sizeof(breason), "[%s] %s", u->nick,
                         reason);
                reason = sstrdup(breason);
            }

            deleted = add_akill(u, mask, u->nick, expires, reason);
            if (deleted < 0) {
                if (AddAkiller) {
                    free(reason);
                }
                return MOD_CONT;
            } else if (deleted) {
                notice_lang(s_OperServ, u, OPER_AKILL_DELETED_SEVERAL,
                            deleted);
            }
            notice_lang(s_OperServ, u, OPER_AKILL_ADDED, mask);

            if (WallOSAkill) {
                char buf[128];

                if (!expires) {
                    strcpy(buf, "does not expire");
                } else {
                    int wall_expiry = expires - now;
                    char *s = NULL;

                    if (wall_expiry >= 86400) {
                        wall_expiry /= 86400;
                        s = "day";
                    } else if (wall_expiry >= 3600) {
                        wall_expiry /= 3600;
                        s = "hour";
                    } else if (wall_expiry >= 60) {
                        wall_expiry /= 60;
                        s = "minute";
                    }

                    snprintf(buf, sizeof(buf), "expires in %d %s%s",
                             wall_expiry, s,
                             (wall_expiry == 1) ? "" : "s");
                }

                anope_cmd_global(s_OperServ,
                                 "%s added an AKILL for %s (%s) (%s)",
                                 u->nick, mask, reason, buf);
            }

            if (readonly) {
                notice_lang(s_OperServ, u, READ_ONLY_MODE);
            }
            if (AddAkiller) {
                free(reason);
            }
        } else {
            syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
        }

    } else if (!stricmp(cmd, "DEL")) {

        char *mask;
        int res = 0;

        mask = strtok(NULL, " ");

        if (!mask) {
            syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
            return MOD_CONT;
        }

        if (akills.count == 0) {
            notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
            return MOD_CONT;
        }

        if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
            /* Deleting a range */
            res = slist_delete_range(&akills, mask, NULL);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
                return MOD_CONT;
            } else if (res == 1) {
                notice_lang(s_OperServ, u, OPER_AKILL_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_AKILL_DELETED_SEVERAL,
                            res);
            }
        } else {
            if ((res = slist_indexof(&akills, mask)) == -1) {
                notice_lang(s_OperServ, u, OPER_AKILL_NOT_FOUND, mask);
                return MOD_CONT;
            }

            slist_delete(&akills, res);
            notice_lang(s_OperServ, u, OPER_AKILL_DELETED, mask);
        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);

    } else if (!stricmp(cmd, "LIST")) {
        char *mask;
        int res, sent_header = 0;

        if (akills.count == 0) {
            notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, " ");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&akills, mask, &akill_list_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
                return MOD_CONT;
            } else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Akill");
            }
        } else {
            int i;
            char amask[BUFSIZE];

            for (i = 0; i < akills.count; i++) {
                snprintf(amask, sizeof(amask), "%s@%s",
                         ((Akill *) akills.list[i])->user,
                         ((Akill *) akills.list[i])->host);
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    akill_list(i + 1, akills.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
            else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Akill");
            }
        }
    } else if (!stricmp(cmd, "VIEW")) {
        char *mask;
        int res, sent_header = 0;

        if (akills.count == 0) {
            notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, " ");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&akills, mask, &akill_view_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
                return MOD_CONT;
            }
        } else {
            int i;
            char amask[BUFSIZE];

            for (i = 0; i < akills.count; i++) {
                snprintf(amask, sizeof(amask), "%s@%s",
                         ((Akill *) akills.list[i])->user,
                         ((Akill *) akills.list[i])->host);
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    akill_view(i + 1, akills.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
        }
    } else if (!stricmp(cmd, "CLEAR")) {
        slist_clear(&akills, 1);
        notice_lang(s_OperServ, u, OPER_AKILL_CLEAR);
    } else {
        syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
    }
    return MOD_CONT;
}
Ejemplo n.º 3
0
/**
 * The /os sgline command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_sgline(User * u)
{
    char *cmd = strtok(NULL, " ");

    if (!cmd)
        cmd = "";

    if (!stricmp(cmd, "ADD")) {
        int deleted = 0;
        char *expiry, *mask, *reason;
        time_t expires;

        mask = strtok(NULL, ":");
        if (mask && *mask == '+') {
            expiry = mask;
            mask = strchr(expiry, ' ');
            if (mask) {
                *mask = 0;
                mask++;
            }
        } else {
            expiry = NULL;
        }

        expires = expiry ? dotime(expiry) : SGLineExpiry;
        /* If the expiry given does not contain a final letter, it's in days,
         * said the doc. Ah well.
         */
        if (expiry && isdigit(expiry[strlen(expiry) - 1]))
            expires *= 86400;
        /* Do not allow less than a minute expiry time */
        if (expires != 0 && expires < 60) {
            notice_lang(s_OperServ, u, BAD_EXPIRY_TIME);
            return MOD_CONT;
        } else if (expires > 0) {
            expires += time(NULL);
        }

        if (mask && (reason = strtok(NULL, ""))) {
			/* Clean up the last character of the mask if it is a space
			 * See bug #761
			 */
			size_t masklen = strlen(mask);
			if (mask[masklen - 1] == ' ')
				mask[masklen - 1] = '\0';
			
            /* We first do some sanity check on the proposed mask. */

            if (mask && strspn(mask, "*?") == strlen(mask)) {
                notice_lang(s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
                return MOD_CONT;
            }

            deleted = add_sgline(u, mask, u->nick, expires, reason);
            if (deleted < 0)
                return MOD_CONT;
            else if (deleted)
                notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL,
                            deleted);
            notice_lang(s_OperServ, u, OPER_SGLINE_ADDED, mask);

            if (WallOSSGLine) {
                char buf[128];

                if (!expires) {
                    strcpy(buf, "does not expire");
                } else {
                    int wall_expiry = expires - time(NULL);
                    char *s = NULL;

                    if (wall_expiry >= 86400) {
                        wall_expiry /= 86400;
                        s = "day";
                    } else if (wall_expiry >= 3600) {
                        wall_expiry /= 3600;
                        s = "hour";
                    } else if (wall_expiry >= 60) {
                        wall_expiry /= 60;
                        s = "minute";
                    }

                    snprintf(buf, sizeof(buf), "expires in %d %s%s",
                             wall_expiry, s,
                             (wall_expiry == 1) ? "" : "s");
                }

                xanadu_cmd_global(s_OperServ,
                                 "%s added an SGLINE for %s (%s)", u->nick,
                                 mask, buf);
            }

            if (readonly)
                notice_lang(s_OperServ, u, READ_ONLY_MODE);

        } else {
            syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
        }

    } else if (!stricmp(cmd, "DEL")) {

        char *mask;
        int res = 0;

        mask = strtok(NULL, "");

        if (!mask) {
            syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
            return MOD_CONT;
        }

        if (sglines.count == 0) {
            notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
            return MOD_CONT;
        }

        if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
            /* Deleting a range */
            res = slist_delete_range(&sglines, mask, NULL);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
                return MOD_CONT;
            } else if (res == 1) {
                notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL,
                            res);
            }
        } else {
            if ((res = slist_indexof(&sglines, mask)) == -1) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NOT_FOUND, mask);
                return MOD_CONT;
            }

            slist_delete(&sglines, res);
            notice_lang(s_OperServ, u, OPER_SGLINE_DELETED, mask);
        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);

    } else if (!stricmp(cmd, "LIST")) {
        char *mask;
        int res, sent_header = 0;

        if (sglines.count == 0) {
            notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, "");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&sglines, mask, &sgline_list_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
                return MOD_CONT;
            }
        } else {
            int i;
            char *amask;

            for (i = 0; i < sglines.count; i++) {
                amask = ((SXLine *) sglines.list[i])->mask;
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    sgline_list(i + 1, sglines.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
            else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "SGLine");
            }
        }
    } else if (!stricmp(cmd, "VIEW")) {
        char *mask;
        int res, sent_header = 0;

        if (sglines.count == 0) {
            notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, "");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&sglines, mask, &sgline_view_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
                return MOD_CONT;
            }
        } else {
            int i;
            char *amask;

            for (i = 0; i < sglines.count; i++) {
                amask = ((SXLine *) sglines.list[i])->mask;
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    sgline_view(i + 1, sglines.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
        }
    } else if (!stricmp(cmd, "CLEAR")) {
        slist_clear(&sglines, 1);
        notice_lang(s_OperServ, u, OPER_SGLINE_CLEAR);
    } else {
        syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
    }
    return MOD_CONT;
}