| 1 | /**************************************************************************
|
|---|
| 2 | * Copyright (C) 2004-2007 by Michael Medin <michael@medin.name> *
|
|---|
| 3 | * *
|
|---|
| 4 | * This code is part of NSClient++ - http://trac.nakednuns.org/nscp *
|
|---|
| 5 | * *
|
|---|
| 6 | * This program is free software; you can redistribute it and/or modify *
|
|---|
| 7 | * it under the terms of the GNU General Public License as published by *
|
|---|
| 8 | * the Free Software Foundation; either version 2 of the License, or *
|
|---|
| 9 | * (at your option) any later version. *
|
|---|
| 10 | * *
|
|---|
| 11 | * This program is distributed in the hope that it will be useful, *
|
|---|
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|---|
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|---|
| 14 | * GNU General Public License for more details. *
|
|---|
| 15 | * *
|
|---|
| 16 | * You should have received a copy of the GNU General Public License *
|
|---|
| 17 | * along with this program; if not, write to the *
|
|---|
| 18 | * Free Software Foundation, Inc., *
|
|---|
| 19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|---|
| 20 | ***************************************************************************/
|
|---|
| 21 | #include "stdafx.h"
|
|---|
| 22 | #include "CheckExternalScripts.h"
|
|---|
| 23 | #include <time.h>
|
|---|
| 24 | #include <string>
|
|---|
| 25 |
|
|---|
| 26 | #include <settings/macros.h>
|
|---|
| 27 | #include <msvc_wrappers.h>
|
|---|
| 28 | #include <config.h>
|
|---|
| 29 | #include <strEx.h>
|
|---|
| 30 | #include <file_helpers.hpp>
|
|---|
| 31 | #include <file_helpers.hpp>
|
|---|
| 32 |
|
|---|
| 33 | #include <boost/regex.hpp>
|
|---|
| 34 | #include <boost/filesystem.hpp>
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 | CheckExternalScripts gCheckExternalScripts;
|
|---|
| 38 |
|
|---|
| 39 | CheckExternalScripts::CheckExternalScripts() {}
|
|---|
| 40 | CheckExternalScripts::~CheckExternalScripts() {}
|
|---|
| 41 |
|
|---|
| 42 | void CheckExternalScripts::addAllScriptsFrom(std::wstring str_path) {
|
|---|
| 43 | boost::filesystem::wpath path = str_path;
|
|---|
| 44 | if (path.has_relative_path())
|
|---|
| 45 | path = GET_CORE()->getBasePath() / path;
|
|---|
| 46 | file_helpers::patterns::pattern_type split_path = file_helpers::patterns::split_pattern(path);
|
|---|
| 47 | if (!boost::filesystem::is_directory(split_path.first))
|
|---|
| 48 | NSC_LOG_ERROR_STD(_T("Path was not found: ") + split_path.first.string());
|
|---|
| 49 |
|
|---|
| 50 | boost::wregex pattern(split_path.second);
|
|---|
| 51 | boost::filesystem::wdirectory_iterator end_itr; // default construction yields past-the-end
|
|---|
| 52 | for ( boost::filesystem::wdirectory_iterator itr( split_path.first ); itr != end_itr; ++itr ) {
|
|---|
| 53 | if ( !is_directory(itr->status()) ) {
|
|---|
| 54 | std::wstring name = itr->path().leaf();
|
|---|
| 55 | if (regex_match(name, pattern))
|
|---|
| 56 | addCommand(name, (split_path.first / name).string(), _T(""));
|
|---|
| 57 | }
|
|---|
| 58 | }
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 | std::wstring CheckExternalScripts::getWrapping(std::wstring val) {
|
|---|
| 63 | strEx::token tok = strEx::getToken(val, ' ', true);
|
|---|
| 64 | std::wstring::size_type pos = tok.first.find_last_of(_T("."));
|
|---|
| 65 | if (pos == std::wstring::npos)
|
|---|
| 66 | return _T("");
|
|---|
| 67 | return tok.first.substr(pos+1);
|
|---|
| 68 | }
|
|---|
| 69 |
|
|---|
| 70 | void CheckExternalScripts::addWrappedCommand(std::wstring key, std::wstring tpl, std::wstring command ) {
|
|---|
| 71 | strEx::token tok = strEx::getToken(command, ' ', true);
|
|---|
| 72 | strEx::replace(tpl, _T("%SCRIPT%"), tok.first);
|
|---|
| 73 | strEx::replace(tpl, _T("%ARGS%"), tok.second);
|
|---|
| 74 | tok = strEx::getToken(tpl, ' ', true);
|
|---|
| 75 | addCommand(key.c_str(),tok.first, tok.second);
|
|---|
| 76 | }
|
|---|
| 77 |
|
|---|
| 78 | bool CheckExternalScripts::loadModule(NSCAPI::moduleLoadMode mode) {
|
|---|
| 79 | SETTINGS_REG_PATH(external_scripts::SECTION);
|
|---|
| 80 | SETTINGS_REG_PATH(external_scripts::SCRIPT_SECTION);
|
|---|
| 81 | SETTINGS_REG_PATH(external_scripts::ALIAS_SECTION);
|
|---|
| 82 | SETTINGS_REG_KEY_I(external_scripts::TIMEOUT);
|
|---|
| 83 | SETTINGS_REG_KEY_S(external_scripts::SCRIPT_PATH);
|
|---|
| 84 | SETTINGS_REG_KEY_B(external_scripts::ALLOW_ARGS);
|
|---|
| 85 | SETTINGS_REG_KEY_B(external_scripts::ALLOW_NASTY);
|
|---|
| 86 |
|
|---|
| 87 | timeout = SETTINGS_GET_INT(external_scripts::TIMEOUT);
|
|---|
| 88 | scriptDirectory_ = SETTINGS_GET_STRING(external_scripts::SCRIPT_PATH);
|
|---|
| 89 | allowArgs_ = SETTINGS_GET_BOOL(nrpe::ALLOW_ARGS);
|
|---|
| 90 | allowNasty_ = SETTINGS_GET_BOOL(nrpe::ALLOW_NASTY);
|
|---|
| 91 | std::list<std::wstring>::const_iterator it;
|
|---|
| 92 | std::list<std::wstring> commands = GET_CORE()->getSettingsSection(setting_keys::external_scripts::SCRIPT_SECTION_PATH);
|
|---|
| 93 | for (it = commands.begin(); it != commands.end(); ++it) {
|
|---|
| 94 | if ((*it).empty())
|
|---|
| 95 | continue;
|
|---|
| 96 | NSC_DEBUG_MSG_STD(_T("Looking under: ") + setting_keys::external_scripts::SCRIPT_SECTION_PATH + _T(", ") + (*it));
|
|---|
| 97 | std::wstring s = GET_CORE()->getSettingsString(setting_keys::external_scripts::SCRIPT_SECTION_PATH, (*it), _T(""));
|
|---|
| 98 | if (s.empty()) {
|
|---|
| 99 | NSC_LOG_ERROR_STD(_T("Invalid command definition: ") + (*it));
|
|---|
| 100 | } else {
|
|---|
| 101 | strEx::token tok = strEx::getToken(s, ' ', true);
|
|---|
| 102 | addCommand((*it).c_str(), tok.first, tok.second);
|
|---|
| 103 | }
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | commands = GET_CORE()->getSettingsSection(setting_keys::external_scripts::ALIAS_SECTION_PATH);
|
|---|
| 107 | for (it = commands.begin(); it != commands.end(); ++it) {
|
|---|
| 108 | if ((*it).empty())
|
|---|
| 109 | continue;
|
|---|
| 110 | std::wstring s = GET_CORE()->getSettingsString(setting_keys::external_scripts::ALIAS_SECTION_PATH, (*it), _T(""));
|
|---|
| 111 | if (s.empty()) {
|
|---|
| 112 | NSC_LOG_ERROR_STD(_T("Invalid command definition: ") + (*it));
|
|---|
| 113 | } else {
|
|---|
| 114 | strEx::token tok = strEx::getToken(s, ' ', true);
|
|---|
| 115 | addAlias((*it).c_str(), tok.first, tok.second);
|
|---|
| 116 | }
|
|---|
| 117 | }
|
|---|
| 118 |
|
|---|
| 119 | std::map<std::wstring,std::wstring> wrappers;
|
|---|
| 120 | std::list<std::wstring> wrappings = GET_CORE()->getSettingsSection(setting_keys::external_scripts::WRAPPINGS_SECTION_PATH);
|
|---|
| 121 | for (it = wrappings.begin(); it != wrappings.end(); ++it) {
|
|---|
| 122 | std::wstring val = GET_CORE()->getSettingsString(setting_keys::external_scripts::WRAPPINGS_SECTION_PATH, *it, _T(""));
|
|---|
| 123 | if (!(*it).empty() && !val.empty()) {
|
|---|
| 124 | wrappers[(*it)] = val;
|
|---|
| 125 | }
|
|---|
| 126 | }
|
|---|
| 127 | std::list<std::wstring> wscript = GET_CORE()->getSettingsSection(setting_keys::external_scripts::WRAPPED_SCRIPT_PATH);
|
|---|
| 128 | for (it = wscript.begin(); it != wscript.end(); ++it) {
|
|---|
| 129 | std::wstring val = GET_CORE()->getSettingsString(setting_keys::external_scripts::WRAPPED_SCRIPT_PATH, *it, _T(""));
|
|---|
| 130 | if (!(*it).empty() && !val.empty()) {
|
|---|
| 131 | std::wstring type = getWrapping(val);
|
|---|
| 132 | std::map<std::wstring,std::wstring>::const_iterator cit = wrappers.find(type);
|
|---|
| 133 | if (cit == wrappers.end()) {
|
|---|
| 134 | NSC_LOG_ERROR_STD(_T("Failed to find wrappings for: ") + type + _T(" (") + (*it) + _T(")"));
|
|---|
| 135 | } else {
|
|---|
| 136 | addWrappedCommand((*it), (*cit).second, val);
|
|---|
| 137 | }
|
|---|
| 138 | }
|
|---|
| 139 | }
|
|---|
| 140 |
|
|---|
| 141 | if (!scriptDirectory_.empty()) {
|
|---|
| 142 | addAllScriptsFrom(scriptDirectory_);
|
|---|
| 143 | }
|
|---|
| 144 | root_ = GET_CORE()->getBasePath();
|
|---|
| 145 | return true;
|
|---|
| 146 | }
|
|---|
| 147 | bool CheckExternalScripts::unloadModule() {
|
|---|
| 148 | return true;
|
|---|
| 149 | }
|
|---|
| 150 |
|
|---|
| 151 |
|
|---|
| 152 | bool CheckExternalScripts::hasCommandHandler() {
|
|---|
| 153 | return true;
|
|---|
| 154 | }
|
|---|
| 155 | bool CheckExternalScripts::hasMessageHandler() {
|
|---|
| 156 | return false;
|
|---|
| 157 | }
|
|---|
| 158 |
|
|---|
| 159 |
|
|---|
| 160 | NSCAPI::nagiosReturn CheckExternalScripts::handleCommand(const std::wstring command, std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf) {
|
|---|
| 161 | std::wstring cmd = command.c_str();
|
|---|
| 162 | boost::to_lower(cmd);
|
|---|
| 163 | command_list::const_iterator cit = commands.find(cmd);
|
|---|
| 164 | bool isAlias = false;
|
|---|
| 165 | if (cit == commands.end()) {
|
|---|
| 166 | cit = alias.find(cmd);
|
|---|
| 167 | if (cit == alias.end())
|
|---|
| 168 | return NSCAPI::returnIgnored;
|
|---|
| 169 | isAlias = true;
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | const command_data cd = (*cit).second;
|
|---|
| 173 | std::wstring args = cd.arguments;
|
|---|
| 174 | if (isAlias || allowArgs_) {
|
|---|
| 175 | int i=1;
|
|---|
| 176 | BOOST_FOREACH(std::wstring str, arguments) {
|
|---|
| 177 | if (isAlias || allowNasty_) {
|
|---|
| 178 | if (str.find_first_of(NASTY_METACHARS) != std::wstring::npos) {
|
|---|
| 179 | NSC_LOG_ERROR(_T("Request string contained illegal metachars!"));
|
|---|
| 180 | return NSCAPI::returnIgnored;
|
|---|
| 181 | }
|
|---|
| 182 | }
|
|---|
| 183 | strEx::replace(args, _T("$ARG") + strEx::itos(i) + _T("$"), str);
|
|---|
| 184 | }
|
|---|
| 185 | }
|
|---|
| 186 | if (isAlias) {
|
|---|
| 187 | return GET_CORE()->InjectSplitAndCommand(cd.command, args, ' ', message, perf, true);
|
|---|
| 188 | } else {
|
|---|
| 189 | int result = process::executeProcess(process::exec_arguments(root_, cd.command + _T(" ") + args, timeout), message, perf);
|
|---|
| 190 | if (!nscapi::plugin_helper::isNagiosReturnCode(result)) {
|
|---|
| 191 | NSC_LOG_ERROR_STD(_T("The command (") + cd.command + _T(") returned an invalid return code: ") + strEx::itos(result));
|
|---|
| 192 | return NSCAPI::returnUNKNOWN;
|
|---|
| 193 | }
|
|---|
| 194 | return nscapi::plugin_helper::int2nagios(result);
|
|---|
| 195 | /*
|
|---|
| 196 | } else if (cd.type == script_dir) {
|
|---|
| 197 | std::wstring args = arrayBuffer::arrayBuffer2string(char_args, argLen, _T(" "));
|
|---|
| 198 | std::wstring cmd = scriptDirectory_ + command.c_str() + _T(" ") +args;
|
|---|
| 199 | return executeNRPECommand(cmd, message, perf);
|
|---|
| 200 | } else {
|
|---|
| 201 | NSC_LOG_ERROR_STD(_T("Unknown script type: ") + command.c_str());
|
|---|
| 202 | return NSCAPI::critical;
|
|---|
| 203 | */
|
|---|
| 204 | }
|
|---|
| 205 |
|
|---|
| 206 | }
|
|---|
| 207 |
|
|---|
| 208 |
|
|---|
| 209 | NSC_WRAP_DLL();
|
|---|
| 210 | NSC_WRAPPERS_MAIN_DEF(gCheckExternalScripts);
|
|---|
| 211 | NSC_WRAPPERS_IGNORE_MSG_DEF();
|
|---|
| 212 | NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckExternalScripts);
|
|---|
| 213 |
|
|---|