fix possible crash on user deletion
[srvx.git] / src / mod-hostserv.c
index 24de72dc7ee471bcd15e5100b0e81a9e2d90416f..3aeddfd306a743c59a31aa104fe4f6dd3875d3ac 100644 (file)
@@ -1281,17 +1281,10 @@ struct devnull_class hostserv_get_user_priv(struct handle_info *hi) {
     
     struct hs_user *huser = hs_get_user(hi, 0);
     if(huser) {
-        struct hs_assignment *assignment;
-        struct hs_secondlevel *slfh;
         struct devnull_class *devc;
-        for(assignment = huser->assignments; assignment; assignment = assignment->unext) {
-            slfh = assignment->secondlevel;
-            if(slfh->devnull_id) {
-                devc = devnull_find_id(slfh->devnull_id);
-                if(!devc) {
-                    slfh->devnull_id = 0;
-                    continue;
-                }
+        if(hi->devnull_id != 0) {
+            devc = devnull_find_id(huser->hi->devnull_id);
+            if(devc) {
                 if(DEVNULL_HAS_PRIV(devc, CHANLIMIT) && (!DEVNULL_HAS_PRIV(&th, CHANLIMIT) || th.maxchan < devc->maxchan))
                     th.maxchan = devc->maxchan;
                 if(DEVNULL_HAS_PRIV(devc, MAXSENDQ) && (!DEVNULL_HAS_PRIV(&th, MAXSENDQ) || th.maxsendq < devc->maxsendq))
@@ -1300,6 +1293,26 @@ struct devnull_class hostserv_get_user_priv(struct handle_info *hi) {
                 if(!th.name)
                     th.name = devc->name;
             }
+        } else {
+            struct hs_assignment *assignment;
+            struct hs_secondlevel *slfh;
+            for(assignment = huser->assignments; assignment; assignment = assignment->unext) {
+                slfh = assignment->secondlevel;
+                if(slfh->devnull_id) {
+                    devc = devnull_find_id(slfh->devnull_id);
+                    if(!devc) {
+                        slfh->devnull_id = 0;
+                        continue;
+                    }
+                    if(DEVNULL_HAS_PRIV(devc, CHANLIMIT) && (!DEVNULL_HAS_PRIV(&th, CHANLIMIT) || th.maxchan < devc->maxchan))
+                        th.maxchan = devc->maxchan;
+                    if(DEVNULL_HAS_PRIV(devc, MAXSENDQ) && (!DEVNULL_HAS_PRIV(&th, MAXSENDQ) || th.maxsendq < devc->maxsendq))
+                        th.maxsendq = devc->maxsendq;
+                    th.modes |= devc->modes;
+                    if(!th.name)
+                        th.name = devc->name;
+                }
+            }
         }
     }
     return th;
@@ -1517,6 +1530,13 @@ static void hostserv_db_cleanup(void) {
     hs_free_all();
 }
 
+static void hostserv_unreg_account(UNUSED_ARG(struct userNode *user), struct handle_info *handle) {
+    struct hs_user *huser = hs_get_user(handle, 0);
+    if (huser) {
+        hs_del_user(huser);
+    }
+}
+
 int hostserv_init() {
     HS_LOG = log_register_type("HostServ", "file:hostserv.log");
     
@@ -1529,6 +1549,7 @@ int hostserv_init() {
     }
         
     conf_register_reload(hostserv_conf_read);
+    reg_unreg_func(hostserv_unreg_account);
     reg_exit_func(hostserv_db_cleanup);
     saxdb_register("HostServ", hostserv_saxdb_read, hostserv_saxdb_write);
     hostserv_module = module_register("HostServ", HS_LOG, "mod-hostserv.help", NULL);