Merge branch 'HostServ' of ssh://git.pk910.de:16110/srvx into HostServ
authorpk910 <philipp@zoelle1.de>
Fri, 4 Jan 2013 20:05:47 +0000 (21:05 +0100)
committerpk910 <philipp@zoelle1.de>
Fri, 4 Jan 2013 20:05:47 +0000 (21:05 +0100)
src/mod-hostserv.c
src/nickserv.c
src/nickserv.h

index 9084ac1d3158a6ff423255b525b59238dac8d55b..fbba68cb27893f073f10ab5f17c20b3a4cebfe61 100644 (file)
@@ -45,9 +45,9 @@
 #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)" },
@@ -90,6 +90,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 };
@@ -100,7 +103,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 {
@@ -148,67 +150,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;
@@ -388,26 +329,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];
     
-    hs_user = assignment->user;
-    if(hs_user->assignments) {
-        for(assgn = hs_user->assignments; assgn; assgn = assgn->unext) {
+    assert((!assignment || (assignment->user == user)));
+    
+    if(user->assignments) {
+        for(assgn = assignment->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(assignment->user->hi, NULL);
 }
 
 static struct hs_assignment *hs_add_assignment(struct hs_secondlevel *slfh, struct hs_user *user) {
@@ -421,7 +369,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;
 }
@@ -455,11 +403,19 @@ static void hs_del_assignment(struct hs_assignment *assignment, int remove_from_
         }
         
         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)
@@ -468,6 +424,15 @@ static void hs_del_assignment(struct hs_assignment *assignment, int remove_from_
     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) {
@@ -599,112 +564,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], '.')) {
@@ -824,6 +683,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 NULL;
+        }
+        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;
@@ -856,17 +822,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;
@@ -906,16 +876,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++;
@@ -934,17 +900,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;
@@ -990,37 +960,33 @@ 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);
@@ -1030,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])))
@@ -1041,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++;
@@ -1062,20 +1023,20 @@ 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;
+                    hs_add_assignment(slfh, hs_user);
+                    reply("HSMSG_FAKEHOST_ASSIGN_SUCCESS", slfh_name, tlfh_name);
+                    return 1;
                 }
             }
         }
@@ -1086,7 +1047,6 @@ static MODCMD_FUNC(cmd_assign) {
 
 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])))
@@ -1097,20 +1057,16 @@ static MODCMD_FUNC(cmd_unassign) {
             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++;
@@ -1120,16 +1076,20 @@ static MODCMD_FUNC(cmd_unassign) {
     }
     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(hiuser, assignment->secondlevel->toplevel, assignment->secondlevel)) {
-                    hs_del_assignment(assignment, 1);
-                    reply("HSMSG_FAKEHOST_UNASSIGN_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;
             }
         }
     }
@@ -1137,8 +1097,7 @@ static MODCMD_FUNC(cmd_unassign) {
     return 0;
 }
 
-static void hostserv_conf_read(void)
-{
+static void hostserv_conf_read(void) {
     dict_t conf_node;
     const char *str;
 
@@ -1161,10 +1120,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));
index 0912912634246227a9de839a9a6d44d25ec976b5..af25c3eba1a5ecdf84589eb4780169554d36d075 100644 (file)
@@ -988,7 +988,7 @@ reg_handle_rename_func(handle_rename_func_t func)
     rf_list[rf_list_used++] = func;
 }
 
-static char *
+char *
 generate_fakehost(struct handle_info *handle)
 {
     extern const char *hidden_host_suffix;
@@ -1009,7 +1009,7 @@ generate_fakehost(struct handle_info *handle)
     return handle->fakehost;
 }
 
-static char *
+char *
 generate_fakeident(struct handle_info *handle, struct userNode *user)
 {
     static char buffer[USERLEN+1];
@@ -1023,7 +1023,7 @@ generate_fakeident(struct handle_info *handle, struct userNode *user)
     return handle->fakeident;
 }
 
-static void
+void
 apply_fakehost(struct handle_info *handle, struct userNode *user)
 {
     struct userNode *target;
index 751e05988178c72f54ac9babd6fcfea7b39c05a2..bfe7c0bcacbceb7cdcbac97f70a4cdb51758e890 100644 (file)
@@ -158,6 +158,9 @@ struct handle_info *checklogin(const char *user, const char *pass, const char *n
 char *getfakehost(const char *user);
 void nickserv_devnull_delete(char *name);
 void nickserv_devnull_rename(char *oldname, char *newname);
+char *generate_fakehost(struct handle_info *handle);
+char *generate_fakeident(struct handle_info *handle, struct userNode *user);
+void apply_fakehost(struct handle_info *handle, struct userNode *user);
 
 /* auth_funcs are called when a user gets a new handle_info.  They are
  * called *after* user->handle_info has been updated.  */