UUID functions renamed to avoid conflict with Mac OS X system functions
[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, const uuid& guid)
36 {
37 TCHAR path[256], buffer[64];
38 int tail;
39
40 _sntprintf(path, 256, POLICY_REGISTRY_PATH _T("/policy-%s/"), guid.toString(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(const uuid& guid)
58 {
59 TCHAR path[256], buffer[64];
60
61 _sntprintf(path, 256, POLICY_REGISTRY_PATH _T("/policy-%s"), guid.toString(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(const uuid& guid)
71 {
72 TCHAR path[256], buffer[64];
73 int type;
74
75 _sntprintf(path, 256, POLICY_REGISTRY_PATH _T("/policy-%s/type"), guid.toString(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, const uuid& 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 guid.toString(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, const uuid& 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
145 type = request->getFieldAsUInt16(VID_POLICY_TYPE);
146 uuid guid = request->getFieldAsGUID(VID_GUID);
147
148 switch(type)
149 {
150 case AGENT_POLICY_CONFIG:
151 rcc = DeployConfig(session->getIndex(), guid, request);
152 break;
153 case AGENT_POLICY_LOG_PARSER:
154 rcc = DeployLogParser(session->getIndex(), guid, request);
155 break;
156 default:
157 rcc = ERR_BAD_ARGUMENTS;
158 break;
159 }
160
161 if (rcc == RCC_SUCCESS)
162 RegisterPolicy(session, type, guid);
163
164 DebugPrintf(session->getIndex(), 3, _T("Policy deployment: TYPE=%d RCC=%d"), type, rcc);
165 return rcc;
166 }
167
168 /**
169 * Remove configuration file
170 */
171 static UINT32 RemoveConfig(UINT32 session, const uuid& guid, NXCPMessage *msg)
172 {
173 TCHAR path[MAX_PATH], name[64], tail;
174 UINT32 rcc;
175
176 tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
177 _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
178 ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
179 guid.toString(name));
180
181 if (_tremove(path) != 0)
182 {
183 rcc = (errno == ENOENT) ? ERR_SUCCESS : ERR_IO_FAILURE;
184 }
185 else
186 {
187 rcc = ERR_SUCCESS;
188 }
189 return rcc;
190 }
191
192 /**
193 * Remove log parser file
194 */
195 static UINT32 RemoveLogParser(UINT32 session, const uuid& guid, NXCPMessage *msg)
196 {
197 TCHAR path[MAX_PATH], name[64], tail;
198 UINT32 rcc;
199
200 tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
201 _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
202 ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
203 guid.toString(name));
204
205 if (_tremove(path) != 0)
206 {
207 rcc = (errno == ENOENT) ? ERR_SUCCESS : ERR_IO_FAILURE;
208 }
209 else
210 {
211 rcc = ERR_SUCCESS;
212 }
213 return rcc;
214 }
215
216 /**
217 * Uninstall policy from agent
218 */
219 UINT32 UninstallPolicy(CommSession *session, NXCPMessage *request)
220 {
221 UINT32 rcc;
222 int type;
223 TCHAR buffer[64];
224
225 uuid guid = request->getFieldAsGUID(VID_GUID);
226 type = GetPolicyType(guid);
227
228 switch(type)
229 {
230 case AGENT_POLICY_CONFIG:
231 rcc = RemoveConfig(session->getIndex(), guid, request);
232 break;
233 case AGENT_POLICY_LOG_PARSER:
234 rcc = RemoveLogParser(session->getIndex(), guid, request);
235 break;
236 default:
237 rcc = ERR_BAD_ARGUMENTS;
238 break;
239 }
240
241 if (rcc == RCC_SUCCESS)
242 UnregisterPolicy(guid);
243
244 DebugPrintf(session->getIndex(), 3, _T("Policy uninstall: GUID=%s TYPE=%d RCC=%d"), guid.toString(buffer), type, rcc);
245 return rcc;
246 }
247
248 /**
249 * Get policy inventory
250 */
251 UINT32 GetPolicyInventory(CommSession *session, NXCPMessage *msg)
252 {
253 Config *registry = AgentOpenRegistry();
254
255 ObjectArray<ConfigEntry> *list = registry->getSubEntries(_T("/policyRegistry"), NULL);
256 if (list != NULL)
257 {
258 msg->setField(VID_NUM_ELEMENTS, (UINT32)list->size());
259 UINT32 varId = VID_ELEMENT_LIST_BASE;
260 for(int i = 0; i < list->size(); i++, varId += 7)
261 {
262 ConfigEntry *e = list->get(i);
263 uuid_t guid;
264
265 if (MatchString(_T("policy-*"), e->getName(), TRUE))
266 {
267 _uuid_parse(&(e->getName()[7]), guid);
268 msg->setField(varId++, guid, UUID_LENGTH);
269 msg->setField(varId++, (WORD)e->getSubEntryValueAsInt(_T("type")));
270 msg->setField(varId++, e->getSubEntryValue(_T("server")));
271 }
272 }
273 delete list;
274 }
275 else
276 {
277 msg->setField(VID_NUM_ELEMENTS, (UINT32)0);
278 }
279
280 AgentCloseRegistry(false);
281 return RCC_SUCCESS;
282 }