/src/net-snmp/agent/mibgroup/mibII/vacm_conf.c
Line | Count | Source |
1 | | /* |
2 | | * SNMPv3 View-based Access Control Model |
3 | | */ |
4 | | /* Portions of this file are subject to the following copyright(s). See |
5 | | * the Net-SNMP's COPYING file for more details and other copyrights |
6 | | * that may apply: |
7 | | */ |
8 | | /* |
9 | | * Portions of this file are copyrighted by: |
10 | | * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. |
11 | | * Use is subject to license terms specified in the COPYING file |
12 | | * distributed with the Net-SNMP package. |
13 | | * |
14 | | * Portions of this file are copyrighted by: |
15 | | * Copyright (c) 2016 VMware, Inc. All rights reserved. |
16 | | * Use is subject to license terms specified in the COPYING file |
17 | | * distributed with the Net-SNMP package. |
18 | | */ |
19 | | |
20 | | #include <net-snmp/net-snmp-config.h> |
21 | | |
22 | | #ifdef HAVE_STDLIB_H |
23 | | #include <stdlib.h> |
24 | | #endif |
25 | | #ifdef HAVE_UNISTD_H |
26 | | #include <unistd.h> |
27 | | #endif |
28 | | #ifdef HAVE_STRING_H |
29 | | #include <string.h> |
30 | | #else |
31 | | #include <strings.h> |
32 | | #endif |
33 | | #ifdef HAVE_MALLOC_H |
34 | | #include <malloc.h> |
35 | | #endif |
36 | | #include <ctype.h> |
37 | | #include <sys/types.h> |
38 | | #ifdef HAVE_NETINET_IN_H |
39 | | #include <netinet/in.h> |
40 | | #endif |
41 | | #ifdef HAVE_ARPA_INET_H |
42 | | #include <arpa/inet.h> |
43 | | #endif |
44 | | |
45 | | #ifdef HAVE_NETDB_H |
46 | | #include <netdb.h> |
47 | | #endif |
48 | | |
49 | | #include <net-snmp/net-snmp-includes.h> |
50 | | #include <net-snmp/agent/net-snmp-agent-includes.h> |
51 | | |
52 | | #include <net-snmp/agent/agent_callbacks.h> |
53 | | #include "vacm_conf.h" |
54 | | |
55 | | #include "snmpd.h" |
56 | | |
57 | | /** |
58 | | * Registers the VACM token handlers for inserting rows into the vacm tables. |
59 | | * These tokens will be recognised by both 'snmpd' and 'snmptrapd'. |
60 | | */ |
61 | | void |
62 | 3.28k | init_vacm_config_tokens(void) { |
63 | 3.28k | snmpd_register_config_handler("group", vacm_parse_group, |
64 | 3.28k | vacm_free_group, |
65 | 3.28k | "name v1|v2c|usm|... security"); |
66 | 3.28k | snmpd_register_config_handler("access", vacm_parse_access, |
67 | 3.28k | vacm_free_access, |
68 | 3.28k | "name context model level prefix read write notify"); |
69 | 3.28k | snmpd_register_config_handler("setaccess", vacm_parse_setaccess, |
70 | 3.28k | vacm_free_access, |
71 | 3.28k | "name context model level prefix viewname viewval"); |
72 | 3.28k | snmpd_register_config_handler("view", vacm_parse_view, vacm_free_view, |
73 | 3.28k | "name type subtree [mask]"); |
74 | 3.28k | snmpd_register_const_config_handler("vacmView", |
75 | 3.28k | vacm_parse_config_view, NULL, NULL); |
76 | 3.28k | snmpd_register_const_config_handler("vacmGroup", |
77 | 3.28k | vacm_parse_config_group, |
78 | 3.28k | NULL, NULL); |
79 | 3.28k | snmpd_register_const_config_handler("vacmAccess", |
80 | 3.28k | vacm_parse_config_access, |
81 | 3.28k | NULL, NULL); |
82 | 3.28k | snmpd_register_const_config_handler("vacmAuthAccess", |
83 | 3.28k | vacm_parse_config_auth_access, |
84 | 3.28k | NULL, NULL); |
85 | | |
86 | | /* easy community auth handler */ |
87 | 3.28k | snmpd_register_config_handler("authcommunity", |
88 | 3.28k | vacm_parse_authcommunity, |
89 | 3.28k | NULL, "authtype1,authtype2 community [default|hostname|network/bits [oid|-V view [context]]]"); |
90 | | |
91 | | /* easy user auth handler */ |
92 | 3.28k | snmpd_register_config_handler("authuser", |
93 | 3.28k | vacm_parse_authuser, |
94 | 3.28k | NULL, "authtype1,authtype2 [-s secmodel] user [noauth|auth|priv [oid|-V view [context]]]"); |
95 | | /* easy group auth handler */ |
96 | 3.28k | snmpd_register_config_handler("authgroup", |
97 | 3.28k | vacm_parse_authuser, |
98 | 3.28k | NULL, "authtype1,authtype2 [-s secmodel] group [noauth|auth|priv [oid|-V view [context]]]"); |
99 | | |
100 | 3.28k | snmpd_register_config_handler("authaccess", vacm_parse_authaccess, |
101 | 3.28k | vacm_free_access, |
102 | 3.28k | "name authtype1,authtype2 [-s secmodel] group view [noauth|auth|priv [context|context*]]"); |
103 | | |
104 | | /* |
105 | | * Define standard views "_all_" and "_none_" |
106 | | */ |
107 | 3.28k | snmp_register_callback(SNMP_CALLBACK_LIBRARY, |
108 | 3.28k | SNMP_CALLBACK_PRE_READ_CONFIG, |
109 | 3.28k | vacm_standard_views, NULL); |
110 | 3.28k | snmp_register_callback(SNMP_CALLBACK_LIBRARY, |
111 | 3.28k | SNMP_CALLBACK_POST_READ_CONFIG, |
112 | 3.28k | vacm_warn_if_not_configured, NULL); |
113 | 3.28k | } |
114 | | |
115 | | /** |
116 | | * Registers the easier-to-use VACM token handlers for quick access rules. |
117 | | * These tokens will only be recognised by 'snmpd'. |
118 | | */ |
119 | | void |
120 | 3.28k | init_vacm_snmpd_easy_tokens(void) { |
121 | 3.28k | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
122 | 3.28k | snmpd_register_config_handler("rwcommunity", vacm_parse_rwcommunity, NULL, |
123 | 3.28k | "community [default|hostname|network/bits [oid|-V view [context]]]"); |
124 | 3.28k | snmpd_register_config_handler("rocommunity", vacm_parse_rocommunity, NULL, |
125 | 3.28k | "community [default|hostname|network/bits [oid|-V view [context]]]"); |
126 | 3.28k | #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN |
127 | 3.28k | snmpd_register_config_handler("rwcommunity6", vacm_parse_rwcommunity6, NULL, |
128 | 3.28k | "community [default|hostname|network/bits [oid|-V view [context]]]"); |
129 | 3.28k | snmpd_register_config_handler("rocommunity6", vacm_parse_rocommunity6, NULL, |
130 | 3.28k | "community [default|hostname|network/bits [oid|-V view [context]]]"); |
131 | 3.28k | #endif |
132 | 3.28k | #endif /* support for community based SNMP */ |
133 | 3.28k | snmpd_register_config_handler("rwuser", vacm_parse_rwuser, NULL, |
134 | 3.28k | "user [noauth|auth|priv [oid|-V view [context]]]"); |
135 | 3.28k | snmpd_register_config_handler("rouser", vacm_parse_rouser, NULL, |
136 | 3.28k | "user [noauth|auth|priv [oid|-V view [context]]]"); |
137 | 3.28k | } |
138 | | |
139 | | void |
140 | | init_vacm_conf(void) |
141 | 3.28k | { |
142 | 3.28k | init_vacm_config_tokens(); |
143 | 3.28k | init_vacm_snmpd_easy_tokens(); |
144 | | /* |
145 | | * register ourselves to handle access control ('snmpd' only) |
146 | | */ |
147 | 3.28k | snmp_register_callback(SNMP_CALLBACK_APPLICATION, |
148 | 3.28k | SNMPD_CALLBACK_ACM_CHECK, vacm_in_view_callback, |
149 | 3.28k | NULL); |
150 | 3.28k | snmp_register_callback(SNMP_CALLBACK_APPLICATION, |
151 | 3.28k | SNMPD_CALLBACK_ACM_CHECK_INITIAL, |
152 | 3.28k | vacm_in_view_callback, NULL); |
153 | 3.28k | snmp_register_callback(SNMP_CALLBACK_APPLICATION, |
154 | 3.28k | SNMPD_CALLBACK_ACM_CHECK_SUBTREE, |
155 | 3.28k | vacm_in_view_callback, NULL); |
156 | 3.28k | } |
157 | | |
158 | | |
159 | | |
160 | | void |
161 | | vacm_parse_group(const char *token, char *param) |
162 | 0 | { |
163 | 0 | char group[VACMSTRINGLEN], model[VACMSTRINGLEN], security[VACMSTRINGLEN]; |
164 | 0 | int imodel; |
165 | 0 | struct vacm_groupEntry *gp = NULL; |
166 | 0 | char *st; |
167 | |
|
168 | 0 | st = copy_nword(param, group, sizeof(group)-1); |
169 | 0 | st = copy_nword(st, model, sizeof(model)-1); |
170 | 0 | st = copy_nword(st, security, sizeof(security)-1); |
171 | |
|
172 | 0 | if (group[0] == 0) { |
173 | 0 | config_perror("missing GROUP parameter"); |
174 | 0 | return; |
175 | 0 | } |
176 | 0 | if (model[0] == 0) { |
177 | 0 | config_perror("missing MODEL parameter"); |
178 | 0 | return; |
179 | 0 | } |
180 | 0 | if (security[0] == 0) { |
181 | 0 | config_perror("missing SECURITY parameter"); |
182 | 0 | return; |
183 | 0 | } |
184 | 0 | if (strcasecmp(model, "v1") == 0) |
185 | 0 | imodel = SNMP_SEC_MODEL_SNMPv1; |
186 | 0 | else if (strcasecmp(model, "v2c") == 0) |
187 | 0 | imodel = SNMP_SEC_MODEL_SNMPv2c; |
188 | 0 | else if (strcasecmp(model, "any") == 0) { |
189 | 0 | config_perror |
190 | 0 | ("bad security model \"any\" should be: v1, v2c, usm or a registered security plugin name - installing anyway"); |
191 | 0 | imodel = SNMP_SEC_MODEL_ANY; |
192 | 0 | } else { |
193 | 0 | if ((imodel = se_find_value_in_slist("snmp_secmods", model)) == |
194 | 0 | SE_DNE) { |
195 | 0 | config_perror |
196 | 0 | ("bad security model, should be: v1, v2c or usm or a registered security plugin name"); |
197 | 0 | return; |
198 | 0 | } |
199 | 0 | } |
200 | 0 | if (strlen(security) + 1 > sizeof(gp->groupName)) { |
201 | 0 | config_perror("security name too long"); |
202 | 0 | return; |
203 | 0 | } |
204 | 0 | gp = vacm_createGroupEntry(imodel, security); |
205 | 0 | if (!gp) { |
206 | 0 | config_perror("failed to create group entry"); |
207 | 0 | return; |
208 | 0 | } |
209 | 0 | strlcpy(gp->groupName, group, sizeof(gp->groupName)); |
210 | 0 | gp->storageType = SNMP_STORAGE_PERMANENT; |
211 | 0 | gp->status = SNMP_ROW_ACTIVE; |
212 | 0 | free(gp->reserved); |
213 | 0 | gp->reserved = NULL; |
214 | 0 | } |
215 | | |
216 | | void |
217 | | vacm_free_group(void) |
218 | 6.57k | { |
219 | 6.57k | vacm_destroyAllGroupEntries(); |
220 | 6.57k | } |
221 | | |
222 | 0 | #define PARSE_CONT 0 |
223 | 0 | #define PARSE_FAIL 1 |
224 | | |
225 | | int |
226 | | _vacm_parse_access_common(const char *token, char *param, char **st, |
227 | | char **name, char **context, int *imodel, |
228 | | int *ilevel, int *iprefix) |
229 | 0 | { |
230 | 0 | char *model, *level, *prefix; |
231 | |
|
232 | 0 | *name = strtok_r(param, " \t\n", st); |
233 | 0 | if (!*name) { |
234 | 0 | config_perror("missing NAME parameter"); |
235 | 0 | return PARSE_FAIL; |
236 | 0 | } |
237 | 0 | *context = strtok_r(NULL, " \t\n", st); |
238 | 0 | if (!*context) { |
239 | 0 | config_perror("missing CONTEXT parameter"); |
240 | 0 | return PARSE_FAIL; |
241 | 0 | } |
242 | | |
243 | 0 | model = strtok_r(NULL, " \t\n", st); |
244 | 0 | if (!model) { |
245 | 0 | config_perror("missing MODEL parameter"); |
246 | 0 | return PARSE_FAIL; |
247 | 0 | } |
248 | 0 | level = strtok_r(NULL, " \t\n", st); |
249 | 0 | if (!level) { |
250 | 0 | config_perror("missing LEVEL parameter"); |
251 | 0 | return PARSE_FAIL; |
252 | 0 | } |
253 | 0 | prefix = strtok_r(NULL, " \t\n", st); |
254 | 0 | if (!prefix) { |
255 | 0 | config_perror("missing PREFIX parameter"); |
256 | 0 | return PARSE_FAIL; |
257 | 0 | } |
258 | | |
259 | 0 | if (strcmp(*context, "\"\"") == 0 || strcmp(*context, "\'\'") == 0) |
260 | 0 | **context = 0; |
261 | 0 | if (strcasecmp(model, "any") == 0) |
262 | 0 | *imodel = SNMP_SEC_MODEL_ANY; |
263 | 0 | else if (strcasecmp(model, "v1") == 0) |
264 | 0 | *imodel = SNMP_SEC_MODEL_SNMPv1; |
265 | 0 | else if (strcasecmp(model, "v2c") == 0) |
266 | 0 | *imodel = SNMP_SEC_MODEL_SNMPv2c; |
267 | 0 | else { |
268 | 0 | if ((*imodel = se_find_value_in_slist("snmp_secmods", model)) |
269 | 0 | == SE_DNE) { |
270 | 0 | config_perror |
271 | 0 | ("bad security model, should be: v1, v2c or usm or a registered security plugin name"); |
272 | 0 | return PARSE_FAIL; |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | 0 | if (strcasecmp(level, "noauth") == 0) |
277 | 0 | *ilevel = SNMP_SEC_LEVEL_NOAUTH; |
278 | 0 | else if (strcasecmp(level, "noauthnopriv") == 0) |
279 | 0 | *ilevel = SNMP_SEC_LEVEL_NOAUTH; |
280 | 0 | else if (strcasecmp(level, "auth") == 0) |
281 | 0 | *ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV; |
282 | 0 | else if (strcasecmp(level, "authnopriv") == 0) |
283 | 0 | *ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV; |
284 | 0 | else if (strcasecmp(level, "priv") == 0) |
285 | 0 | *ilevel = SNMP_SEC_LEVEL_AUTHPRIV; |
286 | 0 | else if (strcasecmp(level, "authpriv") == 0) |
287 | 0 | *ilevel = SNMP_SEC_LEVEL_AUTHPRIV; |
288 | 0 | else { |
289 | 0 | config_perror |
290 | 0 | ("bad security level (noauthnopriv, authnopriv, authpriv)"); |
291 | 0 | return PARSE_FAIL; |
292 | 0 | } |
293 | | |
294 | 0 | if (strcmp(prefix, "exact") == 0) |
295 | 0 | *iprefix = 1; |
296 | 0 | else if (strcmp(prefix, "prefix") == 0) |
297 | 0 | *iprefix = 2; |
298 | 0 | else if (strcmp(prefix, "0") == 0) { |
299 | 0 | config_perror |
300 | 0 | ("bad prefix match parameter \"0\", should be: exact or prefix - installing anyway"); |
301 | 0 | *iprefix = 1; |
302 | 0 | } else { |
303 | 0 | config_perror |
304 | 0 | ("bad prefix match parameter, should be: exact or prefix"); |
305 | 0 | return PARSE_FAIL; |
306 | 0 | } |
307 | | |
308 | 0 | return PARSE_CONT; |
309 | 0 | } |
310 | | |
311 | | /* **************************************/ |
312 | | /* authorization parsing token handlers */ |
313 | | /* **************************************/ |
314 | | |
315 | | int |
316 | | vacm_parse_authtokens(const char *token, char **confline) |
317 | 0 | { |
318 | 0 | char authspec[SNMP_MAXBUF_MEDIUM]; |
319 | 0 | char *strtok_state; |
320 | 0 | char *type; |
321 | 0 | int viewtype, viewtypes = 0; |
322 | |
|
323 | 0 | *confline = copy_nword(*confline, authspec, sizeof(authspec)); |
324 | | |
325 | 0 | DEBUGMSGTL(("vacm_parse_authtokens","parsing %s",authspec)); |
326 | 0 | if (!*confline) { |
327 | 0 | config_perror("Illegal configuration line: missing fields"); |
328 | 0 | return -1; |
329 | 0 | } |
330 | | |
331 | 0 | type = strtok_r(authspec, ",|:", &strtok_state); |
332 | 0 | while(type && *type != '\0') { |
333 | 0 | viewtype = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, type); |
334 | 0 | if (viewtype < 0 || viewtype >= VACM_MAX_VIEWS) { |
335 | 0 | config_perror("Illegal view name"); |
336 | 0 | } else { |
337 | 0 | viewtypes |= (1 << viewtype); |
338 | 0 | } |
339 | 0 | type = strtok_r(NULL, ",|:", &strtok_state); |
340 | 0 | } |
341 | 0 | DEBUGMSG(("vacm_parse_authtokens"," .. result = 0x%x\n",viewtypes)); |
342 | 0 | return viewtypes; |
343 | 0 | } |
344 | | |
345 | | void |
346 | | vacm_parse_authuser(const char *token, char *confline) |
347 | 0 | { |
348 | 0 | int viewtypes = vacm_parse_authtokens(token, &confline); |
349 | 0 | if (viewtypes != -1) |
350 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_V3, viewtypes); |
351 | 0 | } |
352 | | |
353 | | void |
354 | | vacm_parse_authcommunity(const char *token, char *confline) |
355 | 0 | { |
356 | 0 | int viewtypes = vacm_parse_authtokens(token, &confline); |
357 | 0 | if (viewtypes != -1) |
358 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_COM, viewtypes); |
359 | 0 | } |
360 | | |
361 | | void |
362 | | vacm_parse_authaccess(const char *token, char *confline) |
363 | 0 | { |
364 | 0 | char *group, *view, *tmp; |
365 | 0 | const char *context; |
366 | 0 | int model = SNMP_SEC_MODEL_ANY; |
367 | 0 | int level, prefix; |
368 | 0 | int i; |
369 | 0 | char *st; |
370 | 0 | struct vacm_accessEntry *ap; |
371 | 0 | int viewtypes = vacm_parse_authtokens(token, &confline); |
372 | |
|
373 | 0 | if (viewtypes == -1) |
374 | 0 | return; |
375 | | |
376 | 0 | group = strtok_r(confline, " \t\n", &st); |
377 | 0 | if (!group) { |
378 | 0 | config_perror("missing GROUP parameter"); |
379 | 0 | return; |
380 | 0 | } |
381 | 0 | view = strtok_r(NULL, " \t\n", &st); |
382 | 0 | if (!view) { |
383 | 0 | config_perror("missing VIEW parameter"); |
384 | 0 | return; |
385 | 0 | } |
386 | | |
387 | | /* |
388 | | * Check for security model option |
389 | | */ |
390 | 0 | if ( strcasecmp(view, "-s") == 0 ) { |
391 | 0 | tmp = strtok_r(NULL, " \t\n", &st); |
392 | 0 | if (tmp) { |
393 | 0 | if (strcasecmp(tmp, "any") == 0) |
394 | 0 | model = SNMP_SEC_MODEL_ANY; |
395 | 0 | else if (strcasecmp(tmp, "v1") == 0) |
396 | 0 | model = SNMP_SEC_MODEL_SNMPv1; |
397 | 0 | else if (strcasecmp(tmp, "v2c") == 0) |
398 | 0 | model = SNMP_SEC_MODEL_SNMPv2c; |
399 | 0 | else { |
400 | 0 | model = se_find_value_in_slist("snmp_secmods", tmp); |
401 | 0 | if (model == SE_DNE) { |
402 | 0 | config_perror |
403 | 0 | ("bad security model, should be: v1, v2c or usm or a registered security plugin name"); |
404 | 0 | return; |
405 | 0 | } |
406 | 0 | } |
407 | 0 | } else { |
408 | 0 | config_perror("missing SECMODEL parameter"); |
409 | 0 | return; |
410 | 0 | } |
411 | 0 | view = strtok_r(NULL, " \t\n", &st); |
412 | 0 | if (!view) { |
413 | 0 | config_perror("missing VIEW parameter"); |
414 | 0 | return; |
415 | 0 | } |
416 | 0 | } |
417 | 0 | if (strlen(view) >= VACMSTRINGLEN ) { |
418 | 0 | config_perror("View value too long"); |
419 | 0 | return; |
420 | 0 | } |
421 | | |
422 | | /* |
423 | | * Now parse optional fields, or provide default values |
424 | | */ |
425 | | |
426 | 0 | tmp = strtok_r(NULL, " \t\n", &st); |
427 | 0 | if (tmp) { |
428 | 0 | if (strcasecmp(tmp, "noauth") == 0) |
429 | 0 | level = SNMP_SEC_LEVEL_NOAUTH; |
430 | 0 | else if (strcasecmp(tmp, "noauthnopriv") == 0) |
431 | 0 | level = SNMP_SEC_LEVEL_NOAUTH; |
432 | 0 | else if (strcasecmp(tmp, "auth") == 0) |
433 | 0 | level = SNMP_SEC_LEVEL_AUTHNOPRIV; |
434 | 0 | else if (strcasecmp(tmp, "authnopriv") == 0) |
435 | 0 | level = SNMP_SEC_LEVEL_AUTHNOPRIV; |
436 | 0 | else if (strcasecmp(tmp, "priv") == 0) |
437 | 0 | level = SNMP_SEC_LEVEL_AUTHPRIV; |
438 | 0 | else if (strcasecmp(tmp, "authpriv") == 0) |
439 | 0 | level = SNMP_SEC_LEVEL_AUTHPRIV; |
440 | 0 | else { |
441 | 0 | config_perror |
442 | 0 | ("bad security level (noauthnopriv, authnopriv, authpriv)"); |
443 | 0 | return; |
444 | 0 | } |
445 | 0 | } else { |
446 | | /* What about SNMP_SEC_MODEL_ANY ?? */ |
447 | 0 | if ( model == SNMP_SEC_MODEL_SNMPv1 || |
448 | 0 | model == SNMP_SEC_MODEL_SNMPv2c ) |
449 | 0 | level = SNMP_SEC_LEVEL_NOAUTH; |
450 | 0 | else |
451 | 0 | level = SNMP_SEC_LEVEL_AUTHNOPRIV; |
452 | 0 | } |
453 | | |
454 | | |
455 | 0 | context = tmp = strtok_r(NULL, " \t\n", &st); |
456 | 0 | if (tmp) { |
457 | 0 | tmp = (tmp + strlen(tmp)-1); |
458 | 0 | if (tmp && *tmp == '*') { |
459 | 0 | *tmp = '\0'; |
460 | 0 | prefix = 2; |
461 | 0 | } else { |
462 | 0 | prefix = 1; |
463 | 0 | } |
464 | 0 | } else { |
465 | 0 | context = ""; |
466 | 0 | prefix = 1; /* Or prefix(2) ?? */ |
467 | 0 | } |
468 | | |
469 | | /* |
470 | | * Now we can create the access entry |
471 | | */ |
472 | 0 | ap = vacm_getAccessEntry(group, context, model, level); |
473 | 0 | if (!ap) { |
474 | 0 | ap = vacm_createAccessEntry(group, context, model, level); |
475 | 0 | DEBUGMSGTL(("vacm:conf:authaccess", |
476 | 0 | "no existing access found; creating a new one\n")); |
477 | 0 | } else { |
478 | 0 | DEBUGMSGTL(("vacm:conf:authaccess", |
479 | 0 | "existing access found, using it\n")); |
480 | 0 | } |
481 | 0 | if (!ap) { |
482 | 0 | config_perror("failed to create access entry"); |
483 | 0 | return; |
484 | 0 | } |
485 | | |
486 | 0 | for (i = 0; i < VACM_MAX_VIEWS; i++) { |
487 | 0 | if (viewtypes & (1 << i)) { |
488 | 0 | strlcpy(ap->views[i], view, sizeof(ap->views[i])); |
489 | 0 | } |
490 | 0 | } |
491 | 0 | ap->contextMatch = prefix; |
492 | 0 | ap->storageType = SNMP_STORAGE_PERMANENT; |
493 | 0 | ap->status = SNMP_ROW_ACTIVE; |
494 | 0 | if (ap->reserved) |
495 | 0 | free(ap->reserved); |
496 | 0 | ap->reserved = NULL; |
497 | 0 | } |
498 | | |
499 | | void |
500 | | vacm_parse_setaccess(const char *token, char *param) |
501 | 0 | { |
502 | 0 | char *name, *context, *viewname, *viewval; |
503 | 0 | int imodel, ilevel, iprefix; |
504 | 0 | int viewnum; |
505 | 0 | char *st; |
506 | 0 | struct vacm_accessEntry *ap; |
507 | | |
508 | 0 | if (_vacm_parse_access_common(token, param, &st, &name, |
509 | 0 | &context, &imodel, &ilevel, &iprefix) |
510 | 0 | == PARSE_FAIL) { |
511 | 0 | return; |
512 | 0 | } |
513 | | |
514 | 0 | viewname = strtok_r(NULL, " \t\n", &st); |
515 | 0 | if (!viewname) { |
516 | 0 | config_perror("missing viewname parameter"); |
517 | 0 | return; |
518 | 0 | } |
519 | 0 | viewval = strtok_r(NULL, " \t\n", &st); |
520 | 0 | if (!viewval) { |
521 | 0 | config_perror("missing viewval parameter"); |
522 | 0 | return; |
523 | 0 | } |
524 | | |
525 | 0 | if (strlen(viewval) + 1 > sizeof(ap->views[VACM_VIEW_NOTIFY])) { |
526 | 0 | config_perror("View value too long"); |
527 | 0 | return; |
528 | 0 | } |
529 | | |
530 | 0 | viewnum = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, viewname); |
531 | 0 | if (viewnum < 0 || viewnum >= VACM_MAX_VIEWS) { |
532 | 0 | config_perror("Illegal view name"); |
533 | 0 | return; |
534 | 0 | } |
535 | | |
536 | 0 | ap = vacm_getAccessEntry(name, context, imodel, ilevel); |
537 | 0 | if (!ap) { |
538 | 0 | ap = vacm_createAccessEntry(name, context, imodel, ilevel); |
539 | 0 | DEBUGMSGTL(("vacm:conf:setaccess", |
540 | 0 | "no existing access found; creating a new one\n")); |
541 | 0 | } else { |
542 | 0 | DEBUGMSGTL(("vacm:conf:setaccess", |
543 | 0 | "existing access found, using it\n")); |
544 | 0 | } |
545 | 0 | if (!ap) { |
546 | 0 | config_perror("failed to create access entry"); |
547 | 0 | return; |
548 | 0 | } |
549 | | |
550 | 0 | strlcpy(ap->views[viewnum], viewval, sizeof(ap->views[viewnum])); |
551 | 0 | ap->contextMatch = iprefix; |
552 | 0 | ap->storageType = SNMP_STORAGE_PERMANENT; |
553 | 0 | ap->status = SNMP_ROW_ACTIVE; |
554 | 0 | free(ap->reserved); |
555 | 0 | ap->reserved = NULL; |
556 | 0 | } |
557 | | |
558 | | void |
559 | | vacm_parse_access(const char *token, char *param) |
560 | 0 | { |
561 | 0 | char *name, *context, *readView, *writeView, *notify; |
562 | 0 | int imodel, ilevel, iprefix; |
563 | 0 | struct vacm_accessEntry *ap; |
564 | 0 | char *st; |
565 | | |
566 | | |
567 | 0 | if (_vacm_parse_access_common(token, param, &st, &name, |
568 | 0 | &context, &imodel, &ilevel, &iprefix) |
569 | 0 | == PARSE_FAIL) { |
570 | 0 | return; |
571 | 0 | } |
572 | | |
573 | 0 | readView = strtok_r(NULL, " \t\n", &st); |
574 | 0 | if (!readView) { |
575 | 0 | config_perror("missing readView parameter"); |
576 | 0 | return; |
577 | 0 | } |
578 | 0 | writeView = strtok_r(NULL, " \t\n", &st); |
579 | 0 | if (!writeView) { |
580 | 0 | config_perror("missing writeView parameter"); |
581 | 0 | return; |
582 | 0 | } |
583 | 0 | notify = strtok_r(NULL, " \t\n", &st); |
584 | 0 | if (!notify) { |
585 | 0 | config_perror("missing notifyView parameter"); |
586 | 0 | return; |
587 | 0 | } |
588 | | |
589 | 0 | if (strlen(readView) + 1 > sizeof(ap->views[VACM_VIEW_READ])) { |
590 | 0 | config_perror("readView too long"); |
591 | 0 | return; |
592 | 0 | } |
593 | 0 | if (strlen(writeView) + 1 > sizeof(ap->views[VACM_VIEW_WRITE])) { |
594 | 0 | config_perror("writeView too long"); |
595 | 0 | return; |
596 | 0 | } |
597 | 0 | if (strlen(notify) + 1 > sizeof(ap->views[VACM_VIEW_NOTIFY])) { |
598 | 0 | config_perror("notifyView too long"); |
599 | 0 | return; |
600 | 0 | } |
601 | 0 | ap = vacm_createAccessEntry(name, context, imodel, ilevel); |
602 | 0 | if (!ap) { |
603 | 0 | config_perror("failed to create access entry"); |
604 | 0 | return; |
605 | 0 | } |
606 | 0 | strlcpy(ap->views[VACM_VIEW_READ], readView, |
607 | 0 | sizeof(ap->views[VACM_VIEW_READ])); |
608 | 0 | strlcpy(ap->views[VACM_VIEW_WRITE], writeView, |
609 | 0 | sizeof(ap->views[VACM_VIEW_WRITE])); |
610 | 0 | strlcpy(ap->views[VACM_VIEW_NOTIFY], notify, |
611 | 0 | sizeof(ap->views[VACM_VIEW_NOTIFY])); |
612 | 0 | ap->contextMatch = iprefix; |
613 | 0 | ap->storageType = SNMP_STORAGE_PERMANENT; |
614 | 0 | ap->status = SNMP_ROW_ACTIVE; |
615 | 0 | free(ap->reserved); |
616 | 0 | ap->reserved = NULL; |
617 | 0 | } |
618 | | |
619 | | void |
620 | | vacm_free_access(void) |
621 | 19.7k | { |
622 | 19.7k | vacm_destroyAllAccessEntries(); |
623 | 19.7k | } |
624 | | |
625 | | void |
626 | | vacm_parse_view(const char *token, char *param) |
627 | 19.7k | { |
628 | 19.7k | char *name, *type, *subtree, *mask; |
629 | 19.7k | int inclexcl; |
630 | 19.7k | struct vacm_viewEntry *vp; |
631 | 19.7k | oid suboid[MAX_OID_LEN]; |
632 | 19.7k | size_t suboid_len = 0; |
633 | 19.7k | size_t mask_len = 0; |
634 | 19.7k | u_char viewMask[VACMSTRINGLEN]; |
635 | 19.7k | size_t i; |
636 | 19.7k | char *st; |
637 | | |
638 | 19.7k | name = strtok_r(param, " \t\n", &st); |
639 | 19.7k | if (!name) { |
640 | 0 | config_perror("missing NAME parameter"); |
641 | 0 | return; |
642 | 0 | } |
643 | 19.7k | type = strtok_r(NULL, " \n\t", &st); |
644 | 19.7k | if (!type) { |
645 | 0 | config_perror("missing TYPE parameter"); |
646 | 0 | return; |
647 | 0 | } |
648 | 19.7k | subtree = strtok_r(NULL, " \t\n", &st); |
649 | 19.7k | if (!subtree) { |
650 | 0 | config_perror("missing SUBTREE parameter"); |
651 | 0 | return; |
652 | 0 | } |
653 | 19.7k | mask = strtok_r(NULL, "\0", &st); |
654 | | |
655 | 19.7k | if (strcmp(type, "included") == 0) |
656 | 9.86k | inclexcl = SNMP_VIEW_INCLUDED; |
657 | 9.86k | else if (strcmp(type, "excluded") == 0) |
658 | 9.86k | inclexcl = SNMP_VIEW_EXCLUDED; |
659 | 0 | else { |
660 | 0 | config_perror("TYPE must be included/excluded?"); |
661 | 0 | return; |
662 | 0 | } |
663 | 19.7k | suboid_len = strlen(subtree)-1; |
664 | 19.7k | if (subtree[suboid_len] == '.') |
665 | 0 | subtree[suboid_len] = '\0'; /* stamp on a trailing . */ |
666 | 19.7k | suboid_len = MAX_OID_LEN; |
667 | 19.7k | if (!snmp_parse_oid(subtree, suboid, &suboid_len)) { |
668 | 0 | config_perror("bad SUBTREE object id"); |
669 | 0 | return; |
670 | 0 | } |
671 | 19.7k | if (mask) { |
672 | 0 | unsigned int val; |
673 | 0 | i = 0; |
674 | 0 | for (mask = strtok_r(mask, " .:", &st); mask; mask = strtok_r(NULL, " .:", &st)) { |
675 | 0 | if (i >= sizeof(viewMask)) { |
676 | 0 | config_perror("MASK too long"); |
677 | 0 | return; |
678 | 0 | } |
679 | 0 | if (sscanf(mask, "%x", &val) == 0) { |
680 | 0 | config_perror("invalid MASK"); |
681 | 0 | return; |
682 | 0 | } |
683 | 0 | viewMask[i] = val; |
684 | 0 | i++; |
685 | 0 | } |
686 | 0 | mask_len = i; |
687 | 19.7k | } else { |
688 | 690k | for (i = 0; i < sizeof(viewMask); i++) |
689 | 670k | viewMask[i] = 0xff; |
690 | 19.7k | } |
691 | 19.7k | vp = vacm_createViewEntry(name, suboid, suboid_len); |
692 | 19.7k | if (!vp) { |
693 | 0 | config_perror("failed to create view entry"); |
694 | 0 | return; |
695 | 0 | } |
696 | 19.7k | memcpy(vp->viewMask, viewMask, sizeof(viewMask)); |
697 | 19.7k | vp->viewMaskLen = mask_len; |
698 | 19.7k | vp->viewType = inclexcl; |
699 | 19.7k | vp->viewStorageType = SNMP_STORAGE_PERMANENT; |
700 | 19.7k | vp->viewStatus = SNMP_ROW_ACTIVE; |
701 | 19.7k | free(vp->reserved); |
702 | 19.7k | vp->reserved = NULL; |
703 | 19.7k | } |
704 | | |
705 | | void |
706 | | vacm_free_view(void) |
707 | 6.57k | { |
708 | 6.57k | vacm_destroyAllViewEntries(); |
709 | 6.57k | } |
710 | | |
711 | | void |
712 | | vacm_gen_com2sec(int commcount, const char *community, const char *addressname, |
713 | | const char *publishtoken, |
714 | | void (*parser)(const char *, char *), |
715 | | char *secname, size_t secname_len, |
716 | | char *viewname, size_t viewname_len, int version, |
717 | | const char *context) |
718 | 0 | { |
719 | 0 | char line[SPRINT_MAX_LEN]; |
720 | | |
721 | | /* |
722 | | * com2sec6|comsec [-Cn CONTEXT] anonymousSecNameNUM ADDRESS COMMUNITY |
723 | | */ |
724 | 0 | snprintf(secname, secname_len-1, "comm%d", commcount); |
725 | 0 | secname[secname_len-1] = '\0'; |
726 | 0 | if (viewname) { |
727 | 0 | snprintf(viewname, viewname_len-1, "viewComm%d", commcount); |
728 | 0 | viewname[viewname_len-1] = '\0'; |
729 | 0 | } |
730 | 0 | if ( context && *context ) |
731 | 0 | snprintf(line, sizeof(line), "-Cn %s %s %s '%s'", |
732 | 0 | context, secname, addressname, community); |
733 | 0 | else |
734 | 0 | snprintf(line, sizeof(line), "%s %s '%s'", |
735 | 0 | secname, addressname, community); |
736 | 0 | line[ sizeof(line)-1 ] = 0; |
737 | 0 | DEBUGMSGTL((publishtoken, "passing: %s %s\n", publishtoken, line)); |
738 | 0 | (*parser)(publishtoken, line); |
739 | | |
740 | | /* |
741 | | * sec->group mapping |
742 | | */ |
743 | | /* |
744 | | * group anonymousGroupNameNUM any anonymousSecNameNUM |
745 | | */ |
746 | 0 | if ( version & SNMP_SEC_MODEL_SNMPv1 ) { |
747 | 0 | snprintf(line, sizeof(line), |
748 | 0 | "grp%.28s v1 %s", secname, secname); |
749 | 0 | line[ sizeof(line)-1 ] = 0; |
750 | 0 | DEBUGMSGTL((publishtoken, "passing: %s %s\n", "group", line)); |
751 | 0 | vacm_parse_group("group", line); |
752 | 0 | } |
753 | |
|
754 | 0 | if ( version & SNMP_SEC_MODEL_SNMPv2c ) { |
755 | 0 | snprintf(line, sizeof(line), |
756 | 0 | "grp%.28s v2c %s", secname, secname); |
757 | 0 | line[ sizeof(line)-1 ] = 0; |
758 | 0 | DEBUGMSGTL((publishtoken, "passing: %s %s\n", "group", line)); |
759 | 0 | vacm_parse_group("group", line); |
760 | 0 | } |
761 | 0 | } |
762 | | |
763 | | void |
764 | | vacm_parse_rwuser(const char *token, char *confline) |
765 | 0 | { |
766 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_V3, |
767 | 0 | VACM_VIEW_READ_BIT | VACM_VIEW_WRITE_BIT); |
768 | 0 | } |
769 | | |
770 | | void |
771 | | vacm_parse_rouser(const char *token, char *confline) |
772 | 0 | { |
773 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_V3, |
774 | 0 | VACM_VIEW_READ_BIT); |
775 | 0 | } |
776 | | |
777 | | void |
778 | | vacm_parse_rocommunity(const char *token, char *confline) |
779 | 0 | { |
780 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_COMIPV4, |
781 | 0 | VACM_VIEW_READ_BIT); |
782 | 0 | } |
783 | | |
784 | | void |
785 | | vacm_parse_rwcommunity(const char *token, char *confline) |
786 | 0 | { |
787 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_COMIPV4, |
788 | 0 | VACM_VIEW_READ_BIT | VACM_VIEW_WRITE_BIT); |
789 | 0 | } |
790 | | |
791 | | void |
792 | | vacm_parse_rocommunity6(const char *token, char *confline) |
793 | 0 | { |
794 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_COMIPV6, |
795 | 0 | VACM_VIEW_READ_BIT); |
796 | 0 | } |
797 | | |
798 | | void |
799 | | vacm_parse_rwcommunity6(const char *token, char *confline) |
800 | 0 | { |
801 | 0 | vacm_create_simple(token, confline, VACM_CREATE_SIMPLE_COMIPV6, |
802 | 0 | VACM_VIEW_READ_BIT | VACM_VIEW_WRITE_BIT); |
803 | 0 | } |
804 | | |
805 | | |
806 | | void |
807 | | vacm_create_simple(const char *token, char *confline, |
808 | | int parsetype, int viewtypes) |
809 | 0 | { |
810 | 0 | char line[SPRINT_MAX_LEN]; |
811 | 0 | char community[COMMUNITY_MAX_LEN]; |
812 | 0 | char theoid[SPRINT_MAX_LEN]; |
813 | 0 | char viewname[SPRINT_MAX_LEN]; |
814 | 0 | char *view_ptr = viewname; |
815 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
816 | 0 | char addressname[SPRINT_MAX_LEN]; |
817 | | /* Conveniently, the community-based security |
818 | | model values can also be used as bit flags */ |
819 | 0 | int commversion = SNMP_SEC_MODEL_SNMPv1 | |
820 | 0 | SNMP_SEC_MODEL_SNMPv2c; |
821 | 0 | #endif |
822 | 0 | const char *rw = "none"; |
823 | 0 | char model[SPRINT_MAX_LEN]; |
824 | 0 | char *cp, *tmp; |
825 | 0 | char secname[SPRINT_MAX_LEN]; |
826 | 0 | char grpname[SPRINT_MAX_LEN]; |
827 | 0 | char authlevel[SPRINT_MAX_LEN]; |
828 | 0 | char context[SPRINT_MAX_LEN]; |
829 | 0 | int ctxprefix = 1; /* Default to matching all contexts */ |
830 | 0 | static int commcount = 0; |
831 | | |
832 | | /* |
833 | | * init |
834 | | */ |
835 | 0 | strcpy(model, "any"); |
836 | 0 | memset(context, 0, sizeof(context)); |
837 | 0 | memset(secname, 0, sizeof(secname)); |
838 | 0 | memset(grpname, 0, sizeof(grpname)); |
839 | | |
840 | | /* |
841 | | * community name or user name |
842 | | */ |
843 | 0 | cp = copy_nword(confline, community, sizeof(community)); |
844 | |
|
845 | 0 | if (parsetype == VACM_CREATE_SIMPLE_V3) { |
846 | | /* |
847 | | * maybe security model type |
848 | | */ |
849 | 0 | if (strcmp(community, "-s") == 0) { |
850 | | /* |
851 | | * -s model ... |
852 | | */ |
853 | 0 | if (cp) |
854 | 0 | cp = copy_nword(cp, model, sizeof(model)); |
855 | 0 | if (!cp) { |
856 | 0 | config_perror("illegal line"); |
857 | 0 | return; |
858 | 0 | } |
859 | 0 | if (cp) |
860 | 0 | cp = copy_nword(cp, community, sizeof(community)); |
861 | 0 | } else { |
862 | 0 | strcpy(model, "usm"); |
863 | 0 | } |
864 | | /* |
865 | | * authentication level |
866 | | */ |
867 | 0 | if (cp && *cp) |
868 | 0 | cp = copy_nword(cp, authlevel, sizeof(authlevel)); |
869 | 0 | else |
870 | 0 | strcpy(authlevel, "auth"); |
871 | 0 | DEBUGMSGTL((token, "setting auth level: \"%s\"\n", authlevel)); |
872 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
873 | 0 | } else { |
874 | 0 | if (strcmp(community, "-v") == 0) { |
875 | | /* |
876 | | * -v version ... |
877 | | */ |
878 | 0 | if (cp) |
879 | 0 | cp = copy_nword(cp, model, sizeof(model)); |
880 | 0 | if (!cp) { |
881 | 0 | config_perror("illegal line"); |
882 | 0 | return; |
883 | 0 | } |
884 | 0 | if ( strcasecmp( model, "1" ) == 0 ) |
885 | 0 | strcpy(model, "v1"); |
886 | 0 | if ( strcasecmp( model, "v1" ) == 0 ) |
887 | 0 | commversion = SNMP_SEC_MODEL_SNMPv1; |
888 | 0 | if ( strcasecmp( model, "2c" ) == 0 ) |
889 | 0 | strcpy(model, "v2c"); |
890 | 0 | if ( strcasecmp( model, "v2c" ) == 0 ) |
891 | 0 | commversion = SNMP_SEC_MODEL_SNMPv2c; |
892 | 0 | if (cp) |
893 | 0 | cp = copy_nword(cp, community, sizeof(community)); |
894 | 0 | } |
895 | | /* |
896 | | * source address |
897 | | */ |
898 | 0 | if (cp && *cp) { |
899 | 0 | cp = copy_nword(cp, addressname, sizeof(addressname)); |
900 | 0 | } else { |
901 | 0 | strcpy(addressname, "default"); |
902 | 0 | } |
903 | | /* |
904 | | * authlevel has to be noauth |
905 | | */ |
906 | 0 | strcpy(authlevel, "noauth"); |
907 | 0 | #endif /* support for community based SNMP */ |
908 | 0 | } |
909 | | |
910 | | /* |
911 | | * oid they can touch |
912 | | */ |
913 | 0 | if (cp && *cp) { |
914 | 0 | if (strncmp(cp, "-V ", 3) == 0) { |
915 | 0 | cp = skip_token(cp); |
916 | 0 | cp = copy_nword(cp, viewname, sizeof(viewname)); |
917 | 0 | view_ptr = NULL; |
918 | 0 | } else { |
919 | 0 | cp = copy_nword(cp, theoid, sizeof(theoid)); |
920 | 0 | } |
921 | 0 | } else { |
922 | 0 | strcpy(theoid, ".1"); |
923 | 0 | strcpy(viewname, "_all_"); |
924 | 0 | view_ptr = NULL; |
925 | 0 | } |
926 | | /* |
927 | | * optional, non-default context |
928 | | */ |
929 | 0 | if (cp && *cp) { |
930 | 0 | cp = copy_nword(cp, context, sizeof(context)); |
931 | 0 | tmp = (context + strlen(context)-1); |
932 | 0 | if (tmp && *tmp == '*') { |
933 | 0 | *tmp = '\0'; |
934 | 0 | ctxprefix = 1; |
935 | 0 | } else { |
936 | | /* |
937 | | * If no context field is given, then we default to matching |
938 | | * all contexts (for compatibility with previous releases). |
939 | | * But if a field context is specified (not ending with '*') |
940 | | * then this should be taken as an exact match. |
941 | | * Specifying a context field of "" will match the default |
942 | | * context (and *only* the default context). |
943 | | */ |
944 | 0 | ctxprefix = 0; |
945 | 0 | } |
946 | 0 | } |
947 | |
|
948 | 0 | if (viewtypes & VACM_VIEW_WRITE_BIT) |
949 | 0 | rw = viewname; |
950 | |
|
951 | 0 | commcount++; |
952 | |
|
953 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
954 | 0 | #ifdef NETSNMP_TRANSPORT_UDP_DOMAIN |
955 | 0 | if (parsetype == VACM_CREATE_SIMPLE_COMIPV4 || |
956 | 0 | parsetype == VACM_CREATE_SIMPLE_COM) { |
957 | 0 | vacm_gen_com2sec(commcount, community, addressname, |
958 | 0 | "com2sec", &netsnmp_udp_parse_security, |
959 | 0 | secname, sizeof(secname), |
960 | 0 | view_ptr, sizeof(viewname), commversion, context); |
961 | 0 | } |
962 | 0 | #endif |
963 | |
|
964 | 0 | #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN |
965 | 0 | if (parsetype == VACM_CREATE_SIMPLE_COMUNIX || |
966 | 0 | parsetype == VACM_CREATE_SIMPLE_COM) { |
967 | 0 | if ( *context ) |
968 | 0 | snprintf(line, sizeof(line), "-Cn %s %s %s '%s'", |
969 | 0 | context, secname, addressname, community); |
970 | 0 | else |
971 | 0 | snprintf(line, sizeof(line), "%s %s '%s'", |
972 | 0 | secname, addressname, community); |
973 | 0 | line[ sizeof(line)-1 ] = 0; |
974 | 0 | DEBUGMSGTL((token, "passing: %s %s\n", "com2secunix", line)); |
975 | 0 | netsnmp_unix_parse_security("com2secunix", line); |
976 | 0 | } |
977 | 0 | #endif |
978 | |
|
979 | 0 | #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN |
980 | 0 | if (parsetype == VACM_CREATE_SIMPLE_COMIPV6 || |
981 | 0 | parsetype == VACM_CREATE_SIMPLE_COM) { |
982 | 0 | vacm_gen_com2sec(commcount, community, addressname, |
983 | 0 | "com2sec6", &netsnmp_udp6_parse_security, |
984 | 0 | secname, sizeof(secname), |
985 | 0 | view_ptr, sizeof(viewname), commversion, context); |
986 | 0 | } |
987 | 0 | #endif |
988 | 0 | #endif /* support for community based SNMP */ |
989 | |
|
990 | 0 | if (parsetype == VACM_CREATE_SIMPLE_V3) { |
991 | | /* support for SNMPv3 user names */ |
992 | 0 | if (view_ptr) { |
993 | 0 | sprintf(viewname,"viewUSM%d",commcount); |
994 | 0 | } |
995 | 0 | if ( strcmp( token, "authgroup" ) == 0 ) { |
996 | 0 | strlcpy(grpname, community, sizeof(grpname)); |
997 | 0 | } else { |
998 | 0 | strlcpy(secname, community, sizeof(secname)); |
999 | | |
1000 | | /* |
1001 | | * sec->group mapping |
1002 | | */ |
1003 | | /* |
1004 | | * group anonymousGroupNameNUM any anonymousSecNameNUM |
1005 | | */ |
1006 | 0 | snprintf(grpname, sizeof(grpname), "grp%.28s", secname); |
1007 | 0 | for (tmp=grpname; *tmp; tmp++) |
1008 | 0 | if (!isalnum((unsigned char)(*tmp))) |
1009 | 0 | *tmp = '_'; |
1010 | 0 | snprintf(line, sizeof(line), |
1011 | 0 | "%s %s \"%s\"", grpname, model, secname); |
1012 | 0 | line[ sizeof(line)-1 ] = 0; |
1013 | 0 | DEBUGMSGTL((token, "passing: %s %s\n", "group", line)); |
1014 | 0 | vacm_parse_group("group", line); |
1015 | 0 | } |
1016 | 0 | } else { |
1017 | 0 | snprintf(grpname, sizeof(grpname), "grp%.28s", secname); |
1018 | 0 | for (tmp=grpname; *tmp; tmp++) |
1019 | 0 | if (!isalnum((unsigned char)(*tmp))) |
1020 | 0 | *tmp = '_'; |
1021 | 0 | } |
1022 | | |
1023 | | /* |
1024 | | * view definition |
1025 | | */ |
1026 | | /* |
1027 | | * view anonymousViewNUM included OID |
1028 | | */ |
1029 | 0 | if (view_ptr) { |
1030 | 0 | snprintf(line, sizeof(line), "%s included %s", viewname, theoid); |
1031 | 0 | line[ sizeof(line)-1 ] = 0; |
1032 | 0 | DEBUGMSGTL((token, "passing: %s %s\n", "view", line)); |
1033 | 0 | vacm_parse_view("view", line); |
1034 | 0 | } |
1035 | | |
1036 | | /* |
1037 | | * map everything together |
1038 | | */ |
1039 | 0 | if ((viewtypes == VACM_VIEW_READ_BIT) || |
1040 | 0 | (viewtypes == (VACM_VIEW_READ_BIT | VACM_VIEW_WRITE_BIT))) { |
1041 | | /* Use the simple line access command */ |
1042 | | /* |
1043 | | * access anonymousGroupNameNUM "" MODEL AUTHTYPE prefix anonymousViewNUM [none/anonymousViewNUM] [none/anonymousViewNUM] |
1044 | | */ |
1045 | 0 | snprintf(line, sizeof(line), |
1046 | 0 | "%s %s %s %s %s %s %s %s", |
1047 | 0 | grpname, context[0] ? context : "\"\"", |
1048 | 0 | model, authlevel, |
1049 | 0 | (ctxprefix ? "prefix" : "exact"), |
1050 | 0 | viewname, rw, rw); |
1051 | 0 | line[ sizeof(line)-1 ] = 0; |
1052 | 0 | DEBUGMSGTL((token, "passing: %s %s\n", "access", line)); |
1053 | 0 | vacm_parse_access("access", line); |
1054 | 0 | } else { |
1055 | | /* Use one setaccess line per access type */ |
1056 | | /* |
1057 | | * setaccess anonymousGroupNameNUM "" MODEL AUTHTYPE prefix viewname viewval |
1058 | | */ |
1059 | 0 | int i; |
1060 | 0 | DEBUGMSGTL((token, " checking view levels for %x\n", viewtypes)); |
1061 | 0 | for(i = 0; i <= VACM_MAX_VIEWS; i++) { |
1062 | 0 | if (viewtypes & (1 << i)) { |
1063 | 0 | snprintf(line, sizeof(line), |
1064 | 0 | "%s %s %s %s %s %s %s", |
1065 | 0 | grpname, context[0] ? context : "\"\"", |
1066 | 0 | model, authlevel, |
1067 | 0 | (ctxprefix ? "prefix" : "exact"), |
1068 | 0 | se_find_label_in_slist(VACM_VIEW_ENUM_NAME, i), |
1069 | 0 | viewname); |
1070 | 0 | line[ sizeof(line)-1 ] = 0; |
1071 | 0 | DEBUGMSGTL((token, "passing: %s %s\n", "setaccess", line)); |
1072 | 0 | vacm_parse_setaccess("setaccess", line); |
1073 | 0 | } |
1074 | 0 | } |
1075 | 0 | } |
1076 | 0 | } |
1077 | | |
1078 | | int |
1079 | | vacm_standard_views(int majorID, int minorID, void *serverarg, |
1080 | | void *clientarg) |
1081 | 3.28k | { |
1082 | 3.28k | char line[SPRINT_MAX_LEN]; |
1083 | | |
1084 | 3.28k | memset(line, 0, sizeof(line)); |
1085 | | |
1086 | 3.28k | snprintf(line, sizeof(line), "_all_ included .0"); |
1087 | 3.28k | vacm_parse_view("view", line); |
1088 | 3.28k | snprintf(line, sizeof(line), "_all_ included .1"); |
1089 | 3.28k | vacm_parse_view("view", line); |
1090 | 3.28k | snprintf(line, sizeof(line), "_all_ included .2"); |
1091 | 3.28k | vacm_parse_view("view", line); |
1092 | | |
1093 | 3.28k | snprintf(line, sizeof(line), "_none_ excluded .0"); |
1094 | 3.28k | vacm_parse_view("view", line); |
1095 | 3.28k | snprintf(line, sizeof(line), "_none_ excluded .1"); |
1096 | 3.28k | vacm_parse_view("view", line); |
1097 | 3.28k | snprintf(line, sizeof(line), "_none_ excluded .2"); |
1098 | 3.28k | vacm_parse_view("view", line); |
1099 | | |
1100 | 3.28k | return SNMP_ERR_NOERROR; |
1101 | 3.28k | } |
1102 | | |
1103 | | int |
1104 | | vacm_warn_if_not_configured(int majorID, int minorID, void *serverarg, |
1105 | | void *clientarg) |
1106 | 3.28k | { |
1107 | 3.28k | const char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, |
1108 | 3.28k | NETSNMP_DS_LIB_APPTYPE); |
1109 | 3.28k | const int agent_mode = netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, |
1110 | 3.28k | NETSNMP_DS_AGENT_ROLE); |
1111 | 3.28k | if (NULL==name) |
1112 | 0 | name = "snmpd"; |
1113 | | |
1114 | 3.28k | if (!vacm_is_configured()) { |
1115 | | /* |
1116 | | * An AgentX subagent relies on the master agent to apply suitable |
1117 | | * access control checks, so doesn't need local VACM configuration. |
1118 | | * The trap daemon has a separate check (see below). |
1119 | | * |
1120 | | * Otherwise, an AgentX master or SNMP standalone agent requires some |
1121 | | * form of VACM configuration. No config means that no incoming |
1122 | | * requests will be accepted, so warn the user accordingly. |
1123 | | */ |
1124 | 3.28k | if ((MASTER_AGENT == agent_mode) && (strcmp(name, "snmptrapd") != 0)) { |
1125 | 3.28k | snmp_log(LOG_WARNING, |
1126 | 3.28k | "Warning: no access control information configured.\n" |
1127 | 3.28k | " (Config search path: %s)\n" |
1128 | 3.28k | " It's unlikely this agent can serve any useful purpose in this state.\n" |
1129 | 3.28k | " Run \"snmpconf -g basic_setup\" to help you " |
1130 | 3.28k | "configure the %s.conf file for this agent.\n", |
1131 | 3.28k | get_configuration_directory(), name); |
1132 | 3.28k | } |
1133 | | |
1134 | | /* |
1135 | | * The trap daemon implements VACM-style access control for incoming |
1136 | | * notifications, but offers a way of turning this off (for backwards |
1137 | | * compatibility). Check for this explicitly, and warn if necessary. |
1138 | | * |
1139 | | * NB: The NETSNMP_DS_APP_NO_AUTHORIZATION definition is a duplicate |
1140 | | * of an identical setting in "apps/snmptrapd_ds.h". |
1141 | | * These two need to be kept in sync. |
1142 | | */ |
1143 | | #ifndef NETSNMP_DS_APP_NO_AUTHORIZATION |
1144 | | #define NETSNMP_DS_APP_NO_AUTHORIZATION 17 |
1145 | | #endif |
1146 | 3.28k | if (!strcmp(name, "snmptrapd") && |
1147 | 0 | !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, |
1148 | 0 | NETSNMP_DS_APP_NO_AUTHORIZATION)) { |
1149 | 0 | snmp_log(LOG_WARNING, |
1150 | 0 | "Warning: no access control information configured.\n" |
1151 | 0 | " (Config search path: %s)\n" |
1152 | 0 | "This receiver will *NOT* accept any incoming notifications.\n", |
1153 | 0 | get_configuration_directory()); |
1154 | 0 | } |
1155 | 3.28k | } |
1156 | 3.28k | return SNMP_ERR_NOERROR; |
1157 | 3.28k | } |
1158 | | |
1159 | | int |
1160 | | vacm_in_view_callback(int majorID, int minorID, void *serverarg, |
1161 | | void *clientarg) |
1162 | 0 | { |
1163 | 0 | struct view_parameters *view_parms = |
1164 | 0 | (struct view_parameters *) serverarg; |
1165 | 0 | int retval; |
1166 | |
|
1167 | 0 | if (view_parms == NULL) |
1168 | 0 | return 1; |
1169 | 0 | retval = vacm_in_view(view_parms->pdu, view_parms->name, |
1170 | 0 | view_parms->namelen, view_parms->check_subtree); |
1171 | 0 | if (retval != 0) |
1172 | 0 | view_parms->errorcode = retval; |
1173 | 0 | return retval; |
1174 | 0 | } |
1175 | | |
1176 | | |
1177 | | /** |
1178 | | * vacm_in_view: decides if a given PDU can be acted upon |
1179 | | * |
1180 | | * Parameters: |
1181 | | * *pdu |
1182 | | * *name |
1183 | | * namelen |
1184 | | * check_subtree |
1185 | | * |
1186 | | * Returns: |
1187 | | * VACM_SUCCESS(0) On success. |
1188 | | * VACM_NOSECNAME(1) Missing security name. |
1189 | | * VACM_NOGROUP(2) Missing group |
1190 | | * VACM_NOACCESS(3) Missing access |
1191 | | * VACM_NOVIEW(4) Missing view |
1192 | | * VACM_NOTINVIEW(5) Not in view |
1193 | | * VACM_NOSUCHCONTEXT(6) No Such Context |
1194 | | * VACM_SUBTREE_UNKNOWN(7) When testing an entire subtree, UNKNOWN (i.e., the entire |
1195 | | * subtree has both allowed and disallowed portions) |
1196 | | * |
1197 | | * Debug output listed as follows: |
1198 | | * \<securityName\> \<groupName\> \<viewName\> \<viewType\> |
1199 | | */ |
1200 | | int |
1201 | | vacm_in_view(netsnmp_pdu *pdu, oid * name, size_t namelen, |
1202 | | int check_subtree) |
1203 | 0 | { |
1204 | 0 | int viewtype; |
1205 | |
|
1206 | 0 | switch (pdu->command) { |
1207 | 0 | case SNMP_MSG_GET: |
1208 | 0 | case SNMP_MSG_GETNEXT: |
1209 | 0 | case SNMP_MSG_GETBULK: |
1210 | 0 | viewtype = VACM_VIEW_READ; |
1211 | 0 | break; |
1212 | 0 | #ifndef NETSNMP_NO_WRITE_SUPPORT |
1213 | 0 | case SNMP_MSG_SET: |
1214 | 0 | viewtype = VACM_VIEW_WRITE; |
1215 | 0 | break; |
1216 | 0 | #endif /* !NETSNMP_NO_WRITE_SUPPORT */ |
1217 | 0 | case SNMP_MSG_TRAP: |
1218 | 0 | case SNMP_MSG_TRAP2: |
1219 | 0 | case SNMP_MSG_INFORM: |
1220 | 0 | viewtype = VACM_VIEW_NOTIFY; |
1221 | 0 | break; |
1222 | 0 | default: |
1223 | 0 | snmp_log(LOG_ERR, "bad msg type in vacm_in_view: %d\n", |
1224 | 0 | pdu->command); |
1225 | 0 | viewtype = VACM_VIEW_READ; |
1226 | 0 | } |
1227 | 0 | return vacm_check_view(pdu, name, namelen, check_subtree, viewtype); |
1228 | 0 | } |
1229 | | |
1230 | | /** |
1231 | | * vacm_check_view: decides if a given PDU can be taken based on a view type |
1232 | | * |
1233 | | * Parameters: |
1234 | | * *pdu |
1235 | | * *name |
1236 | | * namelen |
1237 | | * check_subtree |
1238 | | * viewtype |
1239 | | * |
1240 | | * Returns: |
1241 | | * VACM_SUCCESS(0) On success. |
1242 | | * VACM_NOSECNAME(1) Missing security name. |
1243 | | * VACM_NOGROUP(2) Missing group |
1244 | | * VACM_NOACCESS(3) Missing access |
1245 | | * VACM_NOVIEW(4) Missing view |
1246 | | * VACM_NOTINVIEW(5) Not in view |
1247 | | * VACM_NOSUCHCONTEXT(6) No Such Context |
1248 | | * VACM_SUBTREE_UNKNOWN(7) When testing an entire subtree, UNKNOWN (i.e., the entire |
1249 | | * subtree has both allowed and disallowed portions) |
1250 | | * |
1251 | | * Debug output listed as follows: |
1252 | | * \<securityName\> \<groupName\> \<viewName\> \<viewType\> |
1253 | | */ |
1254 | | int |
1255 | | vacm_check_view(netsnmp_pdu *pdu, oid * name, size_t namelen, |
1256 | | int check_subtree, int viewtype) |
1257 | 0 | { |
1258 | 0 | return vacm_check_view_contents(pdu, name, namelen, check_subtree, viewtype, |
1259 | 0 | VACM_CHECK_VIEW_CONTENTS_NO_FLAGS); |
1260 | 0 | } |
1261 | | |
1262 | | int |
1263 | | vacm_check_view_contents(netsnmp_pdu *pdu, oid * name, size_t namelen, |
1264 | | int check_subtree, int viewtype, int flags) |
1265 | 0 | { |
1266 | 0 | struct vacm_accessEntry *ap; |
1267 | 0 | struct vacm_groupEntry *gp; |
1268 | 0 | struct vacm_viewEntry *vp; |
1269 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
1270 | 0 | char vacm_default_context[1] = ""; |
1271 | 0 | const char *contextName = vacm_default_context; |
1272 | 0 | const char *pdu_community; |
1273 | 0 | #endif |
1274 | 0 | const char *sn = NULL; |
1275 | 0 | char *vn; |
1276 | | |
1277 | | /* |
1278 | | * len defined by the vacmContextName object |
1279 | | */ |
1280 | 0 | #define CONTEXTNAMEINDEXLEN 32 |
1281 | 0 | char contextNameIndex[CONTEXTNAMEINDEXLEN + 1]; |
1282 | |
|
1283 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
1284 | | #if defined(NETSNMP_DISABLE_SNMPV1) |
1285 | | if (pdu->version == SNMP_VERSION_2c) |
1286 | | #else |
1287 | | #if defined(NETSNMP_DISABLE_SNMPV2C) |
1288 | | if (pdu->version == SNMP_VERSION_1) |
1289 | | #else |
1290 | 0 | if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) |
1291 | 0 | #endif |
1292 | 0 | #endif |
1293 | 0 | { |
1294 | 0 | pdu_community = (const char *) pdu->community; |
1295 | 0 | if (!pdu_community) |
1296 | 0 | pdu_community = ""; |
1297 | 0 | if (snmp_get_do_debugging()) { |
1298 | 0 | char *buf; |
1299 | 0 | if (pdu->community) { |
1300 | 0 | buf = (char *) malloc(1 + pdu->community_len); |
1301 | 0 | memcpy(buf, pdu->community, pdu->community_len); |
1302 | 0 | buf[pdu->community_len] = '\0'; |
1303 | 0 | } else { |
1304 | 0 | DEBUGMSGTL(("mibII/vacm_vars", "NULL community")); |
1305 | 0 | buf = strdup("NULL"); |
1306 | 0 | } |
1307 | |
|
1308 | 0 | DEBUGMSGTL(("mibII/vacm_vars", |
1309 | 0 | "vacm_in_view: ver=%ld, community=%s\n", |
1310 | 0 | pdu->version, buf)); |
1311 | 0 | free(buf); |
1312 | 0 | } |
1313 | | |
1314 | | /* |
1315 | | * Okay, if this PDU was received from a UDP or a TCP transport then |
1316 | | * ask the transport abstraction layer to map its source address and |
1317 | | * community string to a security name for us. |
1318 | | */ |
1319 | |
|
1320 | 0 | if (0) { |
1321 | 0 | #ifdef NETSNMP_TRANSPORT_UDP_DOMAIN |
1322 | 0 | } else if (pdu->tDomain == netsnmpUDPDomain |
1323 | 0 | #ifdef NETSNMP_TRANSPORT_TCP_DOMAIN |
1324 | 0 | || pdu->tDomain == netsnmp_snmpTCPDomain |
1325 | 0 | #endif |
1326 | 0 | ) { |
1327 | 0 | if (!netsnmp_udp_getSecName(pdu->transport_data, |
1328 | 0 | pdu->transport_data_length, |
1329 | 0 | pdu_community, |
1330 | 0 | pdu->community_len, &sn, |
1331 | 0 | &contextName)) { |
1332 | | /* |
1333 | | * There are no com2sec entries. |
1334 | | */ |
1335 | 0 | sn = NULL; |
1336 | 0 | } |
1337 | | /* force the community -> context name mapping here */ |
1338 | 0 | SNMP_FREE(pdu->contextName); |
1339 | 0 | pdu->contextName = strdup(contextName); |
1340 | 0 | pdu->contextNameLen = strlen(contextName); |
1341 | 0 | #endif |
1342 | 0 | #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN |
1343 | 0 | } else if (pdu->tDomain == netsnmp_UDPIPv6Domain |
1344 | 0 | #ifdef NETSNMP_TRANSPORT_TCPIPV6_DOMAIN |
1345 | 0 | || pdu->tDomain == netsnmp_TCPIPv6Domain |
1346 | 0 | #endif |
1347 | 0 | ) { |
1348 | 0 | if (!netsnmp_udp6_getSecName(pdu->transport_data, |
1349 | 0 | pdu->transport_data_length, |
1350 | 0 | pdu_community, |
1351 | 0 | pdu->community_len, &sn, |
1352 | 0 | &contextName)) { |
1353 | | /* |
1354 | | * There are no com2sec entries. |
1355 | | */ |
1356 | 0 | sn = NULL; |
1357 | 0 | } |
1358 | | /* force the community -> context name mapping here */ |
1359 | 0 | SNMP_FREE(pdu->contextName); |
1360 | 0 | pdu->contextName = strdup(contextName); |
1361 | 0 | pdu->contextNameLen = strlen(contextName); |
1362 | 0 | #endif |
1363 | 0 | #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN |
1364 | 0 | } else if (pdu->tDomain == netsnmp_UnixDomain){ |
1365 | 0 | if (!netsnmp_unix_getSecName(pdu->transport_data, |
1366 | 0 | pdu->transport_data_length, |
1367 | 0 | pdu_community, |
1368 | 0 | pdu->community_len, &sn, |
1369 | 0 | &contextName)) { |
1370 | 0 | sn = NULL; |
1371 | 0 | } |
1372 | | /* force the community -> context name mapping here */ |
1373 | 0 | SNMP_FREE(pdu->contextName); |
1374 | 0 | pdu->contextName = strdup(contextName); |
1375 | 0 | pdu->contextNameLen = strlen(contextName); |
1376 | 0 | #endif |
1377 | 0 | } else { |
1378 | | /* |
1379 | | * Map other <community, transport-address> pairs to security names |
1380 | | * here. For now just let non-IPv4 transport always succeed. |
1381 | | * |
1382 | | * WHAAAATTTT. No, we don't let non-IPv4 transports |
1383 | | * succeed! You must fix this to make it usable, sorry. |
1384 | | * From a security standpoint this is insane. -- Wes |
1385 | | */ |
1386 | | /** @todo alternate com2sec mappings for non v4 transports. |
1387 | | Should be implemented via registration */ |
1388 | 0 | sn = NULL; |
1389 | 0 | } |
1390 | |
|
1391 | 0 | } else |
1392 | 0 | #endif /* !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) */ |
1393 | 0 | if (find_sec_mod(pdu->securityModel)) { |
1394 | | /* |
1395 | | * any legal defined v3 security model |
1396 | | */ |
1397 | 0 | DEBUGMSG(("mibII/vacm_vars", |
1398 | 0 | "vacm_in_view: ver=%ld, model=%d, secName=%s\n", |
1399 | 0 | pdu->version, pdu->securityModel, pdu->securityName)); |
1400 | 0 | sn = pdu->securityName; |
1401 | 0 | } else { |
1402 | 0 | sn = NULL; |
1403 | 0 | } |
1404 | |
|
1405 | 0 | if (sn == NULL) { |
1406 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
1407 | 0 | snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYNAMES); |
1408 | 0 | #endif |
1409 | 0 | DEBUGMSGTL(("mibII/vacm_vars", |
1410 | 0 | "vacm_in_view: No security name found\n")); |
1411 | 0 | return VACM_NOSECNAME; |
1412 | 0 | } |
1413 | | |
1414 | 0 | if (pdu->contextNameLen > CONTEXTNAMEINDEXLEN) { |
1415 | 0 | DEBUGMSGTL(("mibII/vacm_vars", |
1416 | 0 | "vacm_in_view: bad ctxt length %d\n", |
1417 | 0 | (int)pdu->contextNameLen)); |
1418 | 0 | return VACM_NOSUCHCONTEXT; |
1419 | 0 | } |
1420 | | /* |
1421 | | * NULL termination of the pdu field is ugly here. Do in PDU parsing? |
1422 | | */ |
1423 | 0 | if (pdu->contextName) |
1424 | 0 | memcpy(contextNameIndex, pdu->contextName, pdu->contextNameLen); |
1425 | 0 | else |
1426 | 0 | contextNameIndex[0] = '\0'; |
1427 | |
|
1428 | 0 | contextNameIndex[pdu->contextNameLen] = '\0'; |
1429 | 0 | if (!(flags & VACM_CHECK_VIEW_CONTENTS_DNE_CONTEXT_OK) && |
1430 | 0 | !netsnmp_subtree_find_first(contextNameIndex)) { |
1431 | | /* |
1432 | | * rfc 3415 section 3.2, step 1 |
1433 | | * no such context here; return no such context error |
1434 | | */ |
1435 | 0 | DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: no such ctxt \"%s\"\n", |
1436 | 0 | contextNameIndex)); |
1437 | 0 | return VACM_NOSUCHCONTEXT; |
1438 | 0 | } |
1439 | | |
1440 | 0 | DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: sn=%s", sn)); |
1441 | |
|
1442 | 0 | gp = vacm_getGroupEntry(pdu->securityModel, sn); |
1443 | 0 | if (gp == NULL) { |
1444 | 0 | DEBUGMSG(("mibII/vacm_vars", "\n")); |
1445 | 0 | return VACM_NOGROUP; |
1446 | 0 | } |
1447 | 0 | DEBUGMSG(("mibII/vacm_vars", ", gn=%s", gp->groupName)); |
1448 | |
|
1449 | 0 | ap = vacm_getAccessEntry(gp->groupName, contextNameIndex, |
1450 | 0 | pdu->securityModel, pdu->securityLevel); |
1451 | 0 | if (ap == NULL) { |
1452 | 0 | DEBUGMSG(("mibII/vacm_vars", "\n")); |
1453 | 0 | return VACM_NOACCESS; |
1454 | 0 | } |
1455 | | |
1456 | 0 | if (name == NULL) { /* only check the setup of the vacm for the request */ |
1457 | 0 | DEBUGMSG(("mibII/vacm_vars", ", Done checking setup\n")); |
1458 | 0 | return VACM_SUCCESS; |
1459 | 0 | } |
1460 | | |
1461 | 0 | if (viewtype < 0 || viewtype >= VACM_MAX_VIEWS) { |
1462 | 0 | DEBUGMSG(("mibII/vacm_vars", " illegal view type\n")); |
1463 | 0 | return VACM_NOACCESS; |
1464 | 0 | } |
1465 | 0 | vn = ap->views[viewtype]; |
1466 | 0 | DEBUGMSG(("mibII/vacm_vars", ", vn=%s", vn)); |
1467 | |
|
1468 | 0 | if (check_subtree) { |
1469 | 0 | DEBUGMSG(("mibII/vacm_vars", "\n")); |
1470 | 0 | return vacm_checkSubtree(vn, name, namelen); |
1471 | 0 | } |
1472 | | |
1473 | 0 | vp = vacm_getViewEntry(vn, name, namelen, VACM_MODE_FIND); |
1474 | |
|
1475 | 0 | if (vp == NULL) { |
1476 | 0 | DEBUGMSG(("mibII/vacm_vars", "\n")); |
1477 | 0 | return VACM_NOVIEW; |
1478 | 0 | } |
1479 | 0 | DEBUGMSG(("mibII/vacm_vars", ", vt=%d\n", vp->viewType)); |
1480 | |
|
1481 | 0 | if (vp->viewType == SNMP_VIEW_EXCLUDED) { |
1482 | 0 | #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) |
1483 | | #if defined(NETSNMP_DISABLE_SNMPV1) |
1484 | | if (pdu->version == SNMP_VERSION_2c) |
1485 | | #else |
1486 | | #if defined(NETSNMP_DISABLE_SNMPV2C) |
1487 | | if (pdu->version == SNMP_VERSION_1) |
1488 | | #else |
1489 | 0 | if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) |
1490 | 0 | #endif |
1491 | 0 | #endif |
1492 | 0 | { |
1493 | 0 | snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYUSES); |
1494 | 0 | } |
1495 | 0 | #endif |
1496 | 0 | return VACM_NOTINVIEW; |
1497 | 0 | } |
1498 | | |
1499 | 0 | return VACM_SUCCESS; |
1500 | |
|
1501 | 0 | } /* end vacm_in_view() */ |
1502 | | |
1503 | | |