]> jfr.im git - solanum.git/blob - modules/m_grant.c
Merge pull request #279 from edk0/operhide
[solanum.git] / modules / m_grant.c
1 /*
2 * Copyright (C) 2006 Jilles Tjoelker
3 * Copyright (C) 2006 Stephen Bennett <spb@gentoo.org>
4 * Copyright (C) 2016 Jason Volk <jason@zemos.net>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice is present in all copies.
9 *
10 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
11 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
14 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
19 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20 * POSSIBILITY OF SUCH DAMAGE.
21 */
22
23 #include "stdinc.h"
24 #include "modules.h"
25 #include "numeric.h"
26 #include "client.h"
27 #include "ircd.h"
28 #include "send.h"
29 #include "s_user.h"
30 #include "s_serv.h"
31 #include "s_conf.h"
32 #include "s_newconf.h"
33 #include "privilege.h"
34
35
36 static
37 void set_mode(struct Client *const target,
38 const char *const str)
39 {
40 const char *mode[] =
41 {
42 target->name,
43 target->name,
44 str,
45 NULL
46 };
47
48 user_mode(target, target, 3, mode);
49 }
50
51
52 static
53 void set_privset(struct Client *const source,
54 struct Client *const target,
55 const char *const privset_name)
56 {
57 struct PrivilegeSet *const privset = privilegeset_get(privset_name);
58 if(!privset)
59 {
60 sendto_one_notice(source, ":There is no privilege set named '%s'.", privset_name);
61 return;
62 }
63
64 if(IsOper(target) && target->localClient->privset == privset)
65 {
66 sendto_one_notice(source, ":%s already has role of %s.", target->name, privset_name);
67 return;
68 }
69
70 if(IsOper(target))
71 {
72 sendto_one_notice(target, ":%s has changed your role to %s.", source->name, privset_name);
73 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s has changed %s's role to %s.", get_oper_name(source), target->name, privset_name);
74 target->localClient->privset = privset;
75 return;
76 }
77
78 struct oper_conf oper =
79 {
80 .name = (char *)privset->name,
81 .privset = privset,
82 };
83
84 oper_up(target, &oper);
85 set_mode(target, "+o");
86 sendto_one_notice(target, ":%s has granted you the role of %s.", source->name, privset_name);
87 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s has granted %s the role of %s.", get_oper_name(source), target->name, privset_name);
88 }
89
90
91 static
92 void grant_revoke(struct Client *const source,
93 struct Client *const target)
94 {
95 if(!IsOper(target))
96 {
97 sendto_one_notice(source, ":You can't deoper someone who isn't an oper.");
98 return;
99 }
100
101 set_mode(target, "-o");
102 sendto_one_notice(target, ":%s has deopered you.", source->name);
103 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s has deopered %s.", get_oper_name(source), target->name);
104 }
105
106
107 static
108 void grant(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
109 {
110 if(MyClient(source_p) && !HasPrivilege(source_p, "oper:grant"))
111 {
112 sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "grant");
113 return;
114 }
115
116 if(parc < 3)
117 {
118 sendto_one_notice(source_p, ":usage GRANT: <target nickname> <privilegese name | 'revoke'>");
119 return;
120 }
121
122 struct Client *const target_p = find_person(parv[1]);
123
124 if(!target_p)
125 {
126 if(IsPerson(source_p))
127 sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]);
128
129 return;
130 }
131
132 if(!MyClient(source_p) && !find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_GRANT))
133 {
134 sendto_one_notice(source_p, ":GRANT failed: You have no shared configuration block on this server.");
135 return;
136 }
137
138 if(MyClient(target_p))
139 {
140 if(irccmp(parv[2], "revoke") == 0)
141 grant_revoke(source_p, target_p);
142 else
143 set_privset(source_p, target_p, parv[2]);
144 }
145 else if(MyClient(source_p))
146 {
147 sendto_one(target_p, ":%s ENCAP %s GRANT %s %s",
148 get_id(source_p, target_p),
149 target_p->servptr->name,
150 get_id(target_p, target_p),
151 parv[2]);
152 }
153
154 return;
155 }
156
157 struct Message msgtab =
158 {
159 "GRANT", 0, 0, 0, 0,
160 {
161 mg_ignore,
162 mg_not_oper,
163 mg_ignore,
164 mg_ignore,
165 { grant, 3 },
166 { grant, 3 }
167 }
168 };
169
170 mapi_clist_av1 grant_clist[] =
171 {
172 &msgtab,
173 NULL
174 };
175
176 static const char grant_desc[] =
177 "Provides the grant facility for giving other users specific privilege sets";
178
179 DECLARE_MODULE_AV2
180 (
181 grant,
182 NULL,
183 NULL,
184 grant_clist,
185 NULL,
186 NULL,
187 NULL,
188 NULL,
189 grant_desc
190 );