subagent specific API moved to separate library from libnetxms
[public/netxms.git] / src / agent / core / policy.cpp
1 /*
2 ** NetXMS multiplatform core agent
3 ** Copyright (C) 2003-2013 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be usefu,,
11 ** but ITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: policy.cpp
20 **
21 **/
22
23 #include "nxagentd.h"
24
25 #ifdef _WIN32
26 #define write _write
27 #define close _close
28 #endif
29
30 #define POLICY_REGISTRY_PATH _T("/policyRegistry")
31
32 /**
33 * Register policy in persistent storage
34 */
35 static void RegisterPolicy(CommSession *session, UINT32 type, uuid_t guid)
36 {
37 TCHAR path[256], buffer[64];
38 int tail;
39
40 _sntprintf(path, 256, POLICY_REGISTRY_PATH _T("/policy-%s/"), uuid_to_string(guid, buffer));
41 tail = (int)_tcslen(path);
42
43 Config *registry = AgentOpenRegistry();
44
45 _tcscpy(&path[tail], _T("type"));
46 registry->setValue(path, type);
47
48 _tcscpy(&path[tail], _T("server"));
49 registry->setValue(path, session->getServerAddress().toString(buffer));
50
51 AgentCloseRegistry(true);
52 }
53
54 /**
55 * Register policy in persistent storage
56 */
57 static void UnregisterPolicy(uuid_t guid)
58 {
59 TCHAR path[256], buffer[64];
60
61 _sntprintf(path, 256, POLICY_REGISTRY_PATH _T("/policy-%s"), uuid_to_string(guid, buffer));
62 Config *registry = AgentOpenRegistry();
63 registry->deleteEntry(path);
64 AgentCloseRegistry(true);
65 }
66
67 /**
68 * Get policy type by GUID
69 */
70 static int GetPolicyType(uuid_t guid)
71 {
72 TCHAR path[256], buffer[64];
73 int type;
74
75 _sntprintf(path, 256, POLICY_REGISTRY_PATH _T("/policy-%s/type"), uuid_to_string(guid, buffer));
76 Config *registry = AgentOpenRegistry();
77 type = registry->getValueAsInt(path, -1);
78 AgentCloseRegistry(false);
79 return type;
80 }
81
82 /**
83 * Deploy configuration file
84 */
85 static UINT32 DeployConfig(UINT32 session, uuid_t guid, NXCPMessage *msg)
86 {
87 TCHAR path[MAX_PATH], name[64], tail;
88 int fh;
89 UINT32 rcc;
90
91 tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
92 _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
93 ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
94 uuid_to_string(guid, name));
95
96 fh = _topen(path, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR);
97 if (fh != -1)
98 {
99 UINT32 size = msg->getFieldAsBinary(VID_CONFIG_FILE_DATA, NULL, 0);
100 BYTE *data = (BYTE *)malloc(size);
101 if (data != NULL)
102 {
103 msg->getFieldAsBinary(VID_CONFIG_FILE_DATA, data, size);
104 if (write(fh, data, size) == size)
105 {
106 DebugPrintf(session, 3, _T("Configuration file %s saved successfully"), path);
107 rcc = ERR_SUCCESS;
108 }
109 else
110 {
111 rcc = ERR_IO_FAILURE;
112 }
113 free(data);
114 }
115 else
116 {
117 rcc = ERR_MEM_ALLOC_FAILED;
118 }
119 close(fh);
120 }
121 else
122 {
123 DebugPrintf(session, 2, _T("DeployConfig(): Error opening file %s for writing (%s)"), path, _tcserror(errno));
124 rcc = ERR_FILE_OPEN_ERROR;
125 }
126
127 return rcc;
128 }
129
130 /**
131 * Deploy log parser policy
132 */
133 static UINT32 DeployLogParser(UINT32 session, uuid_t guid, NXCPMessage *msg)
134 {
135 return ERR_NOT_IMPLEMENTED;
136 }
137
138 /**
139 * Deploy policy on agent
140 */
141 UINT32 DeployPolicy(CommSession *session, NXCPMessage *request)
142 {
143 UINT32 type, rcc;
144 uuid_t guid;
145
146 type = request->getFieldAsUInt16(VID_POLICY_TYPE);
147 request->getFieldAsBinary(VID_GUID, guid, UUID_LENGTH);
148
149 switch(type)
150 {
151 case AGENT_POLICY_CONFIG:
152 rcc = DeployConfig(session->getIndex(), guid, request);
153 break;
154 case AGENT_POLICY_LOG_PARSER:
155 rcc = DeployLogParser(session->getIndex(), guid, request);
156 break;
157 default:
158 rcc = ERR_BAD_ARGUMENTS;
159 break;
160 }
161
162 if (rcc == RCC_SUCCESS)
163 RegisterPolicy(session, type, guid);
164
165 DebugPrintf(session->getIndex(), 3, _T("Policy deployment: TYPE=%d RCC=%d"), type, rcc);
166 return rcc;
167 }
168
169 /**
170 * Remove configuration file
171 */
172 static UINT32 RemoveConfig(UINT32 session, uuid_t guid, NXCPMessage *msg)
173 {
174 TCHAR path[MAX_PATH], name[64], tail;
175 UINT32 rcc;
176
177 tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
178 _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
179 ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
180 uuid_to_string(guid, name));
181
182 if (_tremove(path) != 0)
183 {
184 rcc = (errno == ENOENT) ? ERR_SUCCESS : ERR_IO_FAILURE;
185 }
186 else
187 {
188 rcc = ERR_SUCCESS;
189 }
190 return rcc;
191 }
192
193 /**
194 * Remove log parser file
195 */
196 static UINT32 RemoveLogParser(UINT32 session, uuid_t guid, NXCPMessage *msg)
197 {
198 TCHAR path[MAX_PATH], name[64], tail;
199 UINT32 rcc;
200
201 tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
202 _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
203 ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
204 uuid_to_string(guid, name));
205
206 if (_tremove(path) != 0)
207 {
208 rcc = (errno == ENOENT) ? ERR_SUCCESS : ERR_IO_FAILURE;
209 }
210 else
211 {
212 rcc = ERR_SUCCESS;
213 }
214 return rcc;
215 }
216
217 /**
218 * Uninstall policy from agent
219 */
220 UINT32 UninstallPolicy(CommSession *session, NXCPMessage *request)
221 {
222 UINT32 rcc;
223 int type;
224 uuid_t guid;
225 TCHAR buffer[64];
226
227 request->getFieldAsBinary(VID_GUID, guid, UUID_LENGTH);
228 type = GetPolicyType(guid);
229
230 switch(type)
231 {
232 case AGENT_POLICY_CONFIG:
233 rcc = RemoveConfig(session->getIndex(), guid, request);
234 break;
235 case AGENT_POLICY_LOG_PARSER:
236 rcc = RemoveLogParser(session->getIndex(), guid, request);
237 break;
238 default:
239 rcc = ERR_BAD_ARGUMENTS;
240 break;
241 }
242
243 if (rcc == RCC_SUCCESS)
244 UnregisterPolicy(guid);
245
246 DebugPrintf(session->getIndex(), 3, _T("Policy uninstall: GUID=%s TYPE=%d RCC=%d"), uuid_to_string(guid, buffer), type, rcc);
247 return rcc;
248 }
249
250 /**
251 * Get policy inventory
252 */
253 UINT32 GetPolicyInventory(CommSession *session, NXCPMessage *msg)
254 {
255 Config *registry = AgentOpenRegistry();
256
257 ObjectArray<ConfigEntry> *list = registry->getSubEntries(_T("/policyRegistry"), NULL);
258 if (list != NULL)
259 {
260 msg->setField(VID_NUM_ELEMENTS, (UINT32)list->size());
261 UINT32 varId = VID_ELEMENT_LIST_BASE;
262 for(int i = 0; i < list->size(); i++, varId += 7)
263 {
264 ConfigEntry *e = list->get(i);
265 uuid_t guid;
266
267 if (MatchString(_T("policy-*"), e->getName(), TRUE))
268 {
269 uuid_parse(&(e->getName()[7]), guid);
270 msg->setField(varId++, guid, UUID_LENGTH);
271 msg->setField(varId++, (WORD)e->getSubEntryValueAsInt(_T("type")));
272 msg->setField(varId++, e->getSubEntryValue(_T("server")));
273 }
274 }
275 delete list;
276 }
277 else
278 {
279 msg->setField(VID_NUM_ELEMENTS, (UINT32)0);
280 }
281
282 AgentCloseRegistry(false);
283 return RCC_SUCCESS;
284 }