diff --git a/pandora_agents/ChangeLog b/pandora_agents/ChangeLog index 833063c2ae..9b06989f94 100644 --- a/pandora_agents/ChangeLog +++ b/pandora_agents/ChangeLog @@ -1,3 +1,17 @@ +2008-12-16 Ramon Novoa + + * win32/modules/pandora_module_wmiquery.cc, + win32/modules/pandora_module_wmiquery.h: Added to repository. WMI + query module. + + * win32/windows/pandora_wmi.cc, + win32/windows/pandora_wmi.h, + win32/modules/pandora_module.h, + win32/modules/pandora_module_factory.cc, + win32/modules/pandora_module_list.cc, + win32/modules/pandora_module.cc, + win32/PandoraAgent.dev: Added support for WMI query module. + 2008-12-11 Evi Vanoost * linux/plugins/SGE: Added the SGE plugin diff --git a/pandora_agents/win32/PandoraAgent.dev b/pandora_agents/win32/PandoraAgent.dev index ab25fcd120..971b5aef13 100644 --- a/pandora_agents/win32/PandoraAgent.dev +++ b/pandora_agents/win32/PandoraAgent.dev @@ -1,7 +1,7 @@ [Project] FileName=PandoraAgent.dev Name=PandoraAgent -UnitCount=79 +UnitCount=81 Type=1 Ver=1 ObjFiles= @@ -837,3 +837,23 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= +[Unit80] +FileName=modules\pandora_module_wmiquery.cc +CompileCpp=1 +Folder=Modules +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=modules\pandora_module_wmiquery.h +CompileCpp=1 +Folder=Modules +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/pandora_agents/win32/modules/pandora_module.cc b/pandora_agents/win32/modules/pandora_module.cc index 7235a7588a..adfbef9694 100644 --- a/pandora_agents/win32/modules/pandora_module.cc +++ b/pandora_agents/win32/modules/pandora_module.cc @@ -39,7 +39,7 @@ Pandora_Module::Pandora_Module (string name) { this->module_interval = 1; this->max = 0; this->min = 0; - this->has_limits = false; + this->has_limits = false; this->async = false; this->data_list = NULL; } @@ -120,8 +120,9 @@ Pandora_Module::parseModuleKindFromString (string kind) { } else if (kind == module_odbc_str) { return MODULE_ODBC; } else if (kind == module_logevent_str) { - - return MODULE_LOGEVENT; + return MODULE_LOGEVENT; + } else if (kind == module_wmiquery_str) { + return MODULE_WMIQUERY; } else { return MODULE_0; } @@ -176,16 +177,16 @@ Module_Kind Pandora_Module::getModuleKind () const { return this->module_kind; } - + /** * Get the output of the module. * * @return The module output in a string value. */ string -Pandora_Module::getLatestOutput () const { +Pandora_Module::getLatestOutput () const { return this->latest_output; -} +} /** * Get the type of the module in a integer_value. @@ -251,7 +252,7 @@ Pandora_Module::setOutput (string output) { if (this->data_list == NULL) this->data_list = new list (); data = new Pandora_Data (output); - this->data_list->push_back (data); + this->data_list->push_back (data); this->latest_output = output; } @@ -363,7 +364,7 @@ Pandora_Module::getXml () { data_element = new TiXmlElement ("data"); element = new TiXmlElement ("value"); try { - data_clean = strreplace (this->getDataOutput (data), + data_clean = strreplace (this->getDataOutput (data), "%", "%%" ); } catch (Output_Error e) { delete element; @@ -425,7 +426,7 @@ void Pandora_Module::setMax (int value) { this->has_limits = true; this->max = value; -} +} /** * Set the min value the module can have. @@ -439,19 +440,19 @@ Pandora_Module::setMin (int value) { this->has_limits = true; this->min = value; } - + /** * Set the async flag to the module. * - * If a module is set to be async, it would try to works only when the + * If a module is set to be async, it would try to works only when the * events happen. Note that not all the modules can work in async mode. * * @param async Flag to set. - */ -void -Pandora_Module::setAsync (bool async) { - this->async = async; -} + */ +void +Pandora_Module::setAsync (bool async) { + this->async = async; +} /** * Set the module type from a string type. diff --git a/pandora_agents/win32/modules/pandora_module.h b/pandora_agents/win32/modules/pandora_module.h index 9de043848c..952163cd76 100644 --- a/pandora_agents/win32/modules/pandora_module.h +++ b/pandora_agents/win32/modules/pandora_module.h @@ -70,7 +70,8 @@ namespace Pandora_Modules { MODULE_FREEMEMORY, /**< The module checks the amount of * freememory in the system */ MODULE_ODBC, /**< The module performs a SQL query via ODBC */ - MODULE_LOGEVENT /**< The module checks for log events */ + MODULE_LOGEVENT, /**< The module checks for log events */ + MODULE_WMIQUERY /**< The module runs WQL queries */ } Module_Kind; const string module_exec_str = "module_exec"; @@ -81,6 +82,7 @@ namespace Pandora_Modules { const string module_cpuusage_str = "module_cpuusage"; const string module_odbc_str = "module_odbc"; const string module_logevent_str = "module_logevent"; + const string module_wmiquery_str = "module_wmiquery"; /** * Pandora module super-class exception. @@ -102,7 +104,8 @@ namespace Pandora_Modules { */ class Interval_Not_Fulfilled : public Pandora_Modules::Module_Exception { }; - /** * Pandora module super-class. + /** + * Pandora module super-class. * * Every defined module must inherit of this class. */ @@ -116,7 +119,7 @@ namespace Pandora_Modules { Module_Type module_type; string module_kind_str; Module_Kind module_kind; - list *data_list; + list *data_list; string latest_output; string getDataOutput (Pandora_Data *data); @@ -134,11 +137,11 @@ namespace Pandora_Modules { /** * The description of the module. */ - string module_description; - - /** - * Flag to set a module as asynchronous - */ + string module_description; + + /** + * Flag to set a module as asynchronous + */ bool async; public: Pandora_Module (string name); @@ -158,13 +161,13 @@ namespace Pandora_Modules { virtual void run (); virtual void setOutput (string output); - virtual void setOutput (string output, + virtual void setOutput (string output, SYSTEMTIME *system_time); string getName () const; string getDescription () const; - string getTypeString () const; + string getTypeString () const; string getLatestOutput () const; Module_Type getTypeInt () const; Module_Type getModuleType () const; @@ -174,7 +177,7 @@ namespace Pandora_Modules { void setKind (string kind); void setDescription (string description); void setMax (int value); - void setMin (int value); + void setMin (int value); void setAsync (bool async); }; } diff --git a/pandora_agents/win32/modules/pandora_module_factory.cc b/pandora_agents/win32/modules/pandora_module_factory.cc index fd847f2629..9dbc4510e1 100644 --- a/pandora_agents/win32/modules/pandora_module_factory.cc +++ b/pandora_agents/win32/modules/pandora_module_factory.cc @@ -28,6 +28,7 @@ #include "pandora_module_cpuusage.h" #include "pandora_module_odbc.h" #include "pandora_module_logevent.h" +#include "pandora_module_wmiquery.h" #include "../pandora_strutils.h" #include @@ -53,10 +54,12 @@ using namespace Pandora_Strutils; #define TOKEN_SOURCE ("module_source ") #define TOKEN_EVENTTYPE ("module_eventtype ") #define TOKEN_EVENTCODE ("module_eventcode ") -#define TOKEN_PATTERN ("module_pattern ") -#define TOKEN_ASYNC ("module_async") -#define TOKEN_WATCHDOG ("module_watchdog ") +#define TOKEN_PATTERN ("module_pattern ") +#define TOKEN_ASYNC ("module_async") +#define TOKEN_WATCHDOG ("module_watchdog ") #define TOKEN_START_COMMAND ("module_start_command ") +#define TOKEN_WMIQUERY ("module_wmiquery ") +#define TOKEN_WMICOLUMN ("module_wmicolumn ") string parseLine (string line, string token) { @@ -91,9 +94,10 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { string module_interval, module_proc, module_service; string module_freedisk, module_cpuusage, module_odbc; string module_odbc_query, module_dsn, module_freememory; - string module_logevent, module_source, module_eventtype, module_eventcode; - string module_pattern, module_async; + string module_logevent, module_source, module_eventtype, module_eventcode; + string module_pattern, module_async; string module_watchdog, module_start_command; + string module_wmiquery, module_wmicolumn; Pandora_Module *module; bool numeric; Module_Type type; @@ -114,10 +118,12 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module_source = ""; module_eventtype = ""; module_eventcode = ""; - module_pattern = ""; - module_async = ""; - module_watchdog = ""; + module_pattern = ""; + module_async = ""; + module_watchdog = ""; module_start_command = ""; + module_wmiquery = ""; + module_wmicolumn = ""; stringtok (tokens, definition, "\n"); @@ -187,14 +193,20 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { } if (module_async == "") { module_async = parseLine (line, TOKEN_ASYNC); - } + } if (module_start_command == "") { module_start_command = parseLine (line, TOKEN_START_COMMAND); - } + } if (module_watchdog == "") { module_watchdog = parseLine (line, TOKEN_WATCHDOG); - } - + } + if (module_wmiquery == "") { + module_wmiquery = parseLine (line, TOKEN_WMIQUERY); + } + if (module_wmicolumn == "") { + module_wmicolumn = parseLine (line, TOKEN_WMICOLUMN); + } + iter++; } @@ -204,35 +216,35 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module_exec); } else if (module_proc != "") { module = new Pandora_Module_Proc (module_name, - module_proc); - if (module_watchdog != "") { - bool enabled; - - enabled = is_enabled (module_watchdog); - if (enabled) { - if (module_start_command == "") { - pandoraLog ("Module \"%s\" is marked to be watchdog but no recover command was set. " - "Please add a new token 'module_start_command c:\\command_to_recover.exe'", - module_name.c_str ()); - delete module; - return NULL; - } - - Pandora_Module_Proc *module_proc; - + module_proc); + if (module_watchdog != "") { + bool enabled; + + enabled = is_enabled (module_watchdog); + if (enabled) { + if (module_start_command == "") { + pandoraLog ("Module \"%s\" is marked to be watchdog but no recover command was set. " + "Please add a new token 'module_start_command c:\\command_to_recover.exe'", + module_name.c_str ()); + delete module; + return NULL; + } + + Pandora_Module_Proc *module_proc; + module_proc = (Pandora_Module_Proc *) module; module_proc->setWatchdog (true); - module_proc->setStartCommand (module_start_command); + module_proc->setStartCommand (module_start_command); } } } else if (module_service != "") { module = new Pandora_Module_Service (module_name, - module_service); - if (module_watchdog != "") { - Pandora_Module_Service *module_service; - + module_service); + if (module_watchdog != "") { + Pandora_Module_Service *module_service; + module_service = (Pandora_Module_Service *) module; - module_service->setWatchdog (is_enabled (module_watchdog)); + module_service->setWatchdog (is_enabled (module_watchdog)); } } else if (module_freedisk != "") { module = new Pandora_Module_Freedisk (module_name, @@ -263,17 +275,20 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module_eventtype, module_eventcode, module_pattern); + } else if (module_wmiquery != "") { + module = new Pandora_Module_WMIQuery (module_name, + module_wmiquery, module_wmicolumn); } else { return NULL; } if (module_description != "") { module->setDescription (module_description); - } + } if (module_async != "") { module->setAsync (true); - } + } type = Pandora_Module::parseModuleTypeFromString (module_type); switch (type) { @@ -334,7 +349,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module_interval.c_str (), module_name.c_str ()); } - } + } return module; } diff --git a/pandora_agents/win32/modules/pandora_module_list.cc b/pandora_agents/win32/modules/pandora_module_list.cc index d3122c5952..4db6f0b038 100644 --- a/pandora_agents/win32/modules/pandora_module_list.cc +++ b/pandora_agents/win32/modules/pandora_module_list.cc @@ -28,6 +28,7 @@ #include "pandora_module_cpuusage.h" #include "pandora_module_odbc.h" #include "pandora_module_logevent.h" +#include "pandora_module_wmiquery.h" #include using namespace std; @@ -81,8 +82,8 @@ Pandora_Modules::Pandora_Module_List::Pandora_Module_List (string filename) { current = new std::list::iterator (); (*current) = modules->begin (); -} - +} + /** * Creates an empty module list object. */ @@ -90,15 +91,15 @@ Pandora_Modules::Pandora_Module_List::Pandora_Module_List () { this->modules = new list (); current = new std::list::iterator (); (*current) = modules->begin (); -} - +} + /** * Adds a module object to a list object. - */ + */ void Pandora_Modules::Pandora_Module_List::addModule (Pandora_Module *module) { modules->push_back (module); -} +} /** @@ -135,6 +136,7 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition) Pandora_Module_Freememory *module_freememory; Pandora_Module_Odbc *module_odbc; Pandora_Module_Logevent *module_logevent; + Pandora_Module_WMIQuery *module_wmiquery; module = Pandora_Module_Factory::getModuleFromDefinition (definition); @@ -180,6 +182,10 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition) module_logevent = (Pandora_Module_Logevent *) module; modules->push_back (module_logevent); break; + case MODULE_WMIQUERY: + module_wmiquery = (Pandora_Module_WMIQuery *) module; + modules->push_back (module_wmiquery); + break; default: break; } diff --git a/pandora_agents/win32/modules/pandora_module_wmiquery.cc b/pandora_agents/win32/modules/pandora_module_wmiquery.cc new file mode 100644 index 0000000000..98c92a6da2 --- /dev/null +++ b/pandora_agents/win32/modules/pandora_module_wmiquery.cc @@ -0,0 +1,69 @@ +/* Pandora wmiquery module. This module runs WQL queries. + + Copyright (C) 2008 Artica ST. + Written by Ramon Novoa. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "pandora_module_wmiquery.h" +#include "../windows/pandora_wmi.h" +#include "../pandora_windows_service.h" + +using namespace Pandora; +using namespace Pandora_Modules; + +/** + * Creates a Pandora_Module_WMIQuery object. + * + * @param name Module name. + */ +Pandora_Module_WMIQuery::Pandora_Module_WMIQuery (string name, string query, string column) + : Pandora_Module (name) { + + this->query = query; + this->column = column; + this->setKind (module_wmiquery_str); +} + +void +Pandora_Module_WMIQuery::run () { + string value; + list rows; + list::iterator row; + + // Run + try { + Pandora_Module::run (); + } catch (Interval_Not_Fulfilled e) { + return; + } + + if (this->query.empty () || this->column.empty ()) { + return; + } + + Pandora_Wmi::runWMIQuery (this->query, this->column, rows); + + // No data + if (rows.size () < 1) { + this->setOutput (""); + return; + } + + for (row = rows.begin (); row != rows.end(); ++row) { + this->setOutput (*row); + } +} diff --git a/pandora_agents/win32/modules/pandora_module_wmiquery.h b/pandora_agents/win32/modules/pandora_module_wmiquery.h new file mode 100644 index 0000000000..3cdfe93c6b --- /dev/null +++ b/pandora_agents/win32/modules/pandora_module_wmiquery.h @@ -0,0 +1,42 @@ +/* Pandora wmiquery module header file. + + Copyright (C) 2008 Artica ST. + Written by Ramon Novoa. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __PANDORA_MODULE_WMIQUERY_H__ +#define __PANDORA_MODULE_WMIQUERY_H__ + +#include "pandora_module.h" + +namespace Pandora_Modules { + + /** + * This module runs WQL queries. + */ + + class Pandora_Module_WMIQuery : public Pandora_Module { + private: + string query; + string column; + public: + Pandora_Module_WMIQuery (string name, string query, string column); + void run (); + }; +} + +#endif diff --git a/pandora_agents/win32/windows/pandora_wmi.cc b/pandora_agents/win32/windows/pandora_wmi.cc index 321cdcca40..a0b62fffdc 100644 --- a/pandora_agents/win32/windows/pandora_wmi.cc +++ b/pandora_agents/win32/windows/pandora_wmi.cc @@ -632,3 +632,40 @@ Pandora_Wmi::stopService (string service_name) { return success; } +/** + * Runs a generic WQL query. + * + * @param wmi_query WQL query. + * @param column Column to retrieve from the query result. + * @param rows List where the query result will be placed. + */ +void +Pandora_Wmi::runWMIQuery (string wmi_query, string column, list &rows) { + CDhInitialize init; + CDispPtr wmi_svc, quickfixes; + char *value = NULL; + wstring column_w(column.length(), L' '); + wstring wmi_query_w(wmi_query.length(), L' '); + + // Copy string to wstring. + std::copy(column.begin(), column.end(), column_w.begin()); + std::copy(wmi_query.begin(), wmi_query.end(), wmi_query_w.begin()); + + try { + dhCheck (dhGetObject (getWmiStr (L"."), NULL, &wmi_svc)); + dhCheck (dhGetValue (L"%o", &quickfixes, wmi_svc, + L".ExecQuery(%S)", + wmi_query_w.c_str ())); + FOR_EACH (quickfix, quickfixes, NULL) { + dhGetValue (L"%s", &value, quickfix, + column_w.c_str ()); + rows.push_back (value); + dhFreeString (value); + } NEXT_THROW (quickfix); + } catch (string errstr) { + pandoraLog ("runWMIQuery error. %s", errstr.c_str ()); + } +} + + + diff --git a/pandora_agents/win32/windows/pandora_wmi.h b/pandora_agents/win32/windows/pandora_wmi.h index 28b3f7c9f0..93fb6ff441 100644 --- a/pandora_agents/win32/windows/pandora_wmi.h +++ b/pandora_agents/win32/windows/pandora_wmi.h @@ -46,21 +46,24 @@ namespace Pandora_Wmi { string getOSName (); string getOSVersion (); string getOSBuild (); - string getSystemName (); + string getSystemName (); - void getEventList (string source, - string type, - string code, - string pattern, - int interval, + void getEventList (string source, + string type, + string code, + string pattern, + int interval, list &event_list); string getTimestampLimit (int interval); - void convertWMIDate (string wmi_date, - SYSTEMTIME *system_time); - - bool runProgram (string command); - bool startService (string service_name); + void convertWMIDate (string wmi_date, + SYSTEMTIME *system_time); + + bool runProgram (string command); + bool startService (string service_name); bool stopService (string service_name); + void runWMIQuery (string wmi_query, + string var, + list &rows); }; #endif