]> jfr.im git - solanum.git/blobdiff - modules/um_callerid.c
reference.conf: add drain_reason
[solanum.git] / modules / um_callerid.c
index 5aa50438b322725d69b743e05694715012435fbe..897435982064c7eadf7833c25b8d93ffec649198 100644 (file)
 #include "s_newconf.h"
 #include "hook.h"
 #include "supported.h"
+#include "logger.h"
 
 static int
 um_callerid_modinit(void)
 {
        user_modes['g'] = find_umode_slot();
+       if (!user_modes['g'])
+       {
+               ierror("um_callerid: unable to allocate usermode slot for +g; unloading module.");
+               return -1;
+       }
+
        user_modes['G'] = find_umode_slot();
+       if (!user_modes['G'])
+       {
+               user_modes['g'] = 0;
+
+               ierror("um_callerid: unable to allocate usermode slot for +G; unloading module.");
+               return -1;
+       }
+
        construct_umodebuf();
 
-       add_isupport("CALLERID", isupport_string, "g");
+       add_isupport("CALLERID", isupport_umode, "g");
 
        return 0;
 }
@@ -65,26 +80,12 @@ um_callerid_moddeinit(void)
        delete_isupport("CALLERID");
 }
 
-#define IsSetCallerID(c)       ((c->umodes & user_modes['g']) == user_modes['g'])
+#define IsSetStrictCallerID(c) ((c->umodes & user_modes['g']) == user_modes['g'])
 #define IsSetRelaxedCallerID(c)        ((c->umodes & user_modes['G']) == user_modes['G'])
+#define IsSetAnyCallerID(c)    (IsSetStrictCallerID(c) || IsSetRelaxedCallerID(c))
 
 static const char um_callerid_desc[] =
-       "Provides usermode +g which restricts messages from unauthorized users.";
-
-static bool
-has_common_channel(struct Client *source_p, struct Client *target_p)
-{
-       rb_dlink_node *ptr;
-
-       RB_DLINK_FOREACH(ptr, source_p->user->channel.head)
-       {
-               struct membership *msptr = ptr->data;
-               if (IsMember(target_p, msptr->chptr))
-                       return msptr->chptr;
-       }
-
-       return NULL;
-}
+       "Provides usermodes +g and +G which restrict messages from unauthorized users.";
 
 static bool
 allow_message(struct Client *source_p, struct Client *target_p)
@@ -92,17 +93,19 @@ allow_message(struct Client *source_p, struct Client *target_p)
        if (!MyClient(target_p))
                return true;
 
-       if (!IsSetCallerID(target_p))
+       if (!IsSetAnyCallerID(target_p))
                return true;
 
-       if (IsSetRelaxedCallerID(target_p) && has_common_channel(source_p, target_p))
+       if (!IsPerson(source_p))
                return true;
 
-       if (IsServer(source_p))
+       if (IsSetRelaxedCallerID(target_p) &&
+                       !IsSetStrictCallerID(target_p) &&
+                       has_common_channel(source_p, target_p))
                return true;
 
        /* XXX: controversial?  allow opers to send through +g */
-       if (IsOper(source_p))
+       if (MayHavePrivilege(source_p, "oper:message"))
                return true;
 
        if (accept_message(source_p, target_p))
@@ -121,7 +124,7 @@ send_callerid_notice(enum message_type msgtype, struct Client *source_p, struct
                return;
 
        sendto_one_numeric(source_p, ERR_TARGUMODEG, form_str(ERR_TARGUMODEG),
-               target_p->name);
+               target_p->name, IsSetStrictCallerID(target_p) ? "+g" : "+G");
 
        if ((target_p->localClient->last_caller_id_time + ConfigFileEntry.caller_id_wait) < rb_current_time())
        {
@@ -130,7 +133,7 @@ send_callerid_notice(enum message_type msgtype, struct Client *source_p, struct
 
                sendto_one(target_p, form_str(RPL_UMODEGMSG),
                           me.name, target_p->name, source_p->name,
-                          source_p->username, source_p->host);
+                          source_p->username, source_p->host, IsSetStrictCallerID(target_p) ? "+g" : "+G");
 
                target_p->localClient->last_caller_id_time = rb_current_time();
        }
@@ -139,6 +142,10 @@ send_callerid_notice(enum message_type msgtype, struct Client *source_p, struct
 static bool
 add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_p, struct Client *target_p)
 {
+       /* only do this on source_p's server */
+       if (!MyClient(source_p))
+               return true;
+
        /*
         * XXX: Controversial? Allow target users to send replies
         * through a +g.  Rationale is that people can presently use +g
@@ -146,9 +153,9 @@ add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_
         * as a way of griefing.  --nenolod
         */
        if(msgtype != MESSAGE_TYPE_NOTICE &&
-                       IsSetCallerID(source_p) &&
-                       !accept_message(target_p, source_p) &&
-                       !IsOper(target_p))
+               IsSetAnyCallerID(source_p) &&
+               !accept_message(target_p, source_p) &&
+               !IsOperGeneral(target_p))
        {
                if(rb_dlink_list_length(&source_p->localClient->allow_list) <
                                (unsigned long)ConfigFileEntry.max_accept)
@@ -160,7 +167,7 @@ add_callerid_accept_for_source(enum message_type msgtype, struct Client *source_
                {
                        sendto_one_numeric(source_p, ERR_OWNMODE,
                                        form_str(ERR_OWNMODE),
-                                       target_p->name, "+g");
+                                       target_p->name, IsSetStrictCallerID(target_p) ? "+g" : "+G");
                        return false;
                }
        }
@@ -174,6 +181,7 @@ h_hdl_invite(void *vdata)
        hook_data_channel_approval *data = vdata;
        struct Client *source_p = data->client;
        struct Client *target_p = data->target;
+       static char errorbuf[BUFSIZE];
 
        if (data->approved)
                return;
@@ -187,9 +195,11 @@ h_hdl_invite(void *vdata)
        if (allow_message(source_p, target_p))
                return;
 
-       send_callerid_notice(MESSAGE_TYPE_PRIVMSG, source_p, target_p);
+       snprintf(errorbuf, sizeof errorbuf, form_str(ERR_TARGUMODEG),
+                target_p->name, IsSetStrictCallerID(target_p) ? "+g" : "+G");
 
        data->approved = ERR_TARGUMODEG;
+       data->error = errorbuf;
 }
 
 static void