If we have users that we want to assign different level of privileges (for example, we want to allow administrator to reset/reboot remote device while we want to prevent ordinary user from doing that (at the same time we want to allow every user to read status of the remote agent) it is not enough just to categorize users by giving them authentication and privacy passwords/keys.
This is where VACM comes into the picture.
VACM uses a MIB to specify which user can access which part of the agent MIB under specified conditions. Conditions include security level (for example certain part of the MIB can be accessed only using authenticated requests, the other only if request is both authenticated and encrypted, …), security model (for example we do not want to allow SNMPv1 or SNMPv2 managers to access v3 configuration tables), userName (for example “bob” can access all objects in the MIB, while “liz” can access only mib-2 subtree), viewType (for example user can be allowed to “read” but not “write” to certain object), and in which context the object exist.
VACM does not specify access rights for every single instance in the agent’s MIB. Rather it specifies them per subtree. Subtree is a set of all objects and object instances that have a common object identifier prefix to their names.
Here is the source code for this lesson (the parts that are the same as in previous lesson are omitted):
int main(int argc, char* argv)
. . .
. . .
BSNMPAgent snmpAgent(tm, &mh, &nv, &vacm);
. . .
BCLI cli( &mh );
. . .
VACM is implemented in BViewBasedAccessControl class. To enable VACM in our agent all we have to do is to create instance of BViewBasedAccessControl class, initialize its tables and pass to MIB handler. This is exactly what happens in the first three lines above.
Please note that vacm.Init() initialize tables from the non-volatile storage. If vacm object is created without nv parameter, Init will leave all tables empty, basically preventing access to any MIB variable!
In order to enable remote configuration of VAM tables, they are registered as group with MIB handler.
Let’s take a look at the prototype of the Query method specified in IMIBHandler interface:
tInt32 Query( tInt32 queryType,
const BSecurityParams& secParams,
const BString& ctxName,
When protocol agent is resolving the request, it calls Query method on the IMIBHandler derived object passed to the agent in constructor. Vbl specifies the list of variables requested.
The interesting parameters for this discussion are secParams and ctxName. In the previous lessons, where VACM object was not used, these two parameters were simply ignored.
Now, these two parameters along with the vbl are used by VACM subsystem to determine the access rights for requested variables. The first of these two parameters, secParams, is reference to BSecurityParams object that contains three security attributes: name, model and level. CtxName is name of the context.
VACM used in this multi-protocol agent is in fact the one defined for SNMP. This means that SNMP request packets inherently carry all the necessary VACM parameters.
In case of requests that come through the other “channels” this not true.
For that reason we have to “artificially” insert VACM parameters in queries originating from other protocol agents.
BCLI uses parameters specified in the following call:
When BCLI processes command that has to access MIB variable it passes VACM parameters along with the request in call through the IMIBHandler interface. These parameters are security model (SNMP_SECURITY_MODEL_SNMPv2c), security name (private), security level (eSecurityLevel_noAuthNoPriv), and context name (“”). This means that all CLI commands that retrieve/modify MIB variables will be given access based on the parameters specified.
The same applies to the HTTP agent. While not apparent from the source code, HTTP agent also gets assigned VACM parameters. This is done through the configuration file; section “Web VACM”
These parameters will be inserted into the Query call while SSI parser resolves requests specified in the shtml pages.
Now, we are ready to dive into the MIB instrumentation.
Please proceed to Lesson 8: Adding Scalar Object