/* * linker_open_ext() * * Inputs: * path to file to open * * Outputs: * linker handle * * Side Effects: * the extension is appended if it's not already there. * a shared module is loaded into the application's memory space */ mowgli_module_t *linker_open_ext(const char *path, char *errbuf, int errlen) { size_t len = strlen(path) + 20; char *buf = smalloc(len); void *ret; mowgli_strlcpy(buf, path, len); if (!strstr(buf, PLATFORM_SUFFIX)) mowgli_strlcat(buf, PLATFORM_SUFFIX, len); /* Don't try to open a file that doesn't exist. */ struct stat s; if (0 != stat(buf, &s)) { mowgli_strlcpy(errbuf, strerror(errno), errlen); free(buf); return NULL; } ret = mowgli_module_open(buf); free(buf); if (!ret) mowgli_strlcpy(errbuf, "mowgli_module_open() failed", errlen); return ret; }
static void opensex_db_close(database_handle_t *db) { opensex_t *rs; int errno1; char oldpath[BUFSIZE], newpath[BUFSIZE]; return_if_fail(db != NULL); rs = db->priv; mowgli_strlcpy(oldpath, db->file, sizeof oldpath); mowgli_strlcat(oldpath, ".new", sizeof oldpath); mowgli_strlcpy(newpath, db->file, sizeof newpath); fclose(rs->f); if (db->txn == DB_WRITE) { /* now, replace the old database with the new one, using an atomic rename */ if (srename(oldpath, newpath) < 0) { errno1 = errno; slog(LG_ERROR, "db_save(): cannot rename services.db.new to services.db: %s", strerror(errno1)); wallops(_("\2DATABASE ERROR\2: db_save(): cannot rename services.db.new to services.db: %s"), strerror(errno1)); } hook_call_db_saved(); } free(rs->buf); free(rs); free(db->file); free(db); }
static void check_registration(hook_user_register_check_t *hdata) { char buf[1024]; const char *user; const char *domain; int count; pid_t pid; struct procdata *pd; if (hdata->approved) return; if (proccount >= MAX_CHILDPROCS) { command_fail(hdata->si, fault_toomany, "Sorry, too many registrations in progress. Try again later."); hdata->approved = 1; return; } switch (pid = fork()) { case 0: /* child */ connection_close_all_fds(); mowgli_strlcpy(buf, hdata->email, sizeof buf); user = strtok(buf, "@"); domain = strtok(NULL, "@"); count = count_mx(domain); if (count <= 0) { /* no MX records or error */ struct hostent *host; /* attempt to resolve host (fallback to A) */ if((host = gethostbyname(domain)) == NULL) _exit(1); } _exit(0); break; case -1: /* error */ slog(LG_ERROR, "fork() failed for check_registration(): %s", strerror(errno)); command_fail(hdata->si, fault_toomany, "Sorry, too many registrations in progress. Try again later."); hdata->approved = 1; return; default: /* parent */ pd = &procdata[proccount++]; mowgli_strlcpy(pd->name, hdata->account, sizeof pd->name); mowgli_strlcpy(pd->email, hdata->email, sizeof pd->email); childproc_add(pid, "ns_mxcheck_async", childproc_cb, pd); return; } }
bool verify_password(myuser_t *mu, const char *password) { if (mu == NULL || password == NULL) return false; if (auth_module_loaded && auth_user_custom) return auth_user_custom(mu, password); if (mu->flags & MU_CRYPTPASS) if (crypto_module_loaded) { const crypt_impl_t *ci, *ci_default; ci = crypt_verify_password(password, mu->pass); if (ci == NULL) return false; if (ci == (ci_default = crypt_get_default_provider())) { if (ci->needs_param_upgrade != NULL && ci->needs_param_upgrade(mu->pass)) { slog(LG_INFO, "verify_password(): transitioning to newer parameters for crypt scheme '%s' for account '%s'", ci->id, entity(mu)->name); mowgli_strlcpy(mu->pass, ci->crypt(password, ci->salt()), PASSLEN); } } else { slog(LG_INFO, "verify_password(): transitioning from crypt scheme '%s' to '%s' for account '%s'", ci->id, ci_default->id, entity(mu)->name); mowgli_strlcpy(mu->pass, ci_default->crypt(password, ci_default->salt()), PASSLEN); } return true; } else { /* not good! * but don't complain about crypted password '*', * this is supposed to never match */ if (strcmp(password, "*")) slog(LG_ERROR, "check_password(): can't check crypted password -- no crypto module!"); return false; } else return (strcmp(mu->pass, password) == 0); }
static void ajoin_on_identify(user_t *u) { myuser_t *mu = u->myuser; metadata_t *md; char buf[512]; char *chan; if (!(md = metadata_find(mu, "private:autojoin"))) return; mowgli_strlcpy(buf, md->value, sizeof buf); chan = strtok(buf, " ,"); while (chan != NULL) { if(ircd->type == PROTOCOL_SHADOWIRCD) { sts(":%s ENCAP * SVSJOIN %s %s", ME, CLIENT_NAME(u), chan); } else { sts(":%s SVSJOIN %s %s", CLIENT_NAME(nicksvs.me->me), CLIENT_NAME(u), chan); } chan = strtok(NULL, ","); } }
static void do_packet(char *buf) { char *ptr, buf2[BUFSIZE * 2]; static char tmp[BUFSIZE * 2 + 1]; while ((ptr = strchr(buf, '\n'))) { *ptr = '\0'; if (ptr != buf && *(ptr - 1) == '\r') *(ptr - 1) = '\0'; snprintf(buf2, (BUFSIZE * 2), "%s%s", tmp, buf); *tmp = '\0'; slog(LG_DEBUG, "-{incoming}-> %s", buf2); buf = ptr + 1; } if (*buf) { mowgli_strlcpy(tmp, buf, BUFSIZE * 2); tmp[BUFSIZE * 2] = '\0'; } }
static bool do_script_list(sourceinfo_t *si) { bool retval = true; dSP; ENTER; SAVETMPS; PUSHMARK(SP); SV *arg = newSV(0); sv_setref_pv(arg, "Atheme::Sourceinfo", si); XPUSHs(sv_2mortal(arg)); PUTBACK; call_pv("Atheme::Init::list_scripts", G_EVAL | G_DISCARD); SPAGAIN; if (SvTRUE(ERRSV)) { retval = false; mowgli_strlcpy(perl_error, SvPV_nolen(ERRSV), sizeof(perl_error)); POPs; } FREETMPS; LEAVE; invalidate_object_references(); return retval; }
static bool do_script_unload(const char *filename) { bool retval = true; dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(filename, 0))); PUTBACK; call_pv("Atheme::Init::unload_script", G_EVAL | G_DISCARD); SPAGAIN; if (SvTRUE(ERRSV)) { retval = false; mowgli_strlcpy(perl_error, SvPV_nolen(ERRSV), sizeof(perl_error)); POPs; } FREETMPS; LEAVE; invalidate_object_references(); return retval; }
static int mech_step(sasl_session_t *p, char *message, int len, char **out, int *out_len) { char auth[256]; char cookie[256]; myuser_t *mu; /* Skip the authzid entirely */ len -= strlen(message) + 1; if(len <= 0) return ASASL_FAIL; message += strlen(message) + 1; /* Copy the authcid */ if(strlen(message) > 255) return ASASL_FAIL; len -= strlen(message) + 1; if(len <= 0) return ASASL_FAIL; strcpy(auth, message); message += strlen(message) + 1; /* Copy the authcookie */ if(strlen(message) > 255) return ASASL_FAIL; mowgli_strlcpy(cookie, message, len + 1); /* Done dissecting, now check. */ if(!(mu = myuser_find_by_nick(auth))) return ASASL_FAIL; p->username = strdup(auth); return authcookie_find(cookie, mu) != NULL ? ASASL_DONE : ASASL_FAIL; }
/* parse_resvconf() * * inputs - NONE * output - -1 if failure 0 if success * side effects - fills in irc_nsaddr_list */ static int parse_resvconf(void) { char *p; char *opt; char *arg; char input[DNS_MAXLINE]; FILE *file; /* XXX "/etc/resolv.conf" should be from a define in setup.h perhaps * for cygwin support etc. this hardcodes it to unix for now -db */ if ((file = fopen("/etc/resolv.conf", "r")) == NULL) return -1; while (fgets(input, sizeof(input), file) != NULL) { /* blow away any newline */ if ((p = strpbrk(input, "\r\n")) != NULL) *p = '\0'; p = input; /* skip until something thats not a space is seen */ while (isspace((unsigned char)*p)) p++; /* if at this point, have a '\0' then continue */ if (*p == '\0') continue; /* Ignore comment lines immediately */ if (*p == '#' || *p == ';') continue; /* skip until a space is found */ opt = p; while (!isspace((unsigned char)*p) && *p != '\0') p++; if (*p == '\0') continue; /* no arguments?.. ignore this line */ /* blow away the space character */ *p++ = '\0'; /* skip these spaces that are before the argument */ while (isspace((unsigned char)*p)) p++; /* Now arg should be right where p is pointing */ arg = p; if ((p = strpbrk(arg, " \t")) != NULL) *p = '\0'; /* take the first word */ if (strcmp(opt, "domain") == 0) mowgli_strlcpy(irc_domain, arg, sizeof(irc_domain)); else if (strcmp(opt, "nameserver") == 0) add_nameserver(arg); } fclose(file); return 0; }
void set_password(myuser_t *mu, const char *newpassword) { if (mu == NULL || newpassword == NULL) return; /* if we can, try to crypt it */ if (crypto_module_loaded) { mu->flags |= MU_CRYPTPASS; mowgli_strlcpy(mu->pass, crypt_string(newpassword, gen_salt()), PASSLEN); } else { mu->flags &= ~MU_CRYPTPASS; /* just in case */ mowgli_strlcpy(mu->pass, newpassword, PASSLEN); } }
static void ns_cmd_fpass(sourceinfo_t *si, int parc, char *parv[]) { char *target = parv[0]; char *password = parv[1]; char *crypt = parv[2]; myuser_t *mu = si->smu; if (!target || !password || !crypt) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FPASS"); command_fail(si, fault_needmoreparams, "Syntax: FPASS <account> <pass> [PLAIN|CRYPT]"); return; } if (auth_module_loaded) { command_fail(si, fault_noprivs, _("You must change the password in the external system.")); return; } if (!(mu = myuser_find(target))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target); return; } if (!strcasecmp(crypt, "CRYPT")) { logcommand(si, CMDLOG_SET, "FPASS: \2%s\2 CRYPTED", entity(mu)->name); mowgli_strlcpy(mu->pass, password, PASSLEN); } else if (!strcasecmp(crypt, "PLAIN")) { if (strlen(password) >= PASSLEN) { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "FPASS"); command_fail(si, fault_badparams, _("Passwords can not exceed \2%d\2 characters."), PASSLEN - 1); return; } else { logcommand(si, CMDLOG_SET, "FPASS: \2%s\2", entity(mu)->name); set_password(mu, password); } } else { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FPASS"); command_fail(si, fault_needmoreparams, "Syntax: FPASS <account> <pass> [PLAIN|CRYPT]"); return; } command_success_nodata(si, _("The password for \2%s\2 has been changed to \2%s\2."), entity(mu)->name, password); return; }
static void command_namegen(struct sourceinfo *si, int parc, char *parv[]) { unsigned int iter; unsigned int amt = 20; char buf[BUFSIZE]; struct mychan *mc; if (!gs_do_parameters(si, &parc, &parv, &mc)) return; if (parv[0]) amt = atoi(parv[0]); // limit to 20 if (amt > 20) amt = 20; *buf = '\0'; for (iter = 0; iter < amt; iter++) { char namebuf[BUFSIZE]; unsigned int medial_iter; // Here we generate the name. mowgli_strlcpy(namebuf, begin_sym[rand() % BEGIN_SYM_SZ], BUFSIZE); for (medial_iter = rand() % 3; medial_iter > 0; medial_iter--) mowgli_strlcat(namebuf, medial_sym[rand() % MEDIAL_SYM_SZ], BUFSIZE); mowgli_strlcat(namebuf, end_sym[rand() % END_SYM_SZ], BUFSIZE); if (iter == 0) mowgli_strlcpy(buf, namebuf, BUFSIZE); else mowgli_strlcat(buf, namebuf, BUFSIZE); mowgli_strlcat(buf, iter + 1 < amt ? ", " : ".", BUFSIZE); } gs_command_report(si, _("Some names to ponder: %s"), buf); }
static void parse_threshold(const char *cidr, mowgli_config_file_entry_t *entry) { int ret; threshold_t *th, *e; th = calloc(sizeof(threshold_t), 1); mowgli_config_file_entry_t *ce; char netrange[INET6_ADDRSTRLEN + 10]; char *len; mowgli_strlcpy(netrange, cidr, sizeof netrange); len = strrchr(netrange, '/'); if(len == NULL) { return; } *len++ = 0; ret = inet_pton(AF_INET, netrange, &th->ip); DPRINTF("P to n ret is %d, for %s\n", ret, netrange); if (ret != 1) { return; } th->cidrlen = atoi(len); th->etype = THRESHOLD_TYPE_ANY; MOWGLI_ITER_FOREACH(ce, entry) { if (!strcasecmp(ce->varname, "mbps")) th->mbps = atoi(ce->vardata); else if (!strcasecmp(ce->varname, "pps")) th->pps = atoi(ce->vardata); else if (!strcasecmp(ce->varname, "protocol")) { if (!strcasecmp(ce->vardata, "tcp")) th->protocol = 6; else if (!strcasecmp(ce->vardata, "tcp-syn")) { th->protocol = 6; th->tcp_synonly = 1; } else if (!strcasecmp(ce->vardata, "udp")) th->protocol = 17; else if (!strcasecmp(ce->vardata, "icmp")) th->protocol = 1; } } DPRINTF("thres: range %s - mbps %d/pps %d/proto %d\n", netrange, th->mbps, th->pps, th->protocol); th->next = th_list[th->protocol]; th_list[th->protocol] = th; }
static int mowgli_linebuf_error(mowgli_vio_t *vio) { mowgli_linebuf_t *linebuf = vio->userdata; mowgli_vio_error_t *error = &(linebuf->vio->error); if (linebuf->flags & MOWGLI_LINEBUF_ERR_READBUF_FULL) { error->op = MOWGLI_VIO_ERR_OP_READ; error->type = MOWGLI_VIO_ERR_CUSTOM; mowgli_strlcpy(error->string, "Read buffer full", sizeof(error->string)); } else if (linebuf->flags & MOWGLI_LINEBUF_ERR_WRITEBUF_FULL) { error->op = MOWGLI_VIO_ERR_OP_WRITE; error->type = MOWGLI_VIO_ERR_CUSTOM; mowgli_strlcpy(error->string, "Write buffer full", sizeof(error->string)); } /* Pass this up to higher callback */ return mowgli_vio_error(vio); }
/* * +f *X:Y (handled by check_flood_old) * +f X:Y (handled by check_flood_old) * * +f [<number><letter>(#<letter>)(,...)] */ static bool check_flood(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu) { char evalbuf[BUFSIZE], *ep, *p; if (*value != '[') return check_flood_old(value, c, mc, u, mu); /* copy this to a local buffer for evaluation */ mowgli_strlcpy(evalbuf, value, sizeof evalbuf); ep = evalbuf + 1; /* check that the parameter ends with a ] */ if ((p = strchr(ep, ']')) == NULL) return false; /* we have a ], blast it away and check for a colon. */ *p = '\0'; if (*(p + 1) != ':') return false; for (p = strtok(ep, ","); p != NULL; p = strtok(NULL, ",")) { while (isdigit(*p)) p++; if (!VALID_FLOOD_CHAR(*p)) return false; *p = '\0'; p++; if (*p != '\0') { if (*p == '#') { p++; if (!VALID_ACTION_CHAR(*p)) return false; } /* not valid, needs to be # or nothing */ return false; } } return true; }
void decode_p10_ip(const char *b64, char ipstring[HOSTIPLEN]) { struct in_addr ip; char buf[4]; int i, j; size_t len; ipstring[0] = '\0'; len = strlen(b64); if (len == 6) { ip.s_addr = ntohl(base64touint(b64)); if (!inet_ntop(AF_INET, &ip, ipstring, HOSTIPLEN)) ipstring[0] = '\0'; } else if (len == 24 || (len < 24 && strchr(b64, '_'))) { /* why is this encoded in such a complicated manner? */ i = 0; j = 0; while (b64[i] != '\0') { if (b64[i] == '_') { i++; if (j >= HOSTIPLEN - 2) break; if (j == 0) ipstring[j++] = '0'; if (b64[i] == '\0') ipstring[j++] = ':'; ipstring[j++] = ':'; } else { if (j >= HOSTIPLEN - 5) break; if (j != 0) ipstring[j++] = ':'; mowgli_strlcpy(buf, b64 + i, 4); i += strlen(buf); j += sprintf(ipstring + j, "%x", (uint16_t)base64touint(buf)); } } ipstring[j] = '\0'; } }
static bool evaluate_condition(sourceinfo_t *si, const char *s) { char word[80]; char *p, *q; while (*s == ' ' || *s == '\t') s++; if (*s == '!') return !evaluate_condition(si, s + 1); mowgli_strlcpy(word, s, sizeof word); p = strchr(word, ' '); if (p != NULL) { *p++ = '\0'; while (*p == ' ' || *p == '\t') p++; } if (!strcmp(word, "halfops")) return ircd->uses_halfops; else if (!strcmp(word, "owner")) return ircd->uses_owner; else if (!strcmp(word, "protect")) return ircd->uses_protect; else if (!strcmp(word, "anyprivs")) return has_any_privs(si); else if (!strcmp(word, "priv")) { if (p != NULL && (q = strchr(p, ' ')) != NULL) *q = '\0'; return has_priv(si, p); } else if (!strcmp(word, "module")) { if (p != NULL && (q = strchr(p, ' ')) != NULL) *q = '\0'; return module_find_published(p) != NULL; } else if (!strcmp(word, "auth")) return me.auth != AUTH_NONE; else return false; }
static void conf_listen_port(mowgli_config_file_t *cf, mowgli_config_file_entry_t *ce) { ushort low, hi; char buf[512]; char *s, *lows, *his; mowgli_strlcpy(buf, ce->vardata, sizeof buf); lows = buf; his = NULL; if ((s = strstr(buf, "..")) || (s = strstr(buf, "-"))) { *s++ = '\0'; while (*s && !isdigit(*s)) s++; his = s; } low = atoi(lows); hi = (his && *his) ? atoi(his) : low; if (low == 0 || hi == 0) { u_log(LG_ERROR, "%s: invalid listen range string", ce->vardata); return; } if (hi < low) { u_log(LG_ERROR, "%u-%u: invalid listen range", low, hi); return; } if (hi - low > 20) { u_log(LG_ERROR, "%u-%u: listener range too large", low, hi); return; } for (; low <= hi; low++) { u_log(LG_DEBUG, "Listening on %u", low); u_link_origin_create(base_ev, low); } }
static database_handle_t *opensex_db_open_write(const char *filename) { database_handle_t *db; opensex_t *rs; int fd; FILE *f; int errno1; char bpath[BUFSIZE], path[BUFSIZE]; snprintf(bpath, BUFSIZE, "%s/%s", datadir, filename != NULL ? filename : "services.db"); mowgli_strlcpy(path, bpath, sizeof path); mowgli_strlcat(path, ".new", sizeof path); fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fd < 0 || ! (f = fdopen(fd, "w"))) { errno1 = errno; slog(LG_ERROR, "db-open-write: cannot open '%s' for writing: %s", path, strerror(errno1)); wallops(_("\2DATABASE ERROR\2: db-open-write: cannot open '%s' for writing: %s"), path, strerror(errno1)); return NULL; } rs = scalloc(sizeof(opensex_t), 1); rs->f = f; rs->grver = 1; db = scalloc(sizeof(database_handle_t), 1); db->priv = rs; db->vt = &opensex_vt; db->txn = DB_WRITE; db->file = sstrdup(bpath); db->line = 0; db->token = 0; db_start_row(db, "GRVER"); db_write_int(db, rs->grver); db_commit_row(db); return db; }
mowgli_linebuf_t * new_conn(const char * host, const char * port, bool use_ssl, mowgli_linebuf_readline_cb_t *cb, void * udata) { struct addrinfo hints, * res; mowgli_vio_sockaddr_t addr; mowgli_linebuf_t * linebuf; int ret; linebuf = mowgli_linebuf_create(cb, udata); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((ret = getaddrinfo(host, port, &hints, &res)) != 0) { linebuf->vio->error.op = MOWGLI_VIO_ERR_OP_OTHER; linebuf->vio->error.type = MOWGLI_VIO_ERR_ERRCODE; linebuf->vio->error.code = ret; mowgli_strlcpy(linebuf->vio->error.string, gai_strerror(ret), sizeof(linebuf->vio->error.string)); mowgli_vio_error(linebuf->vio); return NULL; } if (use_ssl) if (mowgli_vio_openssl_setssl(linebuf->vio, NULL, NULL) != 0) return NULL; if (mowgli_vio_socket(linebuf->vio, res->ai_family, res->ai_socktype, res->ai_protocol) != 0) return NULL; mowgli_linebuf_attach_to_eventloop(linebuf, me.ev); if (mowgli_vio_connect(linebuf->vio, mowgli_vio_sockaddr_from_struct(&addr, res->ai_addr, res->ai_addrlen)) != 0) return NULL; return linebuf; }
static void ns_cmd_generatehash(sourceinfo_t *si, int parc, char *parv[]) { char *pass = parv[0]; char hash[PASSLEN]; if (parc < 1) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "GENERATEHASH"); command_fail(si, fault_needmoreparams, _("Syntax: GENERATEHASH <password>")); return; } if (crypto_module_loaded) { mowgli_strlcpy(hash, crypt_string(pass, gen_salt()), PASSLEN); command_success_string(si, hash, "Hash is: %s", hash); } else command_success_nodata(si, "No crypto module loaded so could not hash anything."); logcommand(si, CMDLOG_GET, "GENERATEHASH"); }
static void do_packet(connection_t *cptr, char *buf) { char *ptr, buf2[BUFSIZE * 2]; static char tmp[BUFSIZE * 2 + 1]; while ((ptr = strchr(buf, '\n'))) { snprintf(buf2, (BUFSIZE * 2), "%s%s", tmp, buf); *tmp = '\0'; slog(LG_DEBUG, "-{incoming}-> %s", buf2); sendq_add(cptr, buf2, strlen(buf2)); buf = ptr + 1; } if (*buf) { mowgli_strlcpy(tmp, buf, BUFSIZE * 2); tmp[BUFSIZE * 2] = '\0'; } }
static void command_df(sourceinfo_t *si, int parc, char *parv[]) { mychan_t *mc; char *arg_dice; char buf[BUFSIZE]; int i, dice; if (!gs_do_parameters(si, &parc, &parv, &mc)) return; if (parc < 1) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DF"); command_fail(si, fault_needmoreparams, _("Syntax: DF <dice>")); return; } arg_dice = parv[0]; dice = atoi(arg_dice); *buf = '\0'; if (dice > 30 || dice < 1) { command_fail(si, fault_badparams, _("Only 1-30 dice may be thrown at one time.")); return; } for (i = 0; i < dice; i++) { int roll = arc4random() % 3; if (*buf != '\0') mowgli_strlcat(buf, df_dice_table[roll], BUFSIZE); else mowgli_strlcpy(buf, df_dice_table[roll], BUFSIZE); } gs_command_report(si, _("Result: %s"), buf); }
static void check_registration(hook_user_register_check_t *hdata) { char buf[1024]; const char *user; const char *domain; int count; if (hdata->approved) return; mowgli_strlcpy(buf, hdata->email, sizeof buf); user = strtok(buf, "@"); domain = strtok(NULL, "@"); count = count_mx(domain); if (count > 0) { /* there are MX records for this domain */ slog(LG_INFO, "REGISTER: mxcheck: %d MX records for %s", count, domain); } else { /* no MX records or error */ struct hostent *host; /* attempt to resolve host (fallback to A) */ if((host = gethostbyname(domain)) == NULL) { slog(LG_INFO, "REGISTER: mxcheck: no A/MX records for %s - " "REGISTER failed", domain); command_fail(hdata->si, fault_noprivs, "Sorry, \2%s\2 does not exist, " "I can't send mail there. Please check and try again.", domain); hdata->approved = 1; return; } } }
void module_cons(mowgli_eventloop_t *eventloop, mowgli_config_file_entry_t *entry) { mowgli_config_file_entry_t *ce; MOWGLI_ITER_FOREACH(ce, entry) { nullable_t *e; char cidr[INET6_ADDRSTRLEN + 10]; char *len; mowgli_strlcpy(cidr, ce->varname, sizeof cidr); len = strrchr(cidr, '/'); if (len == NULL) continue; *len++ = 0; e = calloc(sizeof(nullable_t), 1); e->next = e_list; inet_pton(AF_INET, cidr, &e->ip); e->cidrlen = atoi(len); e->etype = NULLABLE_TYPE_ANY; if (!strcasecmp(ce->vardata, "any")) e->etype = NULLABLE_TYPE_ANY; else if (!strcasecmp(ce->vardata, "src")) e->etype = NULLABLE_TYPE_SRC; else if (!strcasecmp(ce->vardata, "dst")) e->etype = NULLABLE_TYPE_DST; e->val = nullable_validator_tab[e->etype]; DPRINTF("cidr: %s/%d type %d (%s)\n", cidr, e->cidrlen, e->etype, ce->vardata); e_list = e; }
/* * user_delete(user_t *u, const char *comment) * * Destroys a user object and deletes the object from the users DTree. * * Inputs: * - user object to delete * - quit comment * * Outputs: * - nothing * * Side Effects: * - on success, a user is deleted from the users DTree. */ void user_delete(user_t *u, const char *comment) { mowgli_node_t *n, *tn; chanuser_t *cu; mynick_t *mn; char oldnick[NICKLEN]; bool doenforcer = false; return_if_fail(u != NULL); if (u->flags & UF_DOENFORCE) { doenforcer = true; mowgli_strlcpy(oldnick, u->nick, sizeof oldnick); u->flags &= ~UF_DOENFORCE; } if (!comment) comment = ""; slog(LG_DEBUG, "user_delete(): removing user: %s -> %s (%s)", u->nick, u->server->name, comment); hook_call_user_delete_info((&(hook_user_delete_t){ .u = u, .comment = comment}));
static mowgli_node_t *charybdis_next_matching_ban(channel_t *c, user_t *u, int type, mowgli_node_t *first) { chanban_t *cb; mowgli_node_t *n; char hostbuf[NICKLEN+USERLEN+HOSTLEN]; char realbuf[NICKLEN+USERLEN+HOSTLEN]; char ipbuf[NICKLEN+USERLEN+HOSTLEN]; char strippedmask[NICKLEN+USERLEN+HOSTLEN+CHANNELLEN+2]; char *p; bool negate, matched; int exttype; channel_t *target_c; snprintf(hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); snprintf(realbuf, sizeof realbuf, "%s!%s@%s", u->nick, u->user, u->host); /* will be nick!user@ if ip unknown, doesn't matter */ snprintf(ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); MOWGLI_ITER_FOREACH(n, first) { cb = n->data; if (cb->type != type) continue; /* * strip any banforwards from the mask. (SRV-73) * charybdis itself doesn't support banforward but i don't feel like copying * this stuff into ircd-seven and it is possible that charybdis may support them * one day. * --nenolod */ mowgli_strlcpy(strippedmask, cb->mask, sizeof strippedmask); p = strrchr(strippedmask, '$'); if (p != NULL && p != strippedmask) *p = 0; if ((!match(strippedmask, hostbuf) || !match(strippedmask, realbuf) || !match(strippedmask, ipbuf) || !match_cidr(strippedmask, ipbuf))) return n; if (strippedmask[0] == '$') { p = strippedmask + 1; negate = *p == '~'; if (negate) p++; exttype = *p++; if (exttype == '\0') continue; /* check parameter */ if (*p++ != ':') p = NULL; switch (exttype) { case 'a': matched = u->myuser != NULL && !(u->myuser->flags & MU_WAITAUTH) && (p == NULL || !match(p, entity(u->myuser)->name)); break; case 'c': if (p == NULL) continue; target_c = channel_find(p); if (target_c == NULL || (target_c->modes & (CMODE_PRIV | CMODE_SEC))) continue; matched = chanuser_find(target_c, u) != NULL; break; case 'o': matched = is_ircop(u); break; case 'r': if (p == NULL) continue; matched = !match(p, u->gecos); break; case 's': if (p == NULL) continue; matched = !match(p, u->server->name); break; case 'x': if (p == NULL) continue; matched = extgecos_match(p, u); break; default: continue; } if (negate ^ matched) return n; } }
static void cs_cmd_topicswap(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *topic = parv[1]; mychan_t *mc; channel_t *c; const char *topicsetter; time_t prevtopicts; char topicbuf[BUFSIZE]; char commbuf[BUFSIZE]; char *pos = NULL; char *search = NULL; char *replace = NULL; size_t search_size = 0; size_t replace_size = 0; size_t copylen = 0; if (parc < 2) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "TOPICSWAP"); command_fail(si, fault_needmoreparams, _("Syntax: TOPICSWAP <#channel> <search>:[<replace>]")); return; } mowgli_strlcpy(commbuf, parv[1], BUFSIZE); search = commbuf; pos = strrchr(commbuf, ':'); if (!pos || pos == commbuf) { command_fail(si, fault_badparams, STR_INSUFFICIENT_PARAMS, "TOPICSWAP"); command_fail(si, fault_badparams, _("Syntax: TOPICSWAP <#channel> <search>:[<replace>]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } c = channel_find(chan); if (!c) { command_fail(si, fault_nosuch_target, _("\2%s\2 is currently empty."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_TOPIC)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } if (!c->topic) topicbuf[0] = '\0'; else mowgli_strlcpy(topicbuf, c->topic, BUFSIZE); *pos = '\0'; replace = pos + 1; search_size = strlen(search); replace_size = strlen(replace); pos = strstr(topicbuf, search); if (!pos) { command_fail(si, fault_badparams, _("Channel \2%s\2 does not have \2%s\2 in its topic."), chan, search); return; } copylen = strlen(pos + search_size) + 1; if (pos - topicbuf + replace_size + copylen > BUFSIZE) goto invalid_error; memmove(pos + search_size + (replace_size - search_size), pos + search_size, copylen); memcpy(pos, replace, replace_size); if (!validtopic(topicbuf)) { invalid_error: command_fail(si, fault_badparams, _("The new topic is invalid or too long.")); return; } if (si->su != NULL) topicsetter = si->su->nick; else if (si->smu != NULL) topicsetter = entity(si->smu)->name; else topicsetter = "unknown"; prevtopicts = c->topicts; handle_topic(c, topicsetter, CURRTIME, topicbuf); topic_sts(c, si->service->me, topicsetter, CURRTIME, prevtopicts, topicbuf); logcommand(si, CMDLOG_DO, "TOPICSWAP: \2%s\2", mc->name); if (si->su == NULL || !chanuser_find(c, si->su)) command_success_nodata(si, _("Topic set to \2%s\2 on \2%s\2."), c->topic, chan); }
static void cs_cmd_topicprepend(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *topic = parv[1]; mychan_t *mc; char topicbuf[BUFSIZE]; channel_t *c; const char *topicsetter; time_t prevtopicts; if (!chan || !topic) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "TOPICPREPEND"); command_fail(si, fault_needmoreparams, _("Syntax: TOPICPREPEND <#channel> <topic>")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } c = channel_find(chan); if (!c) { command_fail(si, fault_nosuch_target, _("\2%s\2 is currently empty."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_TOPIC)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } topicbuf[0] = '\0'; if (c->topic) { mowgli_strlcpy(topicbuf, topic, BUFSIZE); mowgli_strlcat(topicbuf, " | ", BUFSIZE); mowgli_strlcat(topicbuf, c->topic, BUFSIZE); } else mowgli_strlcpy(topicbuf, topic, BUFSIZE); if (!validtopic(topicbuf)) { command_fail(si, fault_badparams, _("The new topic is invalid or too long.")); return; } if (si->su != NULL) topicsetter = si->su->nick; else if (si->smu != NULL) topicsetter = entity(si->smu)->name; else topicsetter = "unknown"; prevtopicts = c->topicts; handle_topic(c, topicsetter, CURRTIME, topicbuf); topic_sts(c, si->service->me, topicsetter, CURRTIME, prevtopicts, topicbuf); logcommand(si, CMDLOG_DO, "TOPICPREPEND: \2%s\2", mc->name); if (si->su == NULL || !chanuser_find(c, si->su)) command_success_nodata(si, _("Topic set to \2%s\2 on \2%s\2."), c->topic, chan); }