X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmod-hostserv.c;h=8e1ee36e3b08cc4c122078d7e541a85721aca1cd;hb=648ed0b405683a26b2eb69af2063811cec84236f;hp=da02cbb6c431afd111b882124a78e2ea5fc33d17;hpb=db71854cc3332f6aefdf6c14c25aeff4315f8a36;p=srvx.git diff --git a/src/mod-hostserv.c b/src/mod-hostserv.c index da02cbb..8e1ee36 100644 --- a/src/mod-hostserv.c +++ b/src/mod-hostserv.c @@ -23,10 +23,16 @@ * "hostserv" { * "nick" "HostServ"; * "modes" "+iok"; - "toplevel_access" "600"; + * "toplevel_access" "600"; + * "fallback_other_assignment" "1"; //fall back to another assignment when active assignment gets removed + * "manager_can_del_toplevel" "0"; //managers of a toplevel group may delete the whole group + * "manager_can_del_secondlevel" "0"; //managers of a secondlevel group may delete the whole group * }; * }; * + * After you started srvx make the bot active: + /msg opserv bind hostserv * hostserv.* + /msg opserv bind hostserv help *modcmd.help */ #include "chanserv.h" @@ -36,16 +42,15 @@ #include "modcmd.h" #include "saxdb.h" #include "timeq.h" -#include "gline.h" #define KEY_TOPLEVEL "TopLevel" #define KEY_SECONDLEVEL "SecondLevel" #define KEY_MANAGERS "Manager" #define KEY_ASSIGNMENTS "Assignments" #define KEY_ACTIVE "active" -#define KEY_TITLEHOST_SUFFIX "title_suffix" static const struct message_entry msgtab[] = { + { "HSMSG_ACCESS_DENIED", "Access denied." }, { "HSMSG_ASSIGNED_FAKEHOSTS", "Assigned Fakehosts for User $b%s$b:" }, { "HSMSG_ASSIGNED_FAKEHOST", " $b%s.%s$b" }, { "HSMSG_ASSIGNED_FAKEHOST_ACTTIVE", " $b%s.%s$b (active)" }, @@ -58,7 +63,6 @@ static const struct message_entry msgtab[] = { { "HSMSG_MANAGED_FAKEHOST", " $b%s.%s$b assignments: %d" }, { "HSMSG_MANAGE_HOWTO", "Use $bview xxx.yyy$b to view more information about a fakehost group." }, { "HSMSG_UNKNOWN_FAKEHOST", "Fakehost $b%s.%s$b is unknown or you have no access to manage it." }, - { "HSMSG_UNKNOWN_FAKEHOST_TOPLEVEL", "Fakehost $b%s$b is unknown or you have no access to manage it." }, { "HSMSG_TOPLEVEL_FAKEHOSTS", "Fakehosts in group $b*.%s$b:" }, { "HSMSG_TOPLEVEL_FAKEHOST", " $b%s.%s$b assignments: %d managers: %d" }, { "HSMSG_TOPLEVEL_INVALID", "The name of the group you entered is invalid ($b%s$b)" }, @@ -80,7 +84,8 @@ static const struct message_entry msgtab[] = { { "HSMSG_MANAGER_NOT", "$b%s$b is not a manager of %s.%s" }, { "HSMSG_MANAGER_DELETED", "$b%s$b is no longer a manager of %s.%s" }, { "HSMSG_FAKEHOST_ASSIGN_SUCCESS", "Group $b%s.%s$b was assigned successfully." }, - { "HSMSG_FAKEHOST_REVOKE_SUCCESS", "Group $b%s.%s$b was revoked successfully." }, + { "HSMSG_FAKEHOST_ASSIGNED", "Group $b%s.%s$b is already assigned to the user." }, + { "HSMSG_FAKEHOST_UNASSIGN_SUCCESS", "Group $b%s.%s$b was unassigned successfully." }, { NULL, NULL } }; @@ -89,6 +94,9 @@ static struct { const char *nick; const char *modes; int toplevel_access; + int fallback_other_assignment : 1; + int manager_can_del_toplevel : 1; + int manager_can_del_secondlevel : 1; } hostserv_conf; const char *hostserv_module_deps[] = { NULL }; @@ -99,7 +107,6 @@ static struct service *hostserv_service; static struct log_type *HS_LOG; static struct hs_toplevel *toplevels = NULL; static struct hs_user *hostserv_users = NULL; -const char *title_suffix = NULL; /* FAKEHOST STRUCTS */ struct hs_toplevel { @@ -147,67 +154,6 @@ 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 apply_fakehost(struct handle_info *handle, struct userNode *user); - -static char * -generate_fakehost(struct handle_info *handle) -{ - extern const char *hidden_host_suffix; - static char buffer[HOSTLEN+1]; - - if (!handle->fakehost) { - snprintf(buffer, sizeof(buffer), "%s.%s", handle->handle, hidden_host_suffix); - return buffer; - } else if (handle->fakehost[0] == '.') { - /* A leading dot indicates the stored value is actually a title. */ - snprintf(buffer, sizeof(buffer), "%s.%s.%s", handle->handle, handle->fakehost+1, title_suffix); - return buffer; - } else if (handle->fakehost[0] == '$') { - /* A leading $ indicates the stored value begins with the user handle. */ - snprintf(buffer, sizeof(buffer), "%s%s", handle->handle, handle->fakehost+1); - return buffer; - } - return handle->fakehost; -} - -static char * -generate_fakeident(struct handle_info *handle, struct userNode *user) -{ - static char buffer[USERLEN+1]; - - if (!handle->fakeident) { - if (!user) - return NULL; - safestrncpy(buffer, user->ident, sizeof(buffer)); - return buffer; - } - return handle->fakeident; -} - -static void -apply_fakehost(struct handle_info *handle, struct userNode *user) -{ - struct userNode *target; - char *fakehost, *fakeident; - - if (!handle->users) - return; - - fakehost = generate_fakehost(handle); - - if (user) { - fakeident = generate_fakeident(handle, user); - assign_fakehost(user, fakehost, fakeident, 0, 1); - return; - } - - for (target = handle->users; target; target = target->next_authed) { - fakeident = generate_fakeident(handle, target); - assign_fakehost(target, fakehost, fakeident, 0, 1); - } - return; -} - static void hs_free_all() { struct hs_toplevel *tlfh, *next_tlfh; struct hs_secondlevel *slfh, *next_slfh; @@ -222,7 +168,7 @@ static void hs_free_all() { } for(slfh = tlfh->secondlevel; slfh; slfh = next_slfh) { next_slfh = slfh->next; - for(manager = tlfh->managers; manager; manager = next_manager) { + for(manager = slfh->managers; manager; manager = next_manager) { next_manager = manager->next; free(manager); } @@ -387,26 +333,33 @@ static void hs_del_manager(struct hs_manager *manager, int remove_from_object) { free(manager); } -static void activateAssignment(struct hs_assignment *assignment) { +static void hs_activate_assignment(struct hs_user *user, struct hs_assignment *assignment) { struct hs_toplevel *tlfh; struct hs_secondlevel *slfh; - struct hs_user *hs_user; struct hs_assignment *assgn; - char fakehost[140]; - char *prefix = "$"; + char fakehost[HOSTLEN]; + + assert((!assignment || (assignment->user == user))); - hs_user = assignment->user; - if(hs_user->assignments) { - for(assgn = hs_user->assignments; assgn; assgn = assgn->unext) { + if(user->assignments) { + for(assgn = user->assignments; assgn; assgn = assgn->unext) assgn->active = 0; - } } - slfh = assignment->secondlevel; - tlfh = slfh->toplevel; - sprintf(fakehost, "%s.%s.%s", prefix, slfh->fakehost, tlfh->fakehost); - hs_user->hi->fakehost = strdup(fakehost); - apply_fakehost(hs_user->hi, NULL); - assignment->active = 1; + + if(user->hi->fakehost) { + free(user->hi->fakehost); + user->hi->fakehost = NULL; + } + + if(assignment) { + slfh = assignment->secondlevel; + tlfh = slfh->toplevel; + snprintf(fakehost, sizeof(fakehost), "$.%s.%s", slfh->fakehost, tlfh->fakehost); + user->hi->fakehost = strdup(fakehost); + assignment->active = 1; + } + + apply_fakehost(user->hi, NULL); } static struct hs_assignment *hs_add_assignment(struct hs_secondlevel *slfh, struct hs_user *user) { @@ -420,7 +373,7 @@ static struct hs_assignment *hs_add_assignment(struct hs_secondlevel *slfh, stru assignment->unext = user->assignments; user->assignments = assignment; if(assignment->active) { - activateAssignment(assignment); + hs_activate_assignment(user, assignment); } return assignment; } @@ -452,20 +405,38 @@ static void hs_del_assignment(struct hs_assignment *assignment, int remove_from_ } else prev_assignment = cassignment; } - if(assignment->user->managements == NULL && assignment->user->assignments == NULL) - hs_del_user(assignment->user); if(assignment->active) { - struct handle_info *hi; - - hi = assignment->user->hi; - hi->fakehost = NULL; - apply_fakehost(hi, NULL); + /* use another assignment - or fall back to default user host? */ + cassignment = NULL; + if(hostserv_conf.fallback_other_assignment && assignment->user->assignments) { + /* try to find another assignment from same slfh first */ + for(cassignment = assignment->secondlevel->assignments; cassignment; cassignment = cassignment->next) { + if(cassignment != assignment && cassignment->user == assignment->user) + break; + } + /* use another tlfh assignment */ + if(!cassignment) + cassignment = assignment->user->assignments; + } + hs_activate_assignment(assignment->user, cassignment); } + + if(assignment->user->managements == NULL && assignment->user->assignments == NULL) + hs_del_user(assignment->user); } free(assignment); } +static struct hs_assignment *hs_get_assignment(struct hs_secondlevel *slfh, struct hs_user *user) { + struct hs_assignment *cassignment; + for(cassignment = slfh->assignments; cassignment; cassignment = cassignment->next) { + if(cassignment->user == user) + return cassignment; + } + return NULL; +} + static struct hs_user *hs_get_user(struct handle_info *hi, int create) { struct hs_user *cuser; for(cuser = hostserv_users; cuser; cuser = cuser->next) { @@ -597,112 +568,6 @@ static void cmd_view_secondlevel_information(UNUSED_ARG(struct userNode *user), } } -static MODCMD_FUNC(cmd_addhost) { - struct handle_info *hi; - if (!(hi = user->handle_info)) { - reply("NSMSG_MUST_AUTH"); - return 0; - } - 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; - } - if(!irccasecmp(slfh_name, "*")) { - if(hi->opserv_level >= hostserv_conf.toplevel_access) { - struct hs_toplevel *tlfh; - for(tlfh = toplevels; tlfh; tlfh = tlfh->next) { - if(!irccasecmp(tlfh->fakehost, tlfh_name)) break; - } - if(tlfh) { - reply("HSMSG_FAKEHOST_TOPLEVEL_ALREADY_EXISTS", slfh_name, tlfh_name); - return 0; - } - hs_add_toplevel(tlfh_name); - reply("HSMSG_FAKEHOST_TOPLEVEL_ADDED", tlfh_name); - return 1; - } - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); - return 0; - } else { - struct hs_secondlevel *slfh; - 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; - } - 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, NULL)) { - reply("HSMSG_FAKEHOST_SECONDLEVEL_ALREADY_EXISTS", slfh_name, tlfh_name); - return 0; - } - hs_add_secondlevel(tlfh, slfh_name); - reply("HSMSG_FAKEHOST_SECONDLEVEL_ADDED", slfh_name, tlfh_name); - } - return 0; -} - -static MODCMD_FUNC(cmd_delhost) { - struct handle_info *hi; - if (!(hi = user->handle_info)) { - reply("NSMSG_MUST_AUTH"); - return 0; - } - char *slfh_name = argv[1]; - char *tlfh_name = strchr(argv[1], '.'); - *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; - } - if(!irccasecmp(slfh_name, "*")) { - if(hi->opserv_level < hostserv_conf.toplevel_access) { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); - return 0; - } - hs_del_toplevel(tlfh); - reply("HSMSG_FAKEHOST_TOPLEVEL_DELETED", tlfh_name); - return 1; - } else { - struct hs_secondlevel *slfh; - for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { - if(!irccasecmp(slfh->fakehost, slfh_name)) break; - } - if(!slfh || !check_management_access(hi, tlfh, NULL)) { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); - return 0; - } - hs_del_secondlevel(slfh, 1); - reply("HSMSG_FAKEHOST_SECONDLEVEL_DELETED", slfh_name, tlfh_name); - } - return 0; -} - static MODCMD_FUNC(cmd_view) { struct handle_info *hi; if(argc >= 2 && !strchr(argv[1], '.')) { @@ -822,6 +687,113 @@ static MODCMD_FUNC(cmd_view) { return 1; } +static MODCMD_FUNC(cmd_addhost) { + struct handle_info *hi; + struct hs_toplevel *tlfh; + struct hs_secondlevel *slfh; + if (!(hi = user->handle_info)) { + reply("NSMSG_MUST_AUTH"); + return 0; + } + 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; + } + if(!irccasecmp(slfh_name, "*")) { + if(!check_management_access(hi, NULL, NULL)) { + reply("HSMSG_ACCESS_DENIED"); + return 0; + } + for(tlfh = toplevels; tlfh; tlfh = tlfh->next) { + if(!irccasecmp(tlfh->fakehost, tlfh_name)) break; + } + if(tlfh) { + reply("HSMSG_FAKEHOST_TOPLEVEL_ALREADY_EXISTS", slfh_name, tlfh_name); + return 0; + } + hs_add_toplevel(tlfh_name); + reply("HSMSG_FAKEHOST_TOPLEVEL_ADDED", tlfh_name); + } else { + 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; + } + if(!check_management_access(hi, tlfh, NULL)) { + reply("HSMSG_ACCESS_DENIED"); + return 0; + } + for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { + if(!irccasecmp(slfh->fakehost, slfh_name)) break; + } + if(slfh) { + reply("HSMSG_FAKEHOST_SECONDLEVEL_ALREADY_EXISTS", slfh_name, tlfh_name); + return 0; + } + hs_add_secondlevel(tlfh, slfh_name); + reply("HSMSG_FAKEHOST_SECONDLEVEL_ADDED", slfh_name, tlfh_name); + } + return 1; +} + +static MODCMD_FUNC(cmd_delhost) { + struct handle_info *hi; + if (!(hi = user->handle_info)) { + reply("NSMSG_MUST_AUTH"); + return 0; + } + char *slfh_name = argv[1]; + char *tlfh_name = strchr(argv[1], '.'); + *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; + } + if(!irccasecmp(slfh_name, "*")) { + if(!check_management_access(hi, (hostserv_conf.manager_can_del_toplevel ? tlfh : NULL), NULL)) { /* manager access is enough to delete whole toplevel? */ + reply("HSMSG_ACCESS_DENIED"); + return 0; + } + hs_del_toplevel(tlfh); + reply("HSMSG_FAKEHOST_TOPLEVEL_DELETED", 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_del_secondlevel ? slfh : NULL))) { + reply("HSMSG_ACCESS_DENIED"); + return 0; + } + hs_del_secondlevel(slfh, 1); + reply("HSMSG_FAKEHOST_SECONDLEVEL_DELETED", slfh_name, tlfh_name); + } + return 1; +} + static MODCMD_FUNC(cmd_addmanager) { struct handle_info *hi; char *fakehost; @@ -854,17 +826,21 @@ static MODCMD_FUNC(cmd_addmanager) { } if(!irccasecmp(slfh_name, "*")) { if(!check_management_access(user->handle_info, tlfh, NULL)) { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + reply("HSMSG_ACCESS_DENIED"); return 0; } } else { for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { if(!irccasecmp(slfh->fakehost, slfh_name)) break; } - if(!slfh || !check_management_access(user->handle_info, tlfh, slfh)) { + if(!slfh) { reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); return 0; } + if(!check_management_access(user->handle_info, tlfh, slfh)) { + reply("HSMSG_ACCESS_DENIED"); + return 0; + } } struct hs_user *huser = hs_get_user(hi, 1); struct hs_manager *manager; @@ -904,16 +880,12 @@ static MODCMD_FUNC(cmd_delmanager) { return 0; fakehost = argv[1]; } - if(!fakehost) { - reply("HSMSG_ASSIGNED_NONE"); - return 0; - } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); if(tlfh_name) { *tlfh_name = '\0'; } else { - reply("HSMSG_ASSIGNED_NONE"); + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, ""); return 0; } tlfh_name++; @@ -932,17 +904,21 @@ static MODCMD_FUNC(cmd_delmanager) { } if(!irccasecmp(slfh_name, "*")) { if(!check_management_access(user->handle_info, tlfh, NULL)) { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + reply("HSMSG_ACCESS_DENIED"); return 0; } } else { for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { if(!irccasecmp(slfh->fakehost, slfh_name)) break; } - if(!slfh || !check_management_access(user->handle_info, tlfh, slfh)) { + if(!slfh) { reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); return 0; } + if(!check_management_access(user->handle_info, tlfh, slfh)) { + reply("HSMSG_ACCESS_DENIED"); + return 0; + } } struct hs_user *huser = hs_get_user(hi, 0); struct hs_manager *manager; @@ -978,7 +954,6 @@ static MODCMD_FUNC(cmd_set) { struct handle_info *hi; struct hs_user *hs_user; struct hs_assignment *assignment; - struct hs_assignment *assgn; struct hs_toplevel *tlfh; struct hs_secondlevel *slfh; char *fakehost; @@ -988,37 +963,30 @@ static MODCMD_FUNC(cmd_set) { return 0; } hs_user = hs_get_user(hi, 0); + if(!hs_user) + return 0; //nothing to do here if(!strcmp(argv[1], "*")) { - hi->fakehost = NULL; - apply_fakehost(hi, NULL); - if(hs_user->assignments) { - for(assgn = hs_user->assignments; assgn; assgn = assgn->unext) { - assgn->active = 0; - } - } + hs_activate_assignment(hs_user, NULL); return 1; } else { - if(!strchr(argv[1], '.')) { - return 0; - } fakehost = argv[1]; char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); - *tlfh_name = '\0'; - tlfh_name++; - if(strchr(tlfh_name, '.')) { - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + if(tlfh_name) { + *tlfh_name = '\0'; + tlfh_name++; + } + if(!tlfh_name || strchr(tlfh_name, '.')) { + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, (tlfh_name ? tlfh_name : "")); return 0; } for(assignment = hs_user->assignments; assignment; assignment = assignment->unext) { slfh = assignment->secondlevel; tlfh = slfh->toplevel; - if(!irccasecmp(slfh_name, slfh->fakehost)) { - if(!irccasecmp(tlfh_name, tlfh->fakehost)) { - activateAssignment(assignment); - reply("HSMSG_FAKEHOST_SET_SUCCESS", slfh->fakehost, tlfh->fakehost); - return 1; - } + if(!irccasecmp(tlfh_name, tlfh->fakehost) && !irccasecmp(slfh_name, slfh->fakehost)) { + hs_activate_assignment(hs_user, assignment); + reply("HSMSG_FAKEHOST_SET_SUCCESS", slfh->fakehost, tlfh->fakehost); + return 1; } } reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); @@ -1028,7 +996,6 @@ static MODCMD_FUNC(cmd_set) { static MODCMD_FUNC(cmd_assign) { struct handle_info *hi; - struct handle_info *hiuser; char *fakehost; if(!strchr(argv[1], '.')) { if (!(hi = modcmd_get_handle_info(user, argv[1]))) @@ -1039,20 +1006,16 @@ static MODCMD_FUNC(cmd_assign) { return 0; fakehost = argv[1]; } - if (!(hiuser = user->handle_info)) { + if (!user->handle_info) { reply("NSMSG_MUST_AUTH"); return 0; } - if(!fakehost) { - reply("HSMSG_ASSIGNED_NONE"); - return 0; - } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); if(tlfh_name) { *tlfh_name = '\0'; } else { - reply("HSMSG_ASSIGNED_NONE"); + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, ""); return 0; } tlfh_name++; @@ -1060,20 +1023,24 @@ static MODCMD_FUNC(cmd_assign) { reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); return 0; } - struct hs_toplevel *tlfh;; + struct hs_toplevel *tlfh; struct hs_secondlevel *slfh; struct hs_user *hs_user = hs_get_user(hi, 1); for(tlfh = toplevels; tlfh; tlfh = tlfh->next) { if(!irccasecmp(tlfh_name, tlfh->fakehost)) { for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) { if(!irccasecmp(slfh_name, slfh->fakehost)) { - if(check_management_access(hiuser, tlfh, slfh)) { - hs_add_assignment(slfh, hs_user); - reply("HSMSG_FAKEHOST_ASSIGN_SUCCESS", slfh_name, tlfh_name); - return 1; + if(!check_management_access(user->handle_info, tlfh, slfh)) { + reply("HSMSG_ACCESS_DENIED"); + return 0; } - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); - return 0; + if(hs_get_assignment(slfh, hs_user)) { + reply("HSMSG_FAKEHOST_ASSIGNED", slfh_name, tlfh_name); + return 0; + } + hs_add_assignment(slfh, hs_user); + reply("HSMSG_FAKEHOST_ASSIGN_SUCCESS", slfh_name, tlfh_name); + return 1; } } } @@ -1082,9 +1049,8 @@ static MODCMD_FUNC(cmd_assign) { return 0; } -static MODCMD_FUNC(cmd_revoke) { +static MODCMD_FUNC(cmd_unassign) { struct handle_info *hi; - struct handle_info *hiuser; char *fakehost; if(!strchr(argv[1], '.')) { if (!(hi = modcmd_get_handle_info(user, argv[1]))) @@ -1095,20 +1061,16 @@ static MODCMD_FUNC(cmd_revoke) { return 0; fakehost = argv[1]; } - if (!(hiuser = user->handle_info)) { + if (!user->handle_info) { reply("NSMSG_MUST_AUTH"); return 0; } - if(!fakehost) { - reply("HSMSG_ASSIGNED_NONE"); - return 0; - } char *slfh_name = fakehost; char *tlfh_name = strchr(fakehost, '.'); if(tlfh_name) { *tlfh_name = '\0'; } else { - reply("HSMSG_ASSIGNED_NONE"); + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, ""); return 0; } tlfh_name++; @@ -1118,16 +1080,20 @@ static MODCMD_FUNC(cmd_revoke) { } struct hs_assignment *assignment; struct hs_user *hs_user = hs_get_user(hi, 0); + if(!hs_user) { + reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); + return 0; + } for(assignment = hs_user->assignments; assignment; assignment = assignment->unext) { if(!irccasecmp(slfh_name, assignment->secondlevel->fakehost)) { if(!irccasecmp(tlfh_name, assignment->secondlevel->toplevel->fakehost)) { - if(check_management_access(hi, assignment->secondlevel->toplevel, assignment->secondlevel)) { - hs_del_assignment(assignment, 1); - reply("HSMSG_FAKEHOST_REVOKE_SUCCESS", slfh_name, tlfh_name); - return 1; + if(!check_management_access(user->handle_info, assignment->secondlevel->toplevel, assignment->secondlevel)) { + reply("HSMSG_ACCESS_DENIED"); + return 0; } - reply("HSMSG_UNKNOWN_FAKEHOST", slfh_name, tlfh_name); - return 0; + hs_del_assignment(assignment, 1); + reply("HSMSG_FAKEHOST_UNASSIGN_SUCCESS", slfh_name, tlfh_name); + return 1; } } } @@ -1135,8 +1101,7 @@ static MODCMD_FUNC(cmd_revoke) { return 0; } -static void hostserv_conf_read(void) -{ +static void hostserv_conf_read(void) { dict_t conf_node; const char *str; @@ -1159,10 +1124,17 @@ static void hostserv_conf_read(void) unsigned int toplevel_access = atoi(str); hostserv_conf.toplevel_access = (toplevel_access ? toplevel_access : 600); + str = database_get_data(conf_node, "fallback_other_assignment", RECDB_QSTRING); + hostserv_conf.fallback_other_assignment = (atoi(str) ? 1 : 0); + + str = database_get_data(conf_node, "manager_can_del_toplevel", RECDB_QSTRING); + hostserv_conf.manager_can_del_toplevel = (atoi(str) ? 1 : 0); + + 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, "description", RECDB_QSTRING); hostserv_conf.description = (str ? str : NULL);*/ - str = database_get_data(conf_node, KEY_TITLEHOST_SUFFIX, RECDB_QSTRING); - title_suffix = str ? str : "example.net"; } static int hostserv_saxdb_read_secondlevel(const char *name, void *data, UNUSED_ARG(void *extra)); @@ -1347,7 +1319,7 @@ int hostserv_init() { modcmd_register(hostserv_module, "delmanager", cmd_delmanager, 3, MODCMD_REQUIRE_AUTHED, NULL); modcmd_register(hostserv_module, "set", cmd_set, 2, MODCMD_REQUIRE_AUTHED, NULL); modcmd_register(hostserv_module, "assign", cmd_assign, 3, MODCMD_REQUIRE_AUTHED, NULL); - modcmd_register(hostserv_module, "revoke", cmd_revoke, 3, MODCMD_REQUIRE_AUTHED, NULL); + 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); message_register_table(msgtab);