/** * Restart a service * @param dcb Client DCB * @param tree Parse tree */ void exec_restart_service(DCB *dcb, MAXINFO_TREE *tree) { char errmsg[120]; if (tree && tree->value) { SERVICE* service = service_find(tree->value); if (service) { serviceRestart(service); maxinfo_send_ok(dcb); } else { if (strlen(tree->value) > 80) // Prevent buffer overrun { tree->value[80] = 0; } sprintf(errmsg, "Invalid argument '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); } } else { sprintf(errmsg, "Missing argument for 'RESTART SERVICE'"); maxinfo_send_error(dcb, 0, errmsg); } }
int service_start(const char *method, const char *host, const char *uri, const struct module **module, struct data **app_data) { const struct service *serv; const struct module *mod; const char *module_arg; serv = service_find(host, uri); if (!serv) { Error("%s:could not find URI path\n", uri); return -1; } mod = service_module(serv); if (!mod) { Error("%s:no module defined\n", uri); return -1; } module_arg = service_arg(serv); *app_data = module_start(mod, method, uri, module_arg); *module = mod; // TODO: check for error?? Info("%s:using module %s\n", uri, mod->desc); return 0; }
static void os_cmd_helpme(sourceinfo_t *si, int parc, char *parv[]) { service_t *svs; svs = service_find("operserv"); sts(":%s MODE %s :+h", svs->nick, si->su->nick); command_success_nodata(si, _("You are now a network helper.")); }
void _moddeinit(module_unload_intent_t intent) { service_t *svs; service_named_unbind_command("chanserv", &cmd_dice); service_named_unbind_command("chanserv", &cmd_calc); svs = service_find("gameserv"); if (!svs) return; service_unbind_command(svs, &cmd_dice); service_unbind_command(svs, &cmd_calc); del_conf_item("MAX_ROLLS", &svs->conf_table); }
void _modinit(module_t * m) { service_t *svs; service_named_bind_command("chanserv", &cmd_dice); service_named_bind_command("chanserv", &cmd_calc); svs = service_find("gameserv"); if (!svs) return; service_bind_command(svs, &cmd_dice); service_bind_command(svs, &cmd_calc); add_uint_conf_item("MAX_ROLLS", &svs->conf_table, 0, &max_rolls, 1, INT_MAX, 10); }
static void qserver_readable(struct io_fd *fd) { struct qserverClient *client; struct service *service; char *argv[MAXNUMPARAMS]; unsigned int argc; size_t len; int res; char tmpline[MAXLEN]; client = fd->data; assert(client->fd == fd); res = ioset_line_read(fd, tmpline, sizeof(tmpline)); if (res < 0) return; else if (res == 0) { ioset_close(fd, 1); return; } len = strlen(tmpline); while (tmpline[len - 1] == '\r' || tmpline[len - 1] == '\n') tmpline[--len] = '\0'; argc = split_line(tmpline, false, ArrayLength(argv), argv); if (argc < 3) { ioset_printf(fd, "MISSING_ARGS\n"); return; } if (!strcmp(argv[1], "PASS") && conf.password && !strcmp(argv[2], conf.password)) { client->password_ok = 1; } else if ((client->password_ok || !conf.password) && (service = service_find(argv[1])) != NULL) { ioset_printf(fd, "%s S\n", argv[0]); svccmd_invoke_argv(client->user, service, NULL, argc - 2, argv + 2, 1); ioset_printf(fd, "%s E\n", argv[0]); } else { ioset_printf(fd, "%s X %s\n", argv[0], argv[1]); } }
static void gs_cmd_invite(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; myuser_t *mu; groupacs_t *ga; char *group = parv[0]; char *user = parv[1]; char buf[BUFSIZE], description[256]; service_t *svs; if (!group || !user) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "INVITE"); command_fail(si, fault_needmoreparams, _("Syntax: INVITE <!group> <user>")); return; } if ((mg = mygroup_find(group)) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), group); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_INVITE)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if ((mu = myuser_find_ext(user)) == NULL) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered account."), user); return; } if ((ga = groupacs_find(mg, entity(mu), 0, false)) != NULL) { command_fail(si, fault_badparams, _("\2%s\2 is already a member of: \2%s\2"), entity(mu)->name, entity(mg)->name); return; } if (metadata_find(mu, "private:groupinvite")) { command_fail(si, fault_badparams, _("\2%s\2 may not be invited to a group and already has another invitation pending."), entity(mu)->name); return; } if (MU_NEVERGROUP & mu->flags) { command_fail(si, fault_noprivs, _("\2%s\2 does not wish to belong to any groups."), entity(mu)->name); return; } metadata_add(mu, "private:groupinvite", entity(mg)->name); if ((svs = service_find("memoserv")) != NULL) { snprintf(buf, BUFSIZE, "%s [auto memo] You have been invited to the group: %s", entity(mu)->name, entity(mg)->name); command_exec_split(svs, si, "SEND", buf, svs->commands); } else { myuser_notice(si->service->nick, mu, "You have been invited to the group: %s", entity(mg)->name); } logcommand(si, CMDLOG_SET, "INVITE: \2%s\2 \2%s\2", entity(mg)->name, entity(mu)->name); command_success_nodata(si, _("\2%s\2 has been invited to \2%s\2"), entity(mu)->name, entity(mg)->name); snprintf(description, sizeof description, "Invited \2%s\2 to join.", entity(mu)->name); notify_group_misc_change(si, mg, description); }
static struct servicelist * service_valid( char *service ) { struct servicelist *sl; regex_t preg; regmatch_t svm[ 2 ]; char buf[ 1024 ]; char *p; int rc; /* limit access to CNs with matching cookies */ if (( p = strchr( service, '=' )) == NULL ) { syslog( LOG_ERR, "service_valid: %s missing \"=\"", service ); return( NULL ); } *p = '\0'; if (( sl = service_find( service, svm, 2 )) == NULL ) { syslog( LOG_ERR, "service_valid: no matching service for %s", service ); return( NULL ); } /* XXX cosign3 - save compiled regex in sl->sl_auth? */ if (( rc = regcomp( &preg, sl->sl_auth->al_hostname, REG_EXTENDED)) != 0 ) { regerror( rc, &preg, buf, sizeof( buf )); syslog( LOG_ERR, "service_valid: regcomp %s: %s", sl->sl_auth->al_hostname, buf ); return( NULL ); } if (( rc = regexec( &preg, remote_cn, 2, svm, 0 )) != 0 ) { if ( rc == REG_NOMATCH ) { syslog( LOG_ERR, "service_valid: CN %s not allowed " "access to cookie %s (no match)", remote_cn, service ); } else { regerror( rc, &preg, buf, sizeof( buf )); syslog( LOG_ERR, "service_valid: regexec: %s\n", buf ); } sl = NULL; goto service_valid_done; } /* only match whole CNs */ if ( svm[ 0 ].rm_so != 0 || svm[ 0 ].rm_eo != strlen( remote_cn )) { syslog( LOG_ERR, "service_valid: CN %s not allowed " "access to cookie %s (partial match)", remote_cn, service ); sl = NULL; goto service_valid_done; } /* * if there's a custom cookie substitution pattern, use it. * otherwise, the service_find call + the regexec above * verifies that the CN has access to the cookie. */ if ( sl->sl_cookiesub != NULL ) { if ( match_substitute( sl->sl_cookiesub, sizeof( buf ), buf, 2, svm, remote_cn ) != 0 ) { syslog( LOG_ERR, "service_find: match_substitute failed" ); sl = NULL; goto service_valid_done; } if ( strcmp( service, buf ) != 0 ) { syslog( LOG_ERR, "service_valid: CN %s not allowed access " "to cookie %s (%s != %s)\n", remote_cn, service, service, buf ); sl = NULL; } } *p = '='; service_valid_done: regfree( &preg ); return( sl ); }
/* * atheme.command * * XML inputs: * authcookie, account name, source ip, service name, command name, * parameters. * * XML outputs: * depends on command * * Side Effects: * command is executed */ static int xmlrpcmethod_command(void *conn, int parc, char *parv[]) { myuser_t *mu; service_t *svs; command_t *cmd; sourceinfo_t *si; int newparc; char *newparv[20]; struct httpddata *hd = ((connection_t *)conn)->userdata; int i; for (i = 0; i < parc; i++) { if (*parv[i] == '\0' || strchr(parv[i], '\r') || strchr(parv[i], '\n')) { xmlrpc_generic_error(fault_badparams, "Invalid parameters."); return 0; } } if (parc < 5) { xmlrpc_generic_error(fault_needmoreparams, "Insufficient parameters."); return 0; } if (*parv[1] != '\0' && strlen(parv[0]) > 1) { if ((mu = myuser_find(parv[1])) == NULL) { xmlrpc_generic_error(fault_nosuch_source, "Unknown user."); return 0; } if (authcookie_validate(parv[0], mu) == false) { xmlrpc_generic_error(fault_badauthcookie, "Invalid authcookie for this account."); return 0; } } else mu = NULL; /* try literal service name first, then user-configured nickname. */ svs = service_find(parv[3]); if ((svs == NULL && (svs = service_find_nick(parv[3])) == NULL) || svs->commands == NULL) { slog(LG_DEBUG, "xmlrpcmethod_command(): invalid service %s", parv[3]); xmlrpc_generic_error(fault_nosuch_source, "Invalid service name."); return 0; } cmd = command_find(svs->commands, parv[4]); if (cmd == NULL) { xmlrpc_generic_error(fault_nosuch_source, "Invalid command name."); return 0; } memset(newparv, '\0', sizeof newparv); newparc = parc - 5; if (newparc > 20) newparc = 20; if (newparc > 0) memcpy(newparv, parv + 5, newparc * sizeof(parv[0])); si = sourceinfo_create(); si->smu = mu; si->service = svs; si->sourcedesc = parv[2][0] != '\0' ? parv[2] : NULL; si->connection = conn; si->v = &xmlrpc_vtable; si->force_language = language_find("en"); command_exec(svs, si, cmd, newparc, newparv); /* XXX: needs to be fixed up for restartable commands... */ if (!hd->sent_reply) { if (hd->replybuf != NULL) xmlrpc_send_string(hd->replybuf); else xmlrpc_generic_error(fault_unimplemented, "Command did not return a result."); } object_unref(si); return 0; }
/** * Create an instance of the filter for a particular service * within MaxScale. * * @param options The options for this filter * @param params The array of name/value pair parameters for the filter * * @return The instance data for this new instance */ static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { TEE_INSTANCE *my_instance; int i; if ((my_instance = calloc(1, sizeof(TEE_INSTANCE))) != NULL) { if (options) { MXS_ERROR("tee: The tee filter has been passed an option, " "this filter does not support any options."); } my_instance->service = NULL; my_instance->source = NULL; my_instance->userName = NULL; my_instance->match = NULL; my_instance->nomatch = NULL; if (params) { for (i = 0; params[i]; i++) { if (!strcmp(params[i]->name, "service")) { if ((my_instance->service = service_find(params[i]->value)) == NULL) { MXS_ERROR("tee: service '%s' not found.\n", params[i]->value); } } else if (!strcmp(params[i]->name, "match")) { my_instance->match = strdup(params[i]->value); } else if (!strcmp(params[i]->name, "exclude")) { my_instance->nomatch = strdup(params[i]->value); } else if (!strcmp(params[i]->name, "source")) { my_instance->source = strdup(params[i]->value); } else if (!strcmp(params[i]->name, "user")) { my_instance->userName = strdup(params[i]->value); } else if (!filter_standard_parameter(params[i]->name)) { MXS_ERROR("tee: Unexpected parameter '%s'.", params[i]->name); } } } if (my_instance->service == NULL) { free(my_instance->match); free(my_instance->source); free(my_instance); return NULL; } if (my_instance->match && regcomp(&my_instance->re, my_instance->match, REG_ICASE)) { MXS_ERROR("tee: Invalid regular expression '%s'" " for the match parameter.", my_instance->match); free(my_instance->match); free(my_instance->source); free(my_instance); return NULL; } if (my_instance->nomatch && regcomp(&my_instance->nore, my_instance->nomatch, REG_ICASE)) { MXS_ERROR("tee: Invalid regular expression '%s'" " for the nomatch paramter.\n", my_instance->match); if (my_instance->match) regfree(&my_instance->re); free(my_instance->match); free(my_instance->source); free(my_instance); return NULL; } } return(FILTER *) my_instance; }
static void ms_cmd_fsend(sourceinfo_t *si, int parc, char *parv[]) { /* misc structs etc */ user_t *tu; myuser_t *tmu; mowgli_node_t *n; mymemo_t *memo; service_t *memoserv; /* Grab args */ char *target = parv[0]; char *m = parv[1]; /* Arg validation */ if (!target || !m) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FSEND"); command_fail(si, fault_needmoreparams, "Syntax: FSEND <user> <memo>"); return; } if (!si->smu) { command_fail(si, fault_noprivs, _("You are not logged in.")); return; } /* rate limit it -- jilles */ if (CURRTIME - si->smu->memo_ratelimit_time > MEMO_MAX_TIME) si->smu->memo_ratelimit_num = 0; if (si->smu->memo_ratelimit_num > MEMO_MAX_NUM && !has_priv(si, PRIV_FLOOD)) { command_fail(si, fault_toomany, _("You have used this command too many times; please wait a while and try again.")); return; } /* Check for memo text length -- includes/common.h */ if (strlen(m) >= MEMOLEN) { command_fail(si, fault_badparams, "Please make sure your memo is less than %d characters", MEMOLEN); return; } /* Check to make sure the memo doesn't contain hostile CTCP responses. * realistically, we'll probably want to check the _entire_ message for this... --nenolod */ if (*m == '\001') { command_fail(si, fault_badparams, _("Your memo contains invalid characters.")); return; } memoserv = service_find("memoserv"); if (memoserv == NULL) memoserv = si->service; if (*target != '#' && *target != '!') { /* See if target is valid */ if (!(tmu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, "\2%s\2 is not registered.", target); return; } si->smu->memo_ratelimit_num++; si->smu->memo_ratelimit_time = CURRTIME; /* Check to make sure target inbox not full */ if (tmu->memos.count >= me.mdlimit) { command_fail(si, fault_toomany, _("%s's inbox is full"), target); logcommand(si, CMDLOG_SET, "failed SEND to \2%s\2 (target inbox full)", entity(tmu)->name); return; } logcommand(si, CMDLOG_ADMIN, "FSEND: to \2%s\2", entity(tmu)->name); /* Malloc and populate struct */ memo = smalloc(sizeof(mymemo_t)); memo->sent = CURRTIME; memo->status = 0; mowgli_strlcpy(memo->sender,entity(si->smu)->name,NICKLEN); mowgli_strlcpy(memo->text, "[FORCE] ", FMEMOLEN); mowgli_strlcat(memo->text, m, FMEMOLEN); /* Create a linked list node and add to memos */ n = mowgli_node_create(); mowgli_node_add(memo, n, &tmu->memos); tmu->memoct_new++; /* Should we email this? */ if (tmu->flags & MU_EMAILMEMOS) { compat_sendemail(si->su, tmu, EMAIL_MEMO, tmu->email, memo->text); } /* Note: do not disclose other nicks they're logged in with * -- jilles * * Actually, I don't see the point in this at all. If they want this information, * they should use WHOIS. --nenolod */ tu = user_find_named(target); if (tu != NULL && tu->myuser == tmu) command_success_nodata(si, _("%s is currently online, and you may talk directly, by sending a private message."), target); /* Is the user online? If so, tell them about the new memo. */ if (si->su == NULL || !irccasecmp(si->su->nick, entity(si->smu)->name)) myuser_notice(memoserv->nick, tmu, "You have a new memo from %s (%zu).", entity(si->smu)->name, MOWGLI_LIST_LENGTH(&tmu->memos)); else myuser_notice(memoserv->nick, tmu, "You have a new memo from %s (nick: %s) (%zu).", entity(si->smu)->name, si->su->nick, MOWGLI_LIST_LENGTH(&tmu->memos)); myuser_notice(memoserv->nick, tmu, _("To read it, type /%s%s READ %zu"), ircd->uses_rcommand ? "" : "msg ", memoserv->disp, MOWGLI_LIST_LENGTH(&tmu->memos)); /* Tell user memo sent */ command_success_nodata(si, _("The memo has been successfully sent to \2%s\2."), target); } else if (*target == '#') { command_fail(si, fault_nosuch_target, _("Channel memos may not be forced.")); } else { command_fail(si, fault_nosuch_target, _("Group memos may not be forced.")); } return; }
/** * Process a configuration context update and turn it into the set of object * we need. * * @param context The configuration data */ static int process_config_update(CONFIG_CONTEXT *context) { CONFIG_CONTEXT *obj; SERVICE *service; SERVER *server; /** * Process the data and create the services and servers defined * in the data. */ obj = context; while (obj) { char *type = config_get_value(obj->parameters, "type"); if (type == NULL) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Configuration object %s has no type.", obj->object))); } else if (!strcmp(type, "service")) { char *router = config_get_value(obj->parameters, "router"); if (router) { if ((service = service_find(obj->object)) != NULL) { char *user; char *auth; char *enable_root_user; enable_root_user = config_get_value(obj->parameters, "enable_root_user"); user = config_get_value(obj->parameters, "user"); auth = config_get_value(obj->parameters, "passwd"); if (user && auth) { service_update(service, router, user, auth); if (enable_root_user) serviceEnableRootUser(service, atoi(enable_root_user)); } obj->element = service; } else { char *user; char *auth; char *enable_root_user; enable_root_user = config_get_value(obj->parameters, "enable_root_user"); user = config_get_value(obj->parameters, "user"); auth = config_get_value(obj->parameters, "passwd"); obj->element = service_alloc(obj->object, router); if (obj->element && user && auth) { serviceSetUser(obj->element, user, auth); if (enable_root_user) serviceEnableRootUser(service, atoi(enable_root_user)); } } } else { obj->element = NULL; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : No router defined for service " "'%s'.", obj->object))); } } else if (!strcmp(type, "server")) { char *address; char *port; char *protocol; char *monuser; char *monpw; address = config_get_value(obj->parameters, "address"); port = config_get_value(obj->parameters, "port"); protocol = config_get_value(obj->parameters, "protocol"); monuser = config_get_value(obj->parameters, "monitoruser"); monpw = config_get_value(obj->parameters, "monitorpw"); if (address && port && protocol) { if ((server = server_find(address, atoi(port))) != NULL) { server_update(server, protocol, monuser, monpw); obj->element = server; } else { obj->element = server_alloc(address, protocol, atoi(port)); if (obj->element && monuser && monpw) { serverAddMonUser(obj->element, monuser, monpw); } } } else { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Server '%s' is missing a " "required " "configuration parameter. A server must " "have address, port and protocol " "defined.", obj->object))); } } obj = obj->next; } /* * Now we have the services we can add the servers to the services * add the protocols to the services */ obj = context; while (obj) { char *type = config_get_value(obj->parameters, "type"); if (type == NULL) ; else if (!strcmp(type, "service")) { char *servers; char *roptions; servers = config_get_value(obj->parameters, "servers"); roptions = config_get_value(obj->parameters, "router_options"); if (servers && obj->element) { char *s = strtok(servers, ","); while (s) { CONFIG_CONTEXT *obj1 = context; while (obj1) { if (strcmp(s, obj1->object) == 0 && obj->element && obj1->element) { if (!serviceHasBackend(obj->element, obj1->element)) { serviceAddBackend( obj->element, obj1->element); } } obj1 = obj1->next; } s = strtok(NULL, ","); } } if (roptions && obj->element) { char *s = strtok(roptions, ","); serviceClearRouterOptions(obj->element); while (s) { serviceAddRouterOption(obj->element, s); s = strtok(NULL, ","); } } } else if (!strcmp(type, "listener")) { char *service; char *port; char *protocol; char *address; service = config_get_value(obj->parameters, "service"); address = config_get_value(obj->parameters, "address"); port = config_get_value(obj->parameters, "port"); protocol = config_get_value(obj->parameters, "protocol"); if (service && port && protocol) { CONFIG_CONTEXT *ptr = context; while (ptr && strcmp(ptr->object, service) != 0) ptr = ptr->next; if (ptr && ptr->element && serviceHasProtocol(ptr->element, protocol, atoi(port)) == 0) { serviceAddProtocol(ptr->element, protocol, address, atoi(port)); serviceStartProtocol(ptr->element, protocol, atoi(port)); } } } else if (strcmp(type, "server") != 0 && strcmp(type, "monitor") != 0) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Configuration object %s has an invalid " "type specified.", obj->object))); } obj = obj->next; } return 1; }
static int ctrl_handle_get_service_msg(struct ctrlmsg *cm, int peer) { struct ctrlmsg_service *cmg = (struct ctrlmsg_service *)cm; struct service_entry *se; struct service_iter iter; unsigned short prefix_bits = SERVICE_ID_MAX_PREFIX_BITS; struct target *t; LOG_DBG("getting service: %s\n", service_id_to_str(&cmg->service[0].srvid)); if (cmg->service[0].srvid_prefix_bits > 0) prefix_bits = cmg->service[0].srvid_prefix_bits; se = service_find(&cmg->service[0].srvid, prefix_bits); if (se) { struct ctrlmsg_service *cres; size_t size = CTRLMSG_SERVICE_NUM_LEN(se->count); int i = 0; cres = kmalloc(size, GFP_KERNEL); if (!cres) { service_entry_put(se); cm->retval = CTRLMSG_RETVAL_ERROR; ctrl_sendmsg(cm, peer, GFP_KERNEL); return -ENOMEM; } memset(cres, 0, size); cres->cmh.type = CTRLMSG_TYPE_GET_SERVICE; cres->cmh.len = size; cres->cmh.xid = cm->xid; cres->xid = cmg->xid; memset(&iter, 0, sizeof(iter)); service_iter_init(&iter, se, SERVICE_ITER_FORWARD); while ((t = service_iter_next(&iter)) != NULL) { struct service_info *entry = &cres->service[i++]; service_get_id(se, &entry->srvid); memcpy(&entry->address, t->dst, t->dstlen); entry->srvid_prefix_bits = service_get_prefix_bits(se); entry->srvid_flags = service_iter_get_flags(&iter); entry->weight = t->weight; entry->priority = service_iter_get_priority(&iter); #if defined(ENABLE_DEBUG) { char buf[18]; LOG_DBG("Get %s %s priority=%u weight=%u\n", service_id_to_str(&entry->srvid), inet_ntop(AF_INET, &t->dst, buf, 18), entry->priority, entry->weight); } #endif } service_iter_destroy(&iter); service_entry_put(se); if (i == 0) cres->cmh.retval = CTRLMSG_RETVAL_NOENTRY; else cres->cmh.retval = CTRLMSG_RETVAL_OK; ctrl_sendmsg(&cres->cmh, peer, GFP_KERNEL); kfree(cres); LOG_DBG("Service %s matched %u entries. msg_len=%u\n", service_id_to_str(&cmg->service[0].srvid), se->count, cres->cmh.len); } else { cmg->service[0].srvid_flags = SVSF_INVALID; cmg->cmh.retval = CTRLMSG_RETVAL_NOENTRY; ctrl_sendmsg(&cmg->cmh, peer, GFP_KERNEL); LOG_DBG("Service %s not found\n", service_id_to_str(&cmg->service[0].srvid)); } return 0; }