Anope IRC Services  Version 1.8
ns_group.c
Go to the documentation of this file.
1 /* NickServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  *
11  *
12  */
13 /*************************************************************************/
14 
15 #include "module.h"
16 
17 static int do_group(User * u);
18 static void myNickServHelp(User * u);
19 static int do_glist(User * u);
20 static int do_listlinks(User * u);
21 
22 NickAlias *makealias(const char *nick, NickCore * nc);
23 
24 /* Obsolete commands */
25 static int do_link(User * u);
26 
33 int AnopeInit(int argc, char **argv)
34 {
35  Command *c;
36 
37  moduleAddAuthor("Anope");
38  moduleAddVersion(VERSION_STRING);
40 
41  c = createCommand("GROUP", do_group, NULL, NICK_HELP_GROUP, -1, -1, -1,
42  -1);
44 
45  c = createCommand("LINK", do_link, NULL, -1, -1, -1, -1, -1);
47 
48  c = createCommand("GLIST", do_glist, NULL, -1, NICK_HELP_GLIST, -1,
49  NICK_SERVADMIN_HELP_GLIST,
50  NICK_SERVADMIN_HELP_GLIST);
52 
53  c = createCommand("LISTLINKS", do_listlinks, NULL, -1, -1, -1, -1, -1);
55 
57 
58  return MOD_CONT;
59 }
60 
64 void AnopeFini(void)
65 {
66 
67 }
68 
69 
70 
75 static void myNickServHelp(User * u)
76 {
77  notice_lang(s_NickServ, u, NICK_HELP_CMD_GROUP);
78  notice_lang(s_NickServ, u, NICK_HELP_CMD_GLIST);
79 }
80 
86 /* Register a nick in a specified group. */
87 
88 static int do_group(User * u)
89 {
90  NickAlias *na, *target;
91  NickCore *nc;
92  char *nick = strtok(NULL, " ");
93  char *pass = strtok(NULL, " ");
94  int i;
95  char tsbuf[16];
96  char modes[512];
97  int len;
98 
99  if (NSEmailReg && (findrequestnick(u->nick))) {
100  notice_lang(s_NickServ, u, NICK_REQUESTED);
101  return MOD_CONT;
102  }
103 
104  if (readonly) {
105  notice_lang(s_NickServ, u, NICK_GROUP_DISABLED);
106  return MOD_CONT;
107  }
109  notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
110  return MOD_CONT;
111  }
112 
113  if (!anope_valid_nick(u->nick)) {
114  notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick);
115  return MOD_CONT;
116  }
117 
118  if (RestrictOperNicks) {
119  for (i = 0; i < RootNumber; i++) {
120  if (stristr(u->nick, ServicesRoots[i]) && !is_oper(u)) {
121  notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
122  u->nick);
123  return MOD_CONT;
124  }
125  }
126  for (i = 0; i < servadmins.count && (nc = servadmins.list[i]); i++) {
127  if (stristr(u->nick, nc->display) && !is_oper(u)) {
128  notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
129  u->nick);
130  return MOD_CONT;
131  }
132  }
133  for (i = 0; i < servopers.count && (nc = servopers.list[i]); i++) {
134  if (stristr(u->nick, nc->display) && !is_oper(u)) {
135  notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
136  u->nick);
137  return MOD_CONT;
138  }
139  }
140  }
141 
142  if (!nick || !pass) {
143  syntax_error(s_NickServ, u, "GROUP", NICK_GROUP_SYNTAX);
144  } else if (!(target = findnick(nick))) {
145  notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
146  } else if (time(NULL) < u->lastnickreg + NSRegDelay) {
147  notice_lang(s_NickServ, u, NICK_GROUP_PLEASE_WAIT, NSRegDelay);
148  } else if (u->na && (u->na->status & NS_VERBOTEN)) {
149  alog("%s: %s@%s tried to use GROUP from FORBIDden nick %s",
150  s_NickServ, u->username, u->host, u->nick);
151  notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick);
152  } else if (u->na && (u->na->nc->flags & NI_SUSPENDED)) {
153  alog("%s: %s!%s@%s tried to use GROUP from SUSPENDED nick %s",
154  s_NickServ, u->nick, u->username, u->host, target->nick);
155  notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick);
156  } else if (u->na && NSNoGroupChange) {
157  notice_lang(s_NickServ, u, NICK_GROUP_CHANGE_DISABLED, s_NickServ);
158  } else if (u->na && !nick_identified(u)) {
159  notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
160  } else if (target && (target->nc->flags & NI_SUSPENDED)) {
161  alog("%s: %s!%s@%s tried to use GROUP from SUSPENDED nick %s",
162  s_NickServ, u->nick, u->username, u->host, target->nick);
163  notice_lang(s_NickServ, u, NICK_X_SUSPENDED, target->nick);
164  } else if (target->status & NS_VERBOTEN) {
165  notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
166  } else if (u->na && target->nc == u->na->nc) {
167  notice_lang(s_NickServ, u, NICK_GROUP_SAME, target->nick);
168  } else if (NSMaxAliases && (target->nc->aliases.count >= NSMaxAliases)
169  && !nick_is_services_admin(target->nc)) {
170  notice_lang(s_NickServ, u, NICK_GROUP_TOO_MANY, target->nick,
172  } else if (enc_check_password(pass, target->nc->pass) != 1) {
173  alog("%s: Failed GROUP for %s!%s@%s (invalid password)",
174  s_NickServ, u->nick, u->username, u->host);
175  notice_lang(s_NickServ, u, PASSWORD_INCORRECT);
176  bad_password(u);
177  } else {
178  /* If the nick is already registered, drop it.
179  * If not, check that it is valid.
180  */
181  if (u->na) {
182  delnick(u->na);
183  } else {
184  int prefixlen = strlen(NSGuestNickPrefix);
185  int nicklen = strlen(u->nick);
186 
187  if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1
188  && stristr(u->nick, NSGuestNickPrefix) == u->nick
189  && strspn(u->nick + prefixlen,
190  "1234567890") == nicklen - prefixlen) {
191  notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
192  u->nick);
193  return MOD_CONT;
194  }
195  }
196  na = makealias(u->nick, target->nc);
197 
198  if (na) {
199  na->last_usermask =
200  scalloc(strlen(common_get_vident(u)) +
201  strlen(common_get_vhost(u)) + 2, 1);
202  sprintf(na->last_usermask, "%s@%s", common_get_vident(u),
203  common_get_vhost(u));
204  na->last_realname = sstrdup(u->realname);
205  na->time_registered = na->last_seen = time(NULL);
207 
208  if (!(na->nc->flags & NI_SERVICES_ROOT)) {
209  for (i = 0; i < RootNumber; i++) {
210  if (!stricmp(ServicesRoots[i], u->nick)) {
211  na->nc->flags |= NI_SERVICES_ROOT;
212  break;
213  }
214  }
215  }
216 
217  u->na = na;
218  na->u = u;
219 
220 #ifdef USE_RDB
221  /* Is this really needed? Since this is a new alias it will get
222  * its unique id on the next update, since it was previously
223  * deleted by delnick. Must observe...
224  */
225  if (rdb_open()) {
226  rdb_save_ns_alias(na);
227  rdb_close();
228  }
229 #endif
230  send_event(EVENT_GROUP, 1, u->nick);
231  alog("%s: %s!%s@%s makes %s join group of %s (%s) (e-mail: %s)", s_NickServ, u->nick, u->username, u->host, u->nick, target->nick, target->nc->display, (target->nc->email ? target->nc->email : "none"));
232  notice_lang(s_NickServ, u, NICK_GROUP_JOINED, target->nick);
233 
234  u->lastnickreg = time(NULL);
235  snprintf(tsbuf, sizeof(tsbuf), "%lu",
236  (unsigned long int) u->timestamp);
237  if (ircd->modeonreg) {
238  len = strlen(ircd->modeonreg);
239  strncpy(modes,ircd->modeonreg,512);
240  if(ircd->rootmodeonid && is_services_root(u)) {
241  strncat(modes,ircd->rootmodeonid,512-len);
242  } else if(ircd->adminmodeonid && is_services_admin(u)) {
243  strncat(modes,ircd->adminmodeonid,512-len);
244  } else if(ircd->opermodeonid && is_services_oper(u)) {
245  strncat(modes,ircd->opermodeonid,512-len);
246  }
247  if (ircd->tsonmode) {
248  common_svsmode(u, modes, tsbuf);
249  } else {
250  common_svsmode(u, modes, NULL);
251  }
252  }
253 
254  check_memos(u);
255 
256  /* Enable nick tracking if enabled */
257  if (NSNickTracking)
259  } else {
260  alog("%s: makealias(%s) failed", s_NickServ, u->nick);
261  notice_lang(s_NickServ, u, NICK_GROUP_FAILED);
262  }
263  }
264  return MOD_CONT;
265 }
266 
267 
268 /* Creates a new alias in NickServ database. */
269 
270 NickAlias *makealias(const char *nick, NickCore * nc)
271 {
272  NickAlias *na;
273 
274  /* Just need to make the alias */
275  na = scalloc(1, sizeof(NickAlias));
276  na->nick = sstrdup(nick);
277  na->nc = nc;
278  slist_add(&nc->aliases, na);
279  alpha_insert_alias(na);
280  return na;
281 }
282 
283 
284 static int do_link(User * u)
285 {
286  notice_lang(s_NickServ, u, OBSOLETE_COMMAND, "GROUP");
287  return MOD_CONT;
288 }
289 
290 static int do_glist(User * u)
291 {
292  char *nick = strtok(NULL, " ");
293 
294  NickAlias *na, *na2;
295  int is_servadmin = is_services_admin(u);
296  int nick_ided = nick_identified(u);
297  int i;
298 
299  if ((nick ? (stricmp(nick, u->nick) ? !is_servadmin : !nick_ided)
300  : !nick_ided)) {
302  (nick_ided ? ACCESS_DENIED :
303  NICK_IDENTIFY_REQUIRED), s_NickServ);
304  } else if ((!nick ? !(na = u->na) : !(na = findnick(nick)))) {
306  (!nick ? NICK_NOT_REGISTERED : NICK_X_NOT_REGISTERED),
307  nick);
308  } else if (na->status & NS_VERBOTEN) {
309  notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
310  } else {
311  time_t expt;
312  struct tm *tm;
313  char buf[BUFSIZE];
314  int wont_expire;
315 
317  nick ? NICK_GLIST_HEADER_X : NICK_GLIST_HEADER,
318  na->nc->display);
319  for (i = 0; i < na->nc->aliases.count; i++) {
320  na2 = na->nc->aliases.list[i];
321  if (na2->nc == na->nc) {
322  if (!(wont_expire = na2->status & NS_NO_EXPIRE)) {
323  expt = na2->last_seen + NSExpire;
324  tm = localtime(&expt);
325  strftime_lang(buf, sizeof(buf), na2->u,
326  STRFTIME_DATE_TIME_FORMAT, tm);
327  }
329  ((is_services_admin(u) && !wont_expire)
330  ? NICK_GLIST_REPLY_ADMIN : NICK_GLIST_REPLY),
331  (wont_expire ? '!' : ' '), na2->nick, buf);
332  }
333  }
334  notice_lang(s_NickServ, u, NICK_GLIST_FOOTER,
335  na->nc->aliases.count);
336  }
337  return MOD_CONT;
338 }
339 
340 
341 static int do_listlinks(User * u)
342 {
343  notice_lang(s_NickServ, u, OBSOLETE_COMMAND, "GLIST");
344  return MOD_CONT;
345 }
E int is_oper(User *user)
Definition: users.c:937
E size_t strspn(const char *s, const char *accept)
Definition: compat.c:106
int AnopeInit(int argc, char **argv)
Definition: ns_group.c:33
E int nick_is_services_admin(NickCore *nc)
Definition: operserv.c:636
#define NI_SERVICES_ROOT
Definition: services.h:1305
E int readonly
Definition: extern.h:776
E int RestrictOperNicks
Definition: extern.h:359
char nick[NICKMAX]
Definition: services.h:875
static int do_group(User *u)
Definition: ns_group.c:88
E int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: compat.c:37
E NickAlias * findnick(const char *nick)
Definition: db-merger.c:1857
char * adminmodeonid
Definition: services.h:309
E int checkDefCon(int level)
Definition: operserv.c:1608
#define NI_SUSPENDED
Definition: services.h:1308
E IRCDVar * ircd
Definition: extern.h:39
E int enc_check_password(const char *plaintext, const char *password)
Definition: encrypt.c:95
E int NSEmailReg
Definition: extern.h:396
#define EVENT_GROUP
Definition: events.h:54
E SList servadmins
Definition: extern.h:971
E int nick_identified(User *u)
Definition: nickserv.c:1111
E void send_event(const char *name, int argc,...)
Definition: events.c:37
E int delnick(NickAlias *na)
Definition: nickserv.c:1586
E int NSNickTracking
Definition: extern.h:399
char * opermodeonid
Definition: services.h:310
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
E int NSExpire
Definition: extern.h:381
E char * stristr(char *s1, char *s2)
Definition: misc.c:113
#define NS_RECOGNIZED
Definition: services.h:1276
#define NS_VERBOTEN
Definition: services.h:1273
char * host
Definition: services.h:878
char * modeonreg
Definition: services.h:307
E int NSMaxAliases
Definition: extern.h:384
E void check_memos(User *u)
Definition: memoserv.c:86
MDE void moduleAddAuthor(const char *author)
Definition: modules.c:1772
E void syntax_error(char *service, User *u, const char *command, int msgnum)
Definition: language.c:295
E void alpha_insert_alias(NickAlias *na)
Definition: nickserv.c:1338
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
MDE void moduleSetType(MODType type)
Definition: modules.c:818
E void bad_password(User *u)
Definition: actions.c:24
E char * sstrdup(const char *s)
Definition: memory.c:105
NickCore * nc
Definition: services.h:533
int rdb_close()
Definition: rdb.c:47
E void * scalloc(long elsize, long els)
Definition: memory.c:55
char * display
Definition: services.h:542
E int is_services_root(User *u)
Definition: operserv.c:577
void ** list
Definition: slist.h:21
int rdb_save_ns_alias(NickAlias *na)
Definition: rdb.c:265
E NickRequest * findrequestnick(const char *nick)
Definition: nickserv.c:1218
int16 count
Definition: slist.h:23
static int do_link(User *u)
Definition: ns_group.c:284
E int NSRegDelay
Definition: extern.h:379
NickAlias * makealias(const char *nick, NickCore *nc)
Definition: ns_group.c:270
uint16 status
Definition: services.h:532
MDE void moduleAddVersion(const char *version)
Definition: modules.c:1760
static int do_glist(User *u)
Definition: ns_group.c:290
Command * c
Definition: ns_recover.c:17
E void alog(const char *fmt,...) FORMAT(printf
#define MOD_CONT
Definition: modules.h:54
int16_t int16
Definition: db-merger.c:120
time_t time_registered
Definition: services.h:530
E int is_services_admin(User *u)
Definition: operserv.c:591
static int do_listlinks(User *u)
Definition: ns_group.c:341
char * nick
Definition: services.h:526
char * username
Definition: services.h:877
char * last_realname
Definition: services.h:528
E int NSNoGroupChange
Definition: extern.h:390
E char * NSGuestNickPrefix
Definition: extern.h:393
MDE void moduleSetNickHelp(void(*func)(User *u))
Definition: modules.c:2078
static void myNickServHelp(User *u)
Definition: ns_group.c:75
Definition: modules.h:99
MDE Command * createCommand(const char *name, int(*func)(User *u), int(*has_priv)(User *u), int help_all, int help_reg, int help_oper, int help_admin, int help_root)
Definition: modules.c:987
int tsonmode
Definition: services.h:339
E char ** ServicesRoots
Definition: extern.h:434
char pass[PASSMAX]
Definition: services.h:543
int rdb_open()
Definition: rdb.c:31
#define NS_IDENTIFIED
Definition: services.h:1275
time_t lastnickreg
Definition: services.h:913
SList aliases
Definition: services.h:559
E int is_services_oper(User *u)
Definition: operserv.c:606
uint32 flags
Definition: services.h:548
E void common_svsmode(User *u, char *modes, char *arg)
Definition: actions.c:228
time_t last_seen
Definition: services.h:531
#define NS_NO_EXPIRE
Definition: services.h:1274
E int slist_add(SList *slist, void *item)
Definition: slist.c:29
#define DEFCON_NO_NEW_NICKS
Definition: services.h:1255
void AnopeFini(void)
Definition: ns_group.c:64
E int strftime_lang(char *buf, int size, User *u, int format, struct tm *tm)
Definition: language.c:240
User * u
Definition: services.h:536
E char * s_NickServ
Definition: extern.h:284
MDE int moduleAddCommand(CommandHash *cmdTable[], Command *c, int pos)
Definition: modules.c:1082
E SList servopers
Definition: extern.h:972
char * last_usermask
Definition: services.h:529
time_t timestamp
Definition: services.h:886
char * rootmodeonid
Definition: services.h:308
E char * common_get_vhost(User *u)
Definition: actions.c:251
E int anope_valid_nick(char *nick)
Definition: ircd.c:661
#define BUFSIZE
Definition: config.h:47
E int RootNumber
Definition: extern.h:435
#define NICKSERV
Definition: modules.h:59
char * realname
Definition: services.h:883
E char * common_get_vident(User *u)
Definition: actions.c:272
NickAlias * na
Definition: services.h:892
#define MOD_UNIQUE
Definition: module.h:11
char * email
Definition: services.h:544
E void nsStartNickTracking(User *u)
Definition: nickserv.c:1962