diff --git a/help/opers/umode b/help/opers/umode index 3c78a53..d930b58 100644 --- a/help/opers/umode +++ b/help/opers/umode @@ -13,6 +13,7 @@ Usermodes: (* designates that the umode is oper only) * +l - Can see oper locops (local wallops). * +s - Can see server notices (see /quote help snomask). * +z - Can see operwalls. + * +p - Override -- implicit operator access in all channels. +B - Marks you as a bot in /whois. +C - Prevents you from receiving CTCPs other than ACTION. +D - Deaf - ignores all channel messages. diff --git a/include/channel.h b/include/channel.h index 4939ff9..c6a5de9 100644 --- a/include/channel.h +++ b/include/channel.h @@ -88,6 +88,7 @@ struct membership unsigned int flags; unsigned long bants; + unsigned long override_ts; }; #define BANLEN 195 @@ -114,6 +115,7 @@ struct ChModeChange int caps; int nocaps; int mems; + int override; struct Client *client; }; @@ -171,6 +173,7 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p, #define MODE_FREEINVITE 0x0800 /* allow free use of /invite */ #define MODE_FREETARGET 0x1000 /* can be forwarded to without authorization */ #define MODE_DISFORWARD 0x2000 /* disable channel forwarding */ +#define MODE_NOOPERKICK 0x4000 /* disallow kicking opers aka immune */ #define MODE_NOCTCP 0x8000 /* Block CTCPs directed to this channel */ #define MODE_NONOTICE 0x16000 /* Block notices directed to this channel */ #define MODE_NOACTION 0x32000 /* Block CTCP ACTION directed to this channel */ @@ -193,6 +196,8 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p, /* channel visible */ #define ShowChannel(v,c) (PubChannel(c) || IsMember((v),(c))) +/* user visible in channel */ +#define ShowInChannel(v,t,c) ((PubChannel(c) && !IsInvisible(t)) || IsMember((v),(c))) #define IsMember(who, chan) ((who && who->user && \ find_channel_membership(chan, who)) ? 1 : 0) diff --git a/include/chmode.h b/include/chmode.h index a9c04a6..48e96d5 100644 --- a/include/chmode.h +++ b/include/chmode.h @@ -48,6 +48,9 @@ extern void chm_simple(struct Client *source_p, struct Channel *chptr, extern void chm_ban(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, const char **parv, int *errors, int dir, char c, long mode_type); +extern void chm_hidden(struct Client *source_p, struct Channel *chptr, + int alevel, int parc, int *parn, + const char **parv, int *errors, int dir, char c, long mode_type); extern void chm_staff(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, const char **parv, int *errors, int dir, char c, long mode_type); diff --git a/include/client.h b/include/client.h index 2d673cf..e1f285a 100644 --- a/include/client.h +++ b/include/client.h @@ -281,6 +281,8 @@ struct LocalUser struct ev_entry *event; /* used for associated events */ struct PrivilegeSet *privset; /* privset... */ + + struct rb_event_t *override_timeout_event; }; struct PreClient @@ -430,6 +432,17 @@ struct ListClient #define UMODE_ADMIN 0x2000 /* Admin on server */ #define UMODE_SSLCLIENT 0x4000 /* using SSL */ +/* oper-controlled privledge umodes. */ +#define UMODE_OVERRIDE 0x20000 + +/* umode/oper mode macros */ +#define IsOper(x) ((x)->umodes & UMODE_OPER) +#define IsAdmin(x) ((x)->umodes & UMODE_ADMIN) +#define IsHelper(x) ((x)->umodes & UMODE_HELPER) +#define IsAnyOper(x) ((x)->umodes & (UMODE_OPER|UMODE_HELPER)) + +#define IsOverride(x) ((x)->umodes & UMODE_OVERRIDE) + /* overflow flags */ /* EARLIER FLAGS ARE IN s_newconf.h */ #define FLAGS2_EXEMPTRESV 0x00400000 diff --git a/include/s_newconf.h b/include/s_newconf.h index 03e887d..e55d8ec 100644 --- a/include/s_newconf.h +++ b/include/s_newconf.h @@ -164,6 +164,7 @@ extern void cluster_generic(struct Client *, const char *, int cltype, #define IsOperSpy(x) (HasPrivilege((x), "oper:spy")) #define IsOperInvis(x) (HasPrivilege((x), "oper:hidden")) #define IsOperRemoteBan(x) (HasPrivilege((x), "oper:remoteban")) +#define IsOperOverride(x) HasPrivilege(x, "oper:override") #define IsOperMassNotice(x) (HasPrivilege((x), "oper:mass_notice")) extern struct oper_conf *make_oper_conf(void); @@ -175,6 +176,20 @@ extern struct oper_conf *find_oper_conf(const char *username, const char *host, extern const char *get_oper_privs(int flags); +struct mode_table +{ + const char *name; + int mode; +}; + +struct oper_flags +{ + int flag; + const char *name; + char has; + char hasnt; +}; + struct server_conf { char *name; diff --git a/modules/m_privs.c b/modules/m_privs.c index 1d24aad..c87bb0d 100644 --- a/modules/m_privs.c +++ b/modules/m_privs.c @@ -53,13 +53,6 @@ mapi_clist_av1 privs_clist[] = { NULL }; -/* XXX this is a copy, not so nice */ -struct mode_table -{ - const char *name; - int mode; -}; - /* there is no such table like this anywhere else */ static struct mode_table auth_client_table[] = { {"resv_exempt", FLAGS2_EXEMPTRESV }, diff --git a/src/client.c b/src/client.c index b3f33c3..cad1b7f 100644 --- a/src/client.c +++ b/src/client.c @@ -232,6 +232,12 @@ free_local_client(struct Client *client_p) } rb_free(client_p->localClient->auth_user); + + if(client_p->localClient->override_timeout_event) + { + rb_event_delete(client_p->localClient->override_timeout_event); + } + rb_free(client_p->localClient->challenge); rb_free(client_p->localClient->fullcaps); rb_free(client_p->localClient->opername); diff --git a/src/newconf.c b/src/newconf.c index 50ceefc..05f32fa 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -286,12 +286,6 @@ conf_set_modules_path(void *data) #endif } -struct mode_table -{ - const char *name; - int mode; -}; - /* *INDENT-OFF* */ static struct mode_table umode_table[] = { {"callerid", UMODE_CALLERID }, @@ -303,6 +297,7 @@ static struct mode_table umode_table[] = { {"servnotice", UMODE_SERVNOTICE}, {"wallop", UMODE_WALLOP }, {"operwall", UMODE_OPERWALL }, + {"override", UMODE_OVERRIDE }, {"noctcp", UMODE_NOCTCP }, {"noinvite", UMODE_NOINVITE }, {"bot", UMODE_BOT }, diff --git a/src/s_user.c b/src/s_user.c index 441012c..8c9683e 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -109,7 +109,7 @@ int user_modes[256] = { 0, /* m */ 0, /* n */ UMODE_OPER, /* o */ - 0, /* p */ + UMODE_OVERRIDE, /* p */ 0, /* q */ 0, /* r */ UMODE_SERVNOTICE, /* s */ @@ -881,6 +881,15 @@ report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf) } } +static void +expire_umode_p(void *data) +{ + struct Client *source_p = data; + char *parv[4] = {source_p->name, source_p->name, "-p", NULL}; + source_p->localClient->override_timeout_event = NULL; + user_mode(source_p, source_p, 3, parv); +} + static void show_other_user_mode(struct Client *source_p, struct Client *target_p) { @@ -1138,6 +1147,12 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char source_p->umodes &= ~UMODE_ADMIN; } + if(MyConnect(source_p) && (source_p->umodes & UMODE_OVERRIDE) && (!IsOperOverride(source_p))) + { + sendto_one_notice(source_p, ":*** You need oper and the override flag for +p"); + source_p->umodes &= ~UMODE_OVERRIDE; + } + /* let modules providing usermodes know that we've changed our usermode --nenolod */ hdata.client = source_p; hdata.oldumodes = setflags; @@ -1157,6 +1172,17 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char sendto_one_numeric(source_p, RPL_SNOMASK, form_str(RPL_SNOMASK), construct_snobuf(source_p->snomask)); + if(ConfigFileEntry.expire_override_time && MyClient(source_p) && (source_p->umodes & ~setflags) & UMODE_OVERRIDE) + { + source_p->localClient->override_timeout_event = + rb_event_addonce("expire_override", expire_umode_p, source_p, ConfigFileEntry.expire_override_time); + } + else if(MyClient(source_p) && source_p->localClient->override_timeout_event && (setflags & ~source_p->umodes) & UMODE_OVERRIDE) + { + rb_event_delete(source_p->localClient->override_timeout_event); + source_p->localClient->override_timeout_event = NULL; + } + return (0); }