ns_group.c

Go to the documentation of this file.
00001 /* NickServ core functions
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  * $Id: ns_group.c 1265 2007-08-26 15:33:06Z geniusdex $
00012  *
00013  */
00014 /*************************************************************************/
00015 
00016 #include "module.h"
00017 
00018 int do_group(User * u);
00019 void myNickServHelp(User * u);
00020 int do_glist(User * u);
00021 int do_listlinks(User * u);
00022 
00023 NickAlias *makealias(const char *nick, NickCore * nc);
00024 
00025 /* Obsolete commands */
00026 int do_link(User * u);
00027 
00034 int AnopeInit(int argc, char **argv)
00035 {
00036     Command *c;
00037 
00038     moduleAddAuthor("Anope");
00039     moduleAddVersion("$Id: ns_group.c 1265 2007-08-26 15:33:06Z geniusdex $");
00040     moduleSetType(CORE);
00041 
00042     c = createCommand("GROUP", do_group, NULL, NICK_HELP_GROUP, -1, -1, -1,
00043                       -1);
00044     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00045 
00046     c = createCommand("LINK", do_link, NULL, -1, -1, -1, -1, -1);
00047     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00048 
00049     c = createCommand("GLIST", do_glist, NULL, -1, NICK_HELP_GLIST, -1,
00050                       NICK_SERVADMIN_HELP_GLIST,
00051                       NICK_SERVADMIN_HELP_GLIST);
00052     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00053 
00054     c = createCommand("LISTLINKS", do_listlinks, NULL, -1, -1, -1, -1, -1);
00055     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00056 
00057     moduleSetNickHelp(myNickServHelp);
00058 
00059     return MOD_CONT;
00060 }
00061 
00065 void AnopeFini(void)
00066 {
00067 
00068 }
00069 
00070 
00071 
00076 void myNickServHelp(User * u)
00077 {
00078     notice_lang(s_NickServ, u, NICK_HELP_CMD_GROUP);
00079     notice_lang(s_NickServ, u, NICK_HELP_CMD_GLIST);
00080 }
00081 
00087 /* Register a nick in a specified group. */
00088 
00089 int do_group(User * u)
00090 {
00091     NickAlias *na, *target;
00092     NickCore *nc;
00093     char *nick = strtok(NULL, " ");
00094     char *pass = strtok(NULL, " ");
00095     int i;
00096     char tsbuf[16];
00097     char modes[512];
00098     int len;
00099 
00100     if (NSEmailReg && (findrequestnick(u->nick))) {
00101         notice_lang(s_NickServ, u, NICK_REQUESTED);
00102         return MOD_CONT;
00103     }
00104 
00105     if (readonly) {
00106         notice_lang(s_NickServ, u, NICK_GROUP_DISABLED);
00107         return MOD_CONT;
00108     }
00109     if (checkDefCon(DEFCON_NO_NEW_NICKS)) {
00110         notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
00111         return MOD_CONT;
00112     }
00113 
00114     if (RestrictOperNicks) {
00115         for (i = 0; i < RootNumber; i++) {
00116             if (stristr(u->nick, ServicesRoots[i]) && !is_oper(u)) {
00117                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00118                             u->nick);
00119                 return MOD_CONT;
00120             }
00121         }
00122         for (i = 0; i < servadmins.count && (nc = servadmins.list[i]); i++) {
00123             if (stristr(u->nick, nc->display) && !is_oper(u)) {
00124                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00125                             u->nick);
00126                 return MOD_CONT;
00127             }
00128         }
00129         for (i = 0; i < servopers.count && (nc = servopers.list[i]); i++) {
00130             if (stristr(u->nick, nc->display) && !is_oper(u)) {
00131                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00132                             u->nick);
00133                 return MOD_CONT;
00134             }
00135         }
00136     }
00137 
00138     if (!nick || !pass) {
00139         syntax_error(s_NickServ, u, "GROUP", NICK_GROUP_SYNTAX);
00140     } else if (!(target = findnick(nick))) {
00141         notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick);
00142     } else if (time(NULL) < u->lastnickreg + NSRegDelay) {
00143         notice_lang(s_NickServ, u, NICK_GROUP_PLEASE_WAIT, NSRegDelay);
00144     } else if (u->na && (u->na->status & NS_VERBOTEN)) {
00145         alog("%s: %s@%s tried to use GROUP from FORBIDden nick %s",
00146              s_NickServ, u->username, u->host, u->nick);
00147         notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick);
00148     } else if (u->na && (u->na->nc->flags & NI_SUSPENDED)) {
00149         alog("%s: %s!%s@%s tried to use GROUP from SUSPENDED nick %s",
00150              s_NickServ, u->nick, u->username, u->host, target->nick);
00151         notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick);
00152     } else if (u->na && NSNoGroupChange) {
00153         notice_lang(s_NickServ, u, NICK_GROUP_CHANGE_DISABLED, s_NickServ);
00154     } else if (u->na && !nick_identified(u)) {
00155         notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
00156     } else if (target && (target->nc->flags & NI_SUSPENDED)) {
00157         alog("%s: %s!%s@%s tried to use GROUP from SUSPENDED nick %s",
00158              s_NickServ, u->nick, u->username, u->host, target->nick);
00159         notice_lang(s_NickServ, u, NICK_X_SUSPENDED, target->nick);
00160     } else if (target->status & NS_VERBOTEN) {
00161         notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick);
00162     } else if (u->na && target->nc == u->na->nc) {
00163         notice_lang(s_NickServ, u, NICK_GROUP_SAME, target->nick);
00164     } else if (NSMaxAliases && (target->nc->aliases.count >= NSMaxAliases)
00165                && !nick_is_services_admin(target->nc)) {
00166         notice_lang(s_NickServ, u, NICK_GROUP_TOO_MANY, target->nick,
00167                     s_NickServ, s_NickServ);
00168     } else if (enc_check_password(pass, target->nc->pass) != 1) {
00169         alog("%s: Failed GROUP for %s!%s@%s (invalid password)",
00170              s_NickServ, u->nick, u->username, u->host);
00171         notice_lang(s_NickServ, u, PASSWORD_INCORRECT);
00172         bad_password(u);
00173     } else {
00174         /* If the nick is already registered, drop it.
00175          * If not, check that it is valid.
00176          */
00177         if (u->na) {
00178             delnick(u->na);
00179         } else {
00180             int prefixlen = strlen(NSGuestNickPrefix);
00181             int nicklen = strlen(u->nick);
00182 
00183             if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1
00184                 && stristr(u->nick, NSGuestNickPrefix) == u->nick
00185                 && strspn(u->nick + prefixlen,
00186                           "1234567890") == nicklen - prefixlen) {
00187                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00188                             u->nick);
00189                 return MOD_CONT;
00190             }
00191         }
00192         na = makealias(u->nick, target->nc);
00193 
00194         if (na) {
00195             na->last_usermask =
00196                 scalloc(strlen(common_get_vident(u)) +
00197                         strlen(common_get_vhost(u)) + 2, 1);
00198             sprintf(na->last_usermask, "%s@%s", common_get_vident(u),
00199                     common_get_vhost(u));
00200             na->last_realname = sstrdup(u->realname);
00201             na->time_registered = na->last_seen = time(NULL);
00202             na->status = (int16) (NS_IDENTIFIED | NS_RECOGNIZED);
00203 
00204             if (!(na->nc->flags & NI_SERVICES_ROOT)) {
00205                 for (i = 0; i < RootNumber; i++) {
00206                     if (!stricmp(ServicesRoots[i], u->nick)) {
00207                         na->nc->flags |= NI_SERVICES_ROOT;
00208                         break;
00209                     }
00210                 }
00211             }
00212 
00213             u->na = na;
00214             na->u = u;
00215 
00216 #ifdef USE_RDB
00217             /* Is this really needed? Since this is a new alias it will get
00218              * its unique id on the next update, since it was previously
00219              * deleted by delnick. Must observe...
00220              */
00221             if (rdb_open()) {
00222                 rdb_save_ns_alias(na);
00223                 rdb_close();
00224             }
00225 #endif
00226             send_event(EVENT_GROUP, 1, u->nick);
00227             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"));
00228             notice_lang(s_NickServ, u, NICK_GROUP_JOINED, target->nick);
00229 
00230             u->lastnickreg = time(NULL);
00231             snprintf(tsbuf, sizeof(tsbuf), "%lu",
00232                      (unsigned long int) u->timestamp);
00233             if (ircd->modeonreg) {
00234                 len = strlen(ircd->modeonreg);
00235                 strncpy(modes,ircd->modeonreg,512);
00236            if(ircd->rootmodeonid && is_services_root(u)) { 
00237                     strncat(modes,ircd->rootmodeonid,512-len);
00238             } else if(ircd->adminmodeonid && is_services_admin(u)) {
00239                     strncat(modes,ircd->adminmodeonid,512-len);
00240             } else if(ircd->opermodeonid && is_services_oper(u)) {
00241                     strncat(modes,ircd->opermodeonid,512-len);
00242                 }
00243                 if (ircd->tsonmode) {
00244                     common_svsmode(u, modes, tsbuf);
00245                 } else {
00246                     common_svsmode(u, modes, NULL);
00247                 }
00248             }
00249 
00250             check_memos(u);
00251         } else {
00252             alog("%s: makealias(%s) failed", s_NickServ, u->nick);
00253             notice_lang(s_NickServ, u, NICK_GROUP_FAILED);
00254         }
00255     }
00256     return MOD_CONT;
00257 }
00258 
00259 
00260 /* Creates a new alias in NickServ database. */
00261 
00262 NickAlias *makealias(const char *nick, NickCore * nc)
00263 {
00264     NickAlias *na;
00265 
00266     /* Just need to make the alias */
00267     na = scalloc(1, sizeof(NickAlias));
00268     na->nick = sstrdup(nick);
00269     na->nc = nc;
00270     slist_add(&nc->aliases, na);
00271     alpha_insert_alias(na);
00272     return na;
00273 }
00274 
00275 
00276 int do_link(User * u)
00277 {
00278     notice_lang(s_NickServ, u, OBSOLETE_COMMAND, "GROUP");
00279     return MOD_CONT;
00280 }
00281 
00282 int do_glist(User * u)
00283 {
00284     char *nick = strtok(NULL, " ");
00285 
00286     NickAlias *na, *na2;
00287     int is_servadmin = is_services_admin(u);
00288     int nick_ided = nick_identified(u);
00289     int i;
00290 
00291     if ((nick ? (stricmp(nick, u->nick) ? !is_servadmin : !nick_ided)
00292          : !nick_ided)) {
00293         notice_lang(s_NickServ, u,
00294                     (nick_ided ? ACCESS_DENIED :
00295                      NICK_IDENTIFY_REQUIRED), s_NickServ);
00296     } else if ((!nick ? !(na = u->na) : !(na = findnick(nick)))) {
00297         notice_lang(s_NickServ, u,
00298                     (!nick ? NICK_NOT_REGISTERED : NICK_X_NOT_REGISTERED),
00299                     nick);
00300     } else if (na->status & NS_VERBOTEN) {
00301         notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
00302     } else {
00303         time_t expt;
00304         struct tm *tm;
00305         char buf[BUFSIZE];
00306         int wont_expire;
00307 
00308         notice_lang(s_NickServ, u,
00309                     nick ? NICK_GLIST_HEADER_X : NICK_GLIST_HEADER,
00310                     na->nc->display);
00311         for (i = 0; i < na->nc->aliases.count; i++) {
00312             na2 = na->nc->aliases.list[i];
00313             if (na2->nc == na->nc) {
00314                 if (!(wont_expire = na2->status & NS_NO_EXPIRE)) {
00315                     expt = na2->last_seen + NSExpire;
00316                     tm = localtime(&expt);
00317                     strftime_lang(buf, sizeof(buf), na2->u,
00318                                   STRFTIME_DATE_TIME_FORMAT, tm);
00319                 }
00320                 notice_lang(s_NickServ, u,
00321                             ((is_services_admin(u) && !wont_expire)
00322                              ? NICK_GLIST_REPLY_ADMIN : NICK_GLIST_REPLY),
00323                             (wont_expire ? '!' : ' '), na2->nick, buf);
00324             }
00325         }
00326         notice_lang(s_NickServ, u, NICK_GLIST_FOOTER,
00327                     na->nc->aliases.count);
00328     }
00329     return MOD_CONT;
00330 }
00331 
00332 
00333 int do_listlinks(User * u)
00334 {
00335     notice_lang(s_NickServ, u, OBSOLETE_COMMAND, "GLIST");
00336     return MOD_CONT;
00337 }

Generated on Sun Dec 30 09:26:47 2007 for Anope by  doxygen 1.5.1-20070107