reimplemented fakeident support
[ircu2.10.12-pk.git] / ircd / m_fakehost.c
1 /*
2  * IRC - Internet Relay Chat, ircd/m_fakehost.c
3  * Copyright (C) 2004 Zoot <zoot@gamesurge.net>
4  *
5  * See file AUTHORS in IRC package for additional names of
6  * the programmers.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 1, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  */
24
25 /*
26  * m_functions execute protocol messages on this server:
27  *
28  *    cptr    is always NON-NULL, pointing to a *LOCAL* client
29  *            structure (with an open socket connected!). This
30  *            identifies the physical socket where the message
31  *            originated (or which caused the m_function to be
32  *            executed--some m_functions may call others...).
33  *
34  *    sptr    is the source of the message, defined by the
35  *            prefix part of the message if present. If not
36  *            or prefix not found, then sptr==cptr.
37  *
38  *            (!IsServer(cptr)) => (cptr == sptr), because
39  *            prefixes are taken *only* from servers...
40  *
41  *            (IsServer(cptr))
42  *                    (sptr == cptr) => the message didn't
43  *                    have the prefix.
44  *
45  *                    (sptr != cptr && IsServer(sptr) means
46  *                    the prefix specified servername. (?)
47  *
48  *                    (sptr != cptr && !IsServer(sptr) means
49  *                    that message originated from a remote
50  *                    user (not local).
51  *
52  *            combining
53  *
54  *            (!IsServer(sptr)) means that, sptr can safely
55  *            taken as defining the target structure of the
56  *            message in this server.
57  *
58  *    *Always* true (if 'parse' and others are working correct):
59  *
60  *    1)      sptr->from == cptr  (note: cptr->from == cptr)
61 *
62  *    2)      MyConnect(sptr) <=> sptr == cptr (e.g. sptr
63  *            *cannot* be a local connection, unless it's
64  *            actually cptr!). [MyConnect(x) should probably
65  *            be defined as (x == x->from) --msa ]
66  *
67  *    parc    number of variable parameter strings (if zero,
68  *            parv is allowed to be NULL)
69  *
70  *    parv    a NULL terminated list of parameter pointers,
71  *
72  *                    parv[0], sender (prefix string), if not present
73  *                            this points to an empty string.
74  *                    parv[1]...parv[parc-1]
75  *                            pointers to additional parameters
76  *                    parv[parc] == NULL, *always*
77  *
78  *            note:   it is guaranteed that parv[0]..parv[parc-1] are all
79  *                    non-NULL pointers.
80  */
81 #include "config.h"
82
83 #include "client.h"
84 #include "hash.h"
85 #include "ircd.h"
86 #include "ircd_reply.h"
87 #include "ircd_string.h"
88 #include "msg.h"
89 #include "numeric.h"
90 #include "numnicks.h"
91 #include "s_bsd.h"
92 #include "s_conf.h"
93 #include "s_user.h"
94 #include "s_debug.h"
95 #include "send.h"
96 /*
97  * m_fakehost - fakehost user message handler
98  *
99  * parv[0] = sender prefix
100  * parv[1] = new fake host
101  */
102 int m_fakehost(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
103 {
104 struct Client *acptr,*another;
105 int i;
106   if (!IsNetServ(sptr) || !HasFlag(sptr, FLAG_SECURITY_SERV))
107     return send_reply(sptr, ERR_NOPRIVILEGES);
108
109   if (parc < 2)
110     return need_more_params(sptr, "FAKEHOST");
111   if (parc < 3)
112   {
113
114   /* Assign and propagate the fakehost */
115   ircd_strncpy(cli_user(cptr)->fakehost, parv[1], HOSTLEN);
116   hide_hostmask(cptr, HIDE_HOSTMASK_FLAG_FAKEHOST);
117   
118         /*for(i = HighestFd; i >= 0; i--) {
119         if((another = LocalClientArray[i]) && IsServer(another)) {
120             sendcmdto_one(cptr, CMD_MODE, another, "%s +f :%s", cli_name(cptr), parv[2]);
121         }
122     }*/
123         sendcmdto_serv_butone(sptr, CMD_FAKEHOST_OLD, cptr, "%C %s", cptr,cli_user(cptr)->fakehost);
124   
125   return 0;
126   }
127   else
128   {
129
130     acptr = FindUser(parv[1]);
131     if (!acptr)
132     {
133       send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);
134       return 0;
135     }
136  
137
138   /* Assign and propagate the fakehost */
139   ircd_strncpy(cli_user(acptr)->fakehost, parv[2], HOSTLEN);
140   hide_hostmask(acptr, HIDE_HOSTMASK_FLAG_FAKEHOST);
141         /*
142         for(i = HighestFd; i >= 0; i--) {
143         if((another = LocalClientArray[i]) && IsServer(another)) {
144             sendcmdto_one(acptr, CMD_MODE, another, "%s +f :%s", cli_name(acptr), parv[2]);
145         }
146     }
147   */
148    sendcmdto_serv_butone(sptr, CMD_FAKEHOST_OLD, cptr, "%C %s", acptr,
149                           cli_user(acptr)->fakehost);
150   return 0;
151   }
152 }
153
154 /*
155  * IRC - Internet Relay Chat, ircd/m_fakehost.c
156  * Written by David Herrmann.
157  */
158
159 /*
160  * m_functions execute protocol messages on this server:
161  *
162  *    cptr    is always NON-NULL, pointing to a *LOCAL* client
163  *            structure (with an open socket connected!). This
164  *            identifies the physical socket where the message
165  *            originated (or which caused the m_function to be
166  *            executed--some m_functions may call others...).
167  *
168  *    sptr    is the source of the message, defined by the
169  *            prefix part of the message if present. If not
170  *            or prefix not found, then sptr==cptr.
171  *
172  *            (!IsServer(cptr)) => (cptr == sptr), because
173  *            prefixes are taken *only* from servers...
174  *
175  *            (IsServer(cptr))
176  *                    (sptr == cptr) => the message didn't
177  *                    have the prefix.
178  *
179  *                    (sptr != cptr && IsServer(sptr) means
180  *                    the prefix specified servername. (?)
181  *
182  *                    (sptr != cptr && !IsServer(sptr) means
183  *                    that message originated from a remote
184  *                    user (not local).
185  *
186  *            combining
187  *
188  *            (!IsServer(sptr)) means that, sptr can safely
189  *            taken as defining the target structure of the
190  *            message in this server.
191  *
192  *    *Always* true (if 'parse' and others are working correct):
193  *
194  *    1)      sptr->from == cptr  (note: cptr->from == cptr)
195  *
196  *    2)      MyConnect(sptr) <=> sptr == cptr (e.g. sptr
197  *            *cannot* be a local connection, unless it's
198  *            actually cptr!). [MyConnect(x) should probably
199  *            be defined as (x == x->from) --msa ]
200  *
201  *    parc    number of variable parameter strings (if zero,
202  *            parv is allowed to be NULL)
203  *
204  *    parv    a NULL terminated list of parameter pointers,
205  *
206  *                    parv[0], sender (prefix string), if not present
207  *                            this points to an empty string.
208  *                    parv[1]...parv[parc-1]
209  *                            pointers to additional parameters
210  *                    parv[parc] == NULL, *always*
211  *
212  *            note:   it is guaranteed that parv[0]..parv[parc-1] are all
213  *                    non-NULL pointers.
214  */
215
216
217 /* ms_fakehost - fakehost server message handler
218  *
219  * parv[0] = sender prefix
220  * parv[1] = target user numeric
221  * parv[2] = target user's new fake host
222  */
223 /** Remote fakehost
224  * Allows servers to force a fakehost on remote users.
225  *
226  * The FAKEHOST request can be generated by EVERY server. It is forwarded to the server
227  * of the user which then sets the fakehost and broadcasts the new fakehost.
228  */
229 int ms_fakehost(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) {
230     struct Client *target, *acptr;
231     int i;
232
233     if(parc < 3) {
234         return need_more_params(sptr, "FAKEHOST");
235     }
236
237     if(!(target = findNUser(parv[1]))) {
238         /* Silently ignore FAKEHOSTs for disconnected users. */
239         return 0;
240     }
241
242     /* Ignore the assignment if it changes nothing. */
243     if(IsFakeHost(target) && strcmp(cli_user(target)->fakehost, parv[2]) == 0) {
244         return 0;
245     }
246
247     /* If the user is no local user, we forward the message to the user's server. */
248     if(!MyConnect(target)) {
249         sendcmdto_one(sptr, CMD_FAKEHOST, cli_user(target)->server, "%C %s", target, parv[2]);
250         return 0;
251     }
252
253     /* Set fakehost and propagate the changed host. */
254     ircd_strncpy(cli_user(target)->fakehost, parv[2], HOSTLEN);
255     hide_hostmask(target, HIDE_HOSTMASK_FLAG_FAKEHOST);
256
257     /* Borrowed from send_umode_out().
258      * I found no better way to do this. However, maybe someone has the time to check out
259      * s_user.c to change this.
260      */
261     for(i = HighestFd; i >= 0; i--) {
262         if((acptr = LocalClientArray[i]) && IsServer(acptr)) {
263             sendcmdto_one(target, CMD_MODE, acptr, "%s +f :%s", cli_name(target), parv[2]);
264         }
265     }
266
267     return 0;
268 }
269
270 /* ms_fakehost2 - new fakehost server message handler (SRVX initialized)
271  *
272  * parv[0] = sender prefix
273  * parv[1] = target user numeric
274  * parv[2] = target user's new ident
275  * parv[3] = target user's new fake host
276  * parv[4] = FORCE (optional)
277  */
278 /** Remote fakehost
279  * Allows servers to force a fakehost on remote users.
280  *
281  * The FAKEHOST request can be generated by EVERY server. It is forwarded to the server
282  * of the user which then sets the fakehost and broadcasts the new fakehost.
283  */
284 int ms_fakehost2(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) {
285     struct Client *target, *acptr;
286     int i;
287
288     if(parc < 4) {
289         return need_more_params(sptr, "FAKEHOST");
290     }
291
292     if(!(target = findNUser(parv[1]))) {
293         /* Silently ignore FAKEHOSTs for disconnected users. */
294         return 0;
295     }
296
297     /* Ignore the assignment if it changes nothing. */
298     if(IsFakeHost(target) && IsFakeIdent(target) && strcmp(cli_user(target)->fakehost, parv[3]) == 0 && strcmp(cli_user(target)->fakeuser, parv[2]) == 0) {
299         return 0;
300     }
301
302     /* Set fakehost and propagate the changed host. */
303     ircd_strncpy(cli_user(target)->fakehost, parv[3], HOSTLEN);
304     ircd_strncpy(cli_user(target)->fakeuser, parv[2], USERLEN);
305     hide_hostmask(target, HIDE_HOSTMASK_FLAG_FAKEHOST | HIDE_HOSTMASK_FLAG_FAKEIDENT);
306
307     sendcmdto_serv_butone(sptr, CMD_FAKEHOST2, cptr, "%C %s %s", target, cli_user(target)->fakeuser, cli_user(target)->fakehost);
308
309     return 0;
310 }
311
312 /*
313  * ms_fakehost_old - old fakehost server message handler
314  *
315  * parv[0] = sender prefix
316  * parv[1] = target user numeric
317  * parv[2] = target user's new fake host
318  * parv[3] = target user's new fake ident
319  */
320 int ms_fakehost_old(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) {
321     struct Client *target;
322
323     if(parc < 3)
324         return need_more_params(sptr, "FAKE");
325
326     /* Locate our target user; ignore the message if we can't */
327     if(!(target = findNUser(parv[1])))
328         return 0;
329
330     /* Ignore the assignment if it changes nothing */
331     if(IsFakeHost(target) && strcmp(cli_user(target)->fakehost, parv[2]) == 0) {
332         return 0;
333     }
334
335     /* Assign and propagate the fakehost */
336     ircd_strncpy(cli_user(target)->fakehost, parv[2], HOSTLEN);
337     hide_hostmask(target, HIDE_HOSTMASK_FLAG_FAKEHOST);
338
339     sendcmdto_serv_butone(sptr, CMD_FAKEHOST_OLD, cptr, "%C %s", target,
340                           cli_user(target)->fakehost);
341     return 0;
342 }
343