From 1499c144370f5ee670112326ca70c61dad27c483 Mon Sep 17 00:00:00 2001 From: pk910 Date: Mon, 7 Jan 2013 13:09:17 +0100 Subject: [PATCH] added cmd_renamehost to HostServ module --- src/mod-hostserv.c | 169 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 157 insertions(+), 12 deletions(-) diff --git a/src/mod-hostserv.c b/src/mod-hostserv.c index b865afc..d9f1597 100644 --- a/src/mod-hostserv.c +++ b/src/mod-hostserv.c @@ -25,7 +25,9 @@ * "modes" "+iok"; * "toplevel_access" "600"; * "fallback_other_assignment" "1"; //fall back to another assignment when active assignment gets removed + * "manager_can_rename_toplevel" "0"; //managers of a toplevel group may rename the whole group * "manager_can_del_toplevel" "0"; //managers of a toplevel group may delete the whole group + * "manager_can_rename_secondlevel" "0"; //managers of a secondlevel group may rename the whole group * "manager_can_del_secondlevel" "0"; //managers of a secondlevel group may delete the whole group * }; * }; @@ -83,6 +85,7 @@ static const struct message_entry msgtab[] = { { "HSMSG_FAKEHOST_SECONDLEVEL_ADDED", "Group $b%s.%s$b successfully added." }, { "HSMSG_FAKEHOST_SECONDLEVEL_ALREADY_EXISTS", "Group $b%s.%s$b already exists." }, { "HSMSG_FAKEHOST_SECONDLEVEL_DELETED", "Group $b%s.%s$b successfully deleted." }, + { "HSMSG_FAKEHOST_RENAMED", "Group $b%s.%s$b renamed to $b%s.%s$b." }, { "HSMSG_MANAGER_ALREADY", "$b%s$b is already a manager of %s.%s" }, { "HSMSG_MANAGER_ADDED", "$b%s$b is now a manager of %s.%s" }, { "HSMSG_MANAGER_NOT", "$b%s$b is not a manager of %s.%s" }, @@ -101,6 +104,8 @@ static struct { int fallback_other_assignment : 1; int manager_can_del_toplevel : 1; int manager_can_del_secondlevel : 1; + int manager_can_rename_toplevel : 1; + int manager_can_rename_secondlevel : 1; } hostserv_conf; const char *hostserv_module_deps[] = { NULL }; @@ -157,6 +162,7 @@ static void hs_del_secondlevel(struct hs_secondlevel *slfh, int remove_from_tlfh static void hs_del_manager(struct hs_manager *manager, int remove_from_object); static void hs_del_assignment(struct hs_assignment *assignment, int remove_from_slfh); static void hs_del_user(struct hs_user *user); +static void hs_activate_assignment(struct hs_user *user, struct hs_assignment *assignment); static void hs_free_all() { struct hs_toplevel *tlfh, *next_tlfh; @@ -229,6 +235,23 @@ static void hs_del_toplevel(struct hs_toplevel *tlfh) { free(tlfh); } +static void hs_rename_toplevel(struct hs_toplevel *tlfh, const char *name) { + struct hs_secondlevel *slfh; + struct hs_assignment *assng; + + free(tlfh->fakehost); + tlfh->fakehost = strdup(name); + + //trigger rename for all assignments + for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { + for(assng = slfh->assignments; assng; assng = assng->next) { + if(assng->active) { + hs_activate_assignment(assng->user, assng); + } + } + } +} + static struct hs_secondlevel *hs_add_secondlevel(struct hs_toplevel *tlfh, const char *name) { struct hs_secondlevel *slfh = calloc(1, sizeof(*slfh)); slfh->toplevel = tlfh; @@ -266,6 +289,20 @@ static void hs_del_secondlevel(struct hs_secondlevel *slfh, int remove_from_tlfh free(slfh); } +static void hs_rename_secondlevel(struct hs_secondlevel *slfh, const char *name) { + struct hs_assignment *assng; + + free(slfh->fakehost); + slfh->fakehost = strdup(name); + + //trigger rename for all assignments + for(assng = slfh->assignments; assng; assng = assng->next) { + if(assng->active) { + hs_activate_assignment(assng->user, assng); + } + } +} + static struct hs_manager *hs_add_manager_toplevel(struct hs_toplevel *tlfh, struct hs_user *user) { struct hs_manager *manager = calloc(1, sizeof(*manager)); manager->user = user; @@ -586,6 +623,10 @@ static MODCMD_FUNC(cmd_view) { } char *slfh_name = argv[1]; char *tlfh_name = strchr(argv[1], '.'); + if(!tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", slfh_name); + return 0; + } *tlfh_name = '\0'; tlfh_name++; if(strchr(tlfh_name, '.')) { @@ -800,6 +841,105 @@ static MODCMD_FUNC(cmd_delhost) { return 1; } +static MODCMD_FUNC(cmd_renamehost) { + struct handle_info *hi; + if (!(hi = user->handle_info)) { + reply("NSMSG_MUST_AUTH"); + return 0; + } + //old fakehost name + char *slfh_name = argv[1]; + char *tlfh_name = strchr(argv[1], '.'); + if(!tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", slfh_name); + return 0; + } + *tlfh_name = '\0'; + tlfh_name++; + if(strchr(tlfh_name, '.')) { + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + return 0; + } + struct hs_toplevel *tlfh; + for(tlfh = toplevels; tlfh; tlfh = tlfh->next) { + if(!irccasecmp(tlfh->fakehost, tlfh_name)) break; + } + if(!tlfh) { + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + return 0; + } + //new fakehost name + char *new_slfh_name = argv[2]; + char *new_tlfh_name = strchr(argv[2], '.'); + if(!new_tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", new_slfh_name); + return 0; + } + *new_tlfh_name = '\0'; + new_tlfh_name++; + if(strchr(new_tlfh_name, '.')) { + new_tlfh_name--; + *new_tlfh_name = '.'; + reply("HSMSG_TOPLEVEL_INVALID", new_slfh_name); + return 0; + } + if(!irccasecmp(slfh_name, "*")) { + if(!check_management_access(hi, (hostserv_conf.manager_can_rename_toplevel ? tlfh : NULL), NULL)) { /* manager access is enough to delete whole toplevel? */ + reply("HSMSG_ACCESS_DENIED"); + return 0; + } + if(irccasecmp(new_slfh_name, "*")) { + //can't rename toplevel into secondlevel fakehost! + new_tlfh_name--; + *new_tlfh_name = '.'; + reply("HSMSG_TOPLEVEL_INVALID", new_slfh_name); + return 0; + } + struct hs_toplevel *ctlfh; + for(ctlfh = toplevels; ctlfh; ctlfh = ctlfh->next) { + if(!irccasecmp(ctlfh->fakehost, new_tlfh_name)) break; + } + if(ctlfh) { + reply("HSMSG_FAKEHOST_TOPLEVEL_ALREADY_EXISTS", new_slfh_name, new_tlfh_name); + return 0; + } + if(strcmp(new_tlfh_name, tlfh->fakehost)) + hs_rename_toplevel(tlfh, new_tlfh_name); + reply("HSMSG_FAKEHOST_RENAMED", slfh_name, tlfh_name, new_slfh_name, new_tlfh_name); + } else { + struct hs_secondlevel *slfh; + for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { + if(!irccasecmp(slfh->fakehost, slfh_name)) break; + } + if(!slfh) { + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + return 0; + } + if(!check_management_access(hi, tlfh, (hostserv_conf.manager_can_rename_secondlevel ? slfh : NULL))) { + reply("HSMSG_ACCESS_DENIED"); + return 0; + } + if(irccasecmp(new_tlfh_name, tlfh_name)) { + //can't rename toplevel and secondlevel fakehost with one command! + new_tlfh_name--; + *new_tlfh_name = '.'; + reply("HSMSG_TOPLEVEL_INVALID", new_slfh_name); + } + struct hs_secondlevel *cslfh; + for(cslfh = tlfh->secondlevel; cslfh; cslfh = cslfh->next) { + if(!irccasecmp(cslfh->fakehost, new_slfh_name)) break; + } + if(cslfh) { + reply("HSMSG_FAKEHOST_SECONDLEVEL_ALREADY_EXISTS", new_slfh_name, new_tlfh_name); + return 0; + } + if(strcmp(new_slfh_name, slfh->fakehost)) + hs_rename_secondlevel(slfh, new_slfh_name); + reply("HSMSG_FAKEHOST_RENAMED", slfh_name, tlfh_name, new_slfh_name, new_tlfh_name); + } + return 1; +} + static MODCMD_FUNC(cmd_addmanager) { struct handle_info *hi; char *fakehost; @@ -815,6 +955,10 @@ static MODCMD_FUNC(cmd_addmanager) { } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); + if(!tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", slfh_name); + return 0; + } *tlfh_name = '\0'; tlfh_name++; if(strchr(tlfh_name, '.')) { @@ -888,10 +1032,8 @@ static MODCMD_FUNC(cmd_delmanager) { } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); - if(tlfh_name) { - *tlfh_name = '\0'; - } else { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, ""); + if(!tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", slfh_name); return 0; } tlfh_name++; @@ -1018,10 +1160,8 @@ static MODCMD_FUNC(cmd_assign) { } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); - if(tlfh_name) { - *tlfh_name = '\0'; - } else { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, ""); + if(!tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", slfh_name); return 0; } tlfh_name++; @@ -1073,10 +1213,8 @@ static MODCMD_FUNC(cmd_unassign) { } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); - if(tlfh_name) { - *tlfh_name = '\0'; - } else { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, ""); + if(!tlfh_name) { + reply("HSMSG_TOPLEVEL_INVALID", slfh_name); return 0; } tlfh_name++; @@ -1139,6 +1277,12 @@ static void hostserv_conf_read(void) { str = database_get_data(conf_node, "manager_can_del_secondlevel", RECDB_QSTRING); hostserv_conf.manager_can_del_secondlevel = (atoi(str) ? 1 : 0); + str = database_get_data(conf_node, "manager_can_rename_toplevel", RECDB_QSTRING); + hostserv_conf.manager_can_rename_toplevel = (atoi(str) ? 1 : 0); + + str = database_get_data(conf_node, "manager_can_rename_secondlevel", RECDB_QSTRING); + hostserv_conf.manager_can_rename_secondlevel = (atoi(str) ? 1 : 0); + /*str = database_get_data(conf_node, "description", RECDB_QSTRING); hostserv_conf.description = (str ? str : NULL);*/ } @@ -1325,6 +1469,7 @@ int hostserv_init() { modcmd_register(hostserv_module, "unassign", cmd_unassign, 3, MODCMD_REQUIRE_AUTHED, NULL); modcmd_register(hostserv_module, "addhost", cmd_addhost, 2, MODCMD_REQUIRE_AUTHED, NULL); modcmd_register(hostserv_module, "delhost", cmd_delhost, 2, MODCMD_REQUIRE_AUTHED, NULL); + modcmd_register(hostserv_module, "renamehost", cmd_renamehost, 3, MODCMD_REQUIRE_AUTHED, NULL); message_register_table(msgtab); return 1; } -- 2.20.1