bugfix for double free error when you stop srvx
[srvx.git] / src / mod-hostserv.c
index 152eed0fb7333f055eec973140bdf3be2e3b7537..8e1ee36e3b08cc4c122078d7e541a85721aca1cd 100644 (file)
  *     "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
  *     };
  *  };
  *
@@ -39,7 +42,6 @@
 #include "modcmd.h"
 #include "saxdb.h"
 #include "timeq.h"
-#include "gline.h"
 
 #define KEY_TOPLEVEL "TopLevel"
 #define KEY_SECONDLEVEL "SecondLevel"
@@ -82,6 +84,7 @@ 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_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 }
@@ -165,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);
             }
@@ -339,7 +342,7 @@ static void hs_activate_assignment(struct hs_user *user, struct hs_assignment *a
     assert((!assignment || (assignment->user == user)));
     
     if(user->assignments) {
-        for(assgn = assignment->user->assignments; assgn; assgn = assgn->unext)
+        for(assgn = user->assignments; assgn; assgn = assgn->unext)
             assgn->active = 0;
     }
     
@@ -356,7 +359,7 @@ static void hs_activate_assignment(struct hs_user *user, struct hs_assignment *a
         assignment->active = 1;
     }
     
-    apply_fakehost(assignment->user->hi, NULL);
+    apply_fakehost(user->hi, NULL);
 }
 
 static struct hs_assignment *hs_add_assignment(struct hs_secondlevel *slfh, struct hs_user *user) {
@@ -707,7 +710,7 @@ static MODCMD_FUNC(cmd_addhost) {
     if(!irccasecmp(slfh_name, "*")) {
         if(!check_management_access(hi, NULL, NULL)) {
             reply("HSMSG_ACCESS_DENIED");
-            return NULL;
+            return 0;
         }
         for(tlfh = toplevels; tlfh; tlfh = tlfh->next) {
             if(!irccasecmp(tlfh->fakehost, tlfh_name)) break;
@@ -951,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;
@@ -967,9 +969,6 @@ static MODCMD_FUNC(cmd_set) {
         hs_activate_assignment(hs_user, NULL);
         return 1;
     } else {
-        if(!strchr(argv[1], '.')) {
-            
-        }
         fakehost = argv[1];
         char *slfh_name = fakehost;
         char *tlfh_name = strchr(fakehost, '.');
@@ -1035,6 +1034,10 @@ static MODCMD_FUNC(cmd_assign) {
                         reply("HSMSG_ACCESS_DENIED");
                         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;