fixed ssl.c bug when ssl backend returns IO_BLOCKED but IO engine doesn't get informe...
[ircu2.10.12-pk.git] / ircd / m_svsmode.c
1 /*
2  * IRC - Internet Relay Chat, ircd/m_svsmode.c
3  * Written by David Herrmann.
4  */
5
6 /*
7  * m_functions execute protocol messages on this server:
8  *
9  *    cptr    is always NON-NULL, pointing to a *LOCAL* client
10  *            structure (with an open socket connected!). This
11  *            identifies the physical socket where the message
12  *            originated (or which caused the m_function to be
13  *            executed--some m_functions may call others...).
14  *
15  *    sptr    is the source of the message, defined by the
16  *            prefix part of the message if present. If not
17  *            or prefix not found, then sptr==cptr.
18  *
19  *            (!IsServer(cptr)) => (cptr == sptr), because
20  *            prefixes are taken *only* from servers...
21  *
22  *            (IsServer(cptr))
23  *                    (sptr == cptr) => the message didn't
24  *                    have the prefix.
25  *
26  *                    (sptr != cptr && IsServer(sptr) means
27  *                    the prefix specified servername. (?)
28  *
29  *                    (sptr != cptr && !IsServer(sptr) means
30  *                    that message originated from a remote
31  *                    user (not local).
32  *
33  *            combining
34  *
35  *            (!IsServer(sptr)) means that, sptr can safely
36  *            taken as defining the target structure of the
37  *            message in this server.
38  *
39  *    *Always* true (if 'parse' and others are working correct):
40  *
41  *    1)      sptr->from == cptr  (note: cptr->from == cptr)
42  *
43  *    2)      MyConnect(sptr) <=> sptr == cptr (e.g. sptr
44  *            *cannot* be a local connection, unless it's
45  *            actually cptr!). [MyConnect(x) should probably
46  *            be defined as (x == x->from) --msa ]
47  *
48  *    parc    number of variable parameter strings (if zero,
49  *            parv is allowed to be NULL)
50  *
51  *    parv    a NULL terminated list of parameter pointers,
52  *
53  *                    parv[0], sender (prefix string), if not present
54  *                            this points to an empty string.
55  *                    parv[1]...parv[parc-1]
56  *                            pointers to additional parameters
57  *                    parv[parc] == NULL, *always*
58  *
59  *            note:   it is guaranteed that parv[0]..parv[parc-1] are all
60  *                    non-NULL pointers.
61  */
62 #include "config.h"
63
64 #include "client.h"
65 #include "hash.h"
66 #include "ircd.h"
67 #include "ircd_features.h"
68 #include "ircd_log.h"
69 #include "ircd_reply.h"
70 #include "ircd_string.h"
71 #include "msg.h"
72 #include "numeric.h"
73 #include "numnicks.h"
74 #include "s_conf.h"
75 #include "s_misc.h"
76 #include "s_user.h"
77 #include "send.h"
78 #include "sys.h"
79
80 #include <stdlib.h>
81 #include <string.h>
82
83 /** SVSMODE
84  * SVSMODE is forwarded to the users server, hence, it can be called
85  * from any server.
86  */
87 int m_svsmode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
88 {
89     struct Client *acptr;
90     unsigned int i,allow;
91     char buffer[512];
92     char *act, *m;
93     struct Flags setflags;
94
95         if (!IsNetServ(sptr) || !HasFlag(sptr, FLAG_SECURITY_SERV))
96     return send_reply(sptr, ERR_NOPRIVILEGES);
97         
98     if(parc < 3) {
99         return protocol_violation(cptr, "Too few arguments for SVSMODE");
100     }
101
102     if(!(acptr = FindUser(parv[1]))) {
103         return 0; /* Ignore SVSMODE for a user that has quit */
104     }
105
106     /* Forward the message to the server where the user is connected to. */
107     if(!MyConnect(acptr)) {
108         act = buffer;
109         for(i = 2; i < (parc - 1); ++i) {
110             m = parv[i];
111             while((*act++ = *m++)) /* empty loop */ ;
112             *(act - 1) = ' ';
113         }
114         m = parv[i];
115         *act++ = ':';
116         while((*act++ = *m++)) /* empty loop */ ;
117                 const struct User* user = cli_user(acptr);
118                 struct Client *server = user->server; 
119         sendcmdto_one(sptr, CMD_SVSMODE, acptr, "%s%s %s", cli_yxx(server), cli_yxx(acptr), buffer);
120         return 0;
121     }
122
123     /* Set mode change. */
124     setflags = cli_flags(acptr);
125          /* This is a very important security check! 
126     or shall we allow normal opers to set mode +D?
127     */
128         
129     if(IsSecurityServ(sptr) && IsNetServ(sptr))
130         allow=ALLOWMODES_WITHSECSERV;
131     else
132         allow=ALLOWMODES_ANY;
133     set_user_mode(&me, acptr, parc, parv, allow);
134     send_umode(acptr, acptr, &setflags, ALL_UMODES, 0);
135     return 0;
136 }
137
138 /* ms_svsmode - server message handler
139  * parv[0] = sender prefix
140  * parv[1] = target numeric
141  * parv[2-X] = mode string
142  */
143 signed int ms_svsmode(struct Client* cptr, struct Client* sptr, signed int parc, char* parv[]) {
144     struct Client *acptr;
145     unsigned int i,allow;
146     char buffer[512];
147     char *act, *m;
148     struct Flags setflags;
149
150     if(parc < 3) {
151         return protocol_violation(cptr, "Too few arguments for SVSMODE");
152     }
153
154     if(!(acptr = findNUser(parv[1]))) {
155         return 0; /* Ignore SVSMODE for a user that has quit */
156     }
157
158     /* Forward the message to the server where the user is connected to. */
159     if(!MyConnect(acptr)) {
160         act = buffer;
161         for(i = 2; i < (parc - 1); ++i) {
162             m = parv[i];
163             while((*act++ = *m++)) /* empty loop */ ;
164             *(act - 1) = ' ';
165         }
166         m = parv[i];
167         *act++ = ':';
168         while((*act++ = *m++)) /* empty loop */ ;
169         sendcmdto_one(sptr, CMD_SVSMODE, acptr, "%s %s", parv[1], buffer);
170         return 0;
171     }
172
173     #ifndef UNRESTRICTED_SERV
174     
175     /* Set mode change. */
176     setflags = cli_flags(acptr);
177     /* This is a very important security check! 
178     or shall we allow normal opers to set mode +D?
179     */
180     if(IsSecurityServ(sptr) && IsNetServ(sptr)) {
181         allow=ALLOWMODES_WITHSECSERV;
182         } else {
183         allow=ALLOWMODES_ANY;
184         }
185     set_user_mode(&me, acptr, parc, parv, allow);
186     send_umode(acptr, acptr, &setflags, ALL_UMODES, 0);
187     
188     #endif
189     
190     return 0;
191 }
192