KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > mo > snmp > VacmMIB


1 /*_############################################################################
2   _##
3   _## SNMP4J-Agent - VacmMIB.java
4   _##
5   _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
6   _##
7   _## Licensed under the Apache License, Version 2.0 (the "License");
8   _## you may not use this file except in compliance with the License.
9   _## You may obtain a copy of the License at
10   _##
11   _## http://www.apache.org/licenses/LICENSE-2.0
12   _##
13   _## Unless required by applicable law or agreed to in writing, software
14   _## distributed under the License is distributed on an "AS IS" BASIS,
15   _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   _## See the License for the specific language governing permissions and
17   _## limitations under the License.
18   _##
19   _##########################################################################*/

20
21
22 package org.snmp4j.agent.mo.snmp;
23
24 import java.util.*;
25
26 import org.snmp4j.log.*;
27 import org.snmp4j.agent.*;
28 import org.snmp4j.agent.mo.*;
29 import org.snmp4j.agent.mo.util.*;
30 import org.snmp4j.agent.security.*;
31 import org.snmp4j.security.*;
32 import org.snmp4j.smi.*;
33
34 /**
35  * This concrete implementation of the SNMP-VIEW-BASED-ACM-MIB (RFC 3415).
36  * The configuration of the view access model can be changed programatically
37  * (see {@link MutableVACM}) or via SNMP but an initial configuration must be
38  * created programatically in order to allow any access to the agent via SNMP.
39  *
40  * @author Frank Fock
41  * @version 1.0
42  */

43 public class VacmMIB implements MOGroup, MutableVACM {
44
45   private static final LogAdapter logger = LogFactory.getLogger(VacmMIB.class);
46
47   private static final OID vacmContextEntryOID =
48       new OID(new int[] {1,3,6,1,6,3,16,1,1,1});
49
50   private static final int colVacmGroupName = 3;
51   private static final int colVacmSecurityToGroupStorageType = 4;
52   private static final int colVacmSecurityToGroupRowStatus = 5;
53
54   private static final int idxVacmGroupName = 0;
55   private static final int idxVacmSecurityToGroupStorageType = 1;
56   private static final int idxVacmSecurityToGroupRowStatus = 2;
57
58   private static final OID vacmSecurityToGroupEntryOID =
59       new OID(new int[] {1,3,6,1,6,3,16,1,2,1});
60
61   private static final int colVacmAccessContextMatch = 4;
62   private static final int colVacmAccessReadViewName = 5;
63   private static final int colVacmAccessWriteViewName = 6;
64   private static final int colVacmAccessNotifyViewName = 7;
65   private static final int colVacmAccessStorageType = 8;
66   private static final int colVacmAccessRowStatus = 9;
67
68 // private static final int idxVacmAccessGroupName = 0;
69
private static final int idxVacmAccessContextPrefix = 1;
70   private static final int idxVacmAccessSecurityModel = 2;
71   private static final int idxVacmAccessSecurityLevel = 3;
72   private static final int idxVacmAccessContextMatch = 0;
73   private static final int idxVacmAccessReadViewName = 1;
74   private static final int idxVacmAccessWriteViewName = 2;
75   private static final int idxVacmAccessNotifyViewName = 3;
76   private static final int idxVacmAccessStorageType = 4;
77   private static final int idxVacmAccessRowStatus = 5;
78
79   private static final OID vacmAccessEntryOID =
80       new OID(new int[] {1,3,6,1,6,3,16,1,4,1});
81
82   public static final int vacmExactMatch = MutableVACM.VACM_MATCH_EXACT;
83   public static final int vacmPrefixMatch = MutableVACM.VACM_MATCH_PREFIX;
84
85
86   private static final OID vacmViewSpinLockOID =
87       new OID(new int[] {1,3,6,1,6,3,16,1,5,1,0});
88
89   private static final int colVacmViewTreeFamilyMask = 3;
90   private static final int colVacmViewTreeFamilyType = 4;
91   private static final int colVacmViewTreeFamilyStorageType = 5;
92   private static final int colVacmViewTreeFamilyRowStatus = 6;
93
94 // private static final int idxVacmViewTreeViewName = 0;
95
private static final int idxVacmViewTreeSubtree = 1;
96
97   private static final int idxVacmViewTreeFamilyMask = 0;
98   private static final int idxVacmViewTreeFamilyType = 1;
99   private static final int idxVacmViewTreeFamilyStorageType = 2;
100   private static final int idxVacmViewTreeFamilyRowStatus = 3;
101
102   private static final OID vacmViewTreeFamilyEntryOID =
103       new OID(new int[] {1,3,6,1,6,3,16,1,5,2,1});
104
105   public static final int vacmViewIncluded = MutableVACM.VACM_VIEW_INCLUDED;
106   public static final int vacmViewExcluded = MutableVACM.VACM_VIEW_EXCLUDED;
107
108   private static final int[] vacmViewTreeFamilyTypeValues = {
109       vacmViewIncluded, vacmViewExcluded
110   };
111
112   private static MOTableSubIndex[] vacmViewTreeFamilyIndexes =
113       new MOTableSubIndex[] {
114       new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 1, 32),
115       new MOTableSubIndex(SMIConstants.SYNTAX_OBJECT_IDENTIFIER, 0, 96)
116   };
117
118   private static MOTableIndex vacmViewTreeFamilyIndex =
119       new MOTableIndex(vacmViewTreeFamilyIndexes);
120
121   private static MOTableSubIndex[] vacmAccessIndexes = new MOTableSubIndex[] {
122       new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 1, 32),
123       new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 0, 32),
124       new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER, 1, 1),
125       new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER, 1, 1)
126   };
127
128   private static MOTableIndex vacmAccessIndex =
129       new MOTableIndex(vacmAccessIndexes) {
130     public boolean isValidIndex(OID index) {
131       boolean ok = super.isValidIndex(index);
132       if (ok) {
133         SecurityModels secModels = SecurityModels.getInstance();
134         Integer32 secModel = new Integer32(index.get(index.size()-2));
135         if ((secModel.getValue() != SecurityModel.SECURITY_MODEL_ANY) &&
136             (secModels.getSecurityModel(secModel) == null)) {
137           return false;
138         }
139         int secLevel = index.get(index.size()-1);
140         if ((secLevel < 1) || (secLevel > 3)) {
141           return false;
142         }
143       }
144       return ok;
145     }
146   };
147
148   private MOServer server;
149
150   private DefaultMOTable vacmContextTable;
151
152   private DefaultMOTable vacmSecurityToGroupTable;
153   private DefaultMOMutableTableModel vacmSecurityToGroupTableModel;
154
155   private DefaultMOTable vacmAccessTable;
156   private DefaultMOMutableTableModel vacmAccessTableModel;
157
158   private TestAndIncr vacmViewSpinLock;
159
160   private DefaultMOTable vacmViewTreeFamilyTable;
161   private DefaultMOMutableTableModel vacmViewTreeFamilyTableModel;
162
163
164   public VacmMIB(MOServer server) {
165     this.server = server;
166     createVacmContextTable();
167     createVacmSecuritToGroupTable();
168     createVacmAccessTable();
169     createVacmViewTreeFamilyTable();
170     vacmViewSpinLock = new TestAndIncr(vacmViewSpinLockOID);
171   }
172
173   public void registerMOs(MOServer server, OctetString context) throws
174       DuplicateRegistrationException {
175     server.register(vacmContextTable, context);
176     server.register(vacmSecurityToGroupTable, context);
177     server.register(vacmAccessTable, context);
178     server.register(vacmViewSpinLock, context);
179     server.register(vacmViewTreeFamilyTable, context);
180   }
181
182   private void createVacmContextTable() {
183     MOTableSubIndex[] vacmContextTableIndexes = new MOTableSubIndex[] {
184         new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 0, 32) };
185     MOTableIndex vacmContextTableIndex =
186         new MOTableIndex(vacmContextTableIndexes);
187     MOColumn[] vacmContextColumns = new MOColumn[] {
188         new MOColumn(1, SMIConstants.SYNTAX_OCTET_STRING,
189                      MOAccessImpl.ACCESS_READ_ONLY) };
190
191     this.vacmContextTable =
192         new DefaultMOTable(vacmContextEntryOID, vacmContextTableIndex,
193                            vacmContextColumns);
194     this.vacmContextTable.setVolatile(true);
195     this.vacmContextTable.setModel(new VacmContextTableModel());
196   }
197
198   private void createVacmSecuritToGroupTable() {
199     MOTableSubIndex[] vacmSecurityToGroupIndexes = new MOTableSubIndex[] {
200         new MOTableSubIndex(SMIConstants.SYNTAX_INTEGER, 1, 1),
201         new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 1, 32) };
202
203     MOTableIndex vacmSecurityToGroupIndex =
204         new MOTableIndex(vacmSecurityToGroupIndexes) {
205       public boolean isValidIndex(OID index) {
206         boolean ok = super.isValidIndex(index);
207         if (ok) {
208           SecurityModels secModels = SecurityModels.getInstance();
209           if (secModels.getSecurityModel(new Integer32(index.get(0))) == null) {
210             return false;
211           }
212         }
213         return ok;
214       }
215     };
216
217     MOColumn[] vacmSecurityToGroupColumns = new MOColumn[] {
218         new SnmpAdminString(colVacmGroupName,
219                             MOAccessImpl.ACCESS_READ_CREATE, null, true, 1, 32),
220         new StorageType(colVacmSecurityToGroupStorageType,
221                         MOAccessImpl.ACCESS_READ_CREATE,
222                         new Integer32(StorageType.nonVolatile), true),
223         new RowStatus(colVacmSecurityToGroupRowStatus)
224     };
225
226     this.vacmSecurityToGroupTable =
227         new DefaultMOTable(vacmSecurityToGroupEntryOID,
228                            vacmSecurityToGroupIndex,
229                            vacmSecurityToGroupColumns);
230     vacmSecurityToGroupTableModel = new DefaultMOMutableTableModel();
231     vacmSecurityToGroupTableModel.setRowFactory(new DefaultMOMutableRow2PCFactory());
232     this.vacmSecurityToGroupTable.setModel(vacmSecurityToGroupTableModel);
233   }
234
235   private void createVacmAccessTable() {
236     MOColumn[] vacmAccessColumns = new MOColumn[] {
237         new Enumerated(colVacmAccessContextMatch,
238                         MOAccessImpl.ACCESS_READ_CREATE,
239                         new Integer32(vacmExactMatch), true,
240                         new int[] { vacmExactMatch, vacmPrefixMatch }),
241         new SnmpAdminString(colVacmAccessReadViewName,
242                             MOAccessImpl.ACCESS_READ_CREATE,
243                             new OctetString(), true, 0, 32),
244         new SnmpAdminString(colVacmAccessWriteViewName,
245                             MOAccessImpl.ACCESS_READ_CREATE,
246                             new OctetString(), true, 0, 32),
247         new SnmpAdminString(colVacmAccessNotifyViewName,
248                             MOAccessImpl.ACCESS_READ_CREATE,
249                             new OctetString(), true, 0, 32),
250         new StorageType(colVacmAccessStorageType,
251                         MOAccessImpl.ACCESS_READ_CREATE,
252                         new Integer32(StorageType.nonVolatile), true),
253         new RowStatus(colVacmAccessRowStatus)
254     };
255
256     vacmAccessTable = new DefaultMOTable(vacmAccessEntryOID,
257                                          vacmAccessIndex,
258                                          vacmAccessColumns);
259     vacmAccessTableModel = new DefaultMOMutableTableModel();
260     vacmAccessTableModel.setRowFactory(new DefaultMOMutableRow2PCFactory());
261     vacmAccessTable.setModel(vacmAccessTableModel);
262   }
263
264   private void createVacmViewTreeFamilyTable() {
265     MOColumn[] vacmViewTreeFamilyColumns = new MOColumn[] {
266         new SnmpAdminString(colVacmViewTreeFamilyMask,
267                             MOAccessImpl.ACCESS_READ_CREATE,
268                             new OctetString(), true, 0, 16),
269         new Enumerated(colVacmViewTreeFamilyType,
270                         MOAccessImpl.ACCESS_READ_CREATE,
271                         new Integer32(vacmViewIncluded), true,
272                         vacmViewTreeFamilyTypeValues),
273         new StorageType(colVacmViewTreeFamilyStorageType,
274                         MOAccessImpl.ACCESS_READ_CREATE,
275                         new Integer32(StorageType.nonVolatile), true),
276         new RowStatus(colVacmViewTreeFamilyRowStatus)
277     };
278
279     vacmViewTreeFamilyTable = new DefaultMOTable(vacmViewTreeFamilyEntryOID,
280                                                  vacmViewTreeFamilyIndex,
281                                                  vacmViewTreeFamilyColumns);
282     vacmViewTreeFamilyTableModel = new DefaultMOMutableTableModel();
283     vacmViewTreeFamilyTableModel.setRowFactory(new DefaultMOMutableRow2PCFactory());
284     vacmViewTreeFamilyTable.setModel(vacmViewTreeFamilyTableModel);
285   }
286
287   public void unregisterMOs(MOServer server, OctetString context) {
288     server.unregister(this.vacmContextTable, context);
289     server.unregister(this.vacmSecurityToGroupTable, context);
290     server.unregister(this.vacmAccessTable, context);
291     server.unregister(vacmViewSpinLock, context);
292     server.unregister(vacmViewTreeFamilyTable, context);
293   }
294
295   public int isAccessAllowed(OctetString context, OctetString securityName,
296                              int securityModel, int securityLevel, int viewType,
297                              OID oid) {
298     if (logger.isDebugEnabled()) {
299       logger.debug("VACM access requested for context="+context+
300                    ", securityName="+securityName+
301                    ", securityModel="+securityModel+
302                    ", securityLevel="+securityLevel+
303                    ", viewType="+viewType+
304                    ", OID="+oid);
305     }
306     if (!server.isContextSupported(context)) {
307       if (logger.isDebugEnabled()) {
308         logger.debug("Context '"+context+"' ist not supported");
309       }
310       return VACM.VACM_NO_SUCH_CONTEXT;
311     }
312     OctetString groupName = getGroupName(securityName, securityModel);
313     if (groupName == null) {
314       if (logger.isDebugEnabled()) {
315         logger.debug("No group name for securityName="+securityName+
316                      " and securityModel="+securityModel);
317       }
318       return VACM.VACM_NO_GROUP_NAME;
319     }
320     OctetString viewName = getViewNameByGroup(context, securityModel,
321                                               securityLevel, viewType,
322                                               groupName);
323     if (viewName == null) {
324       return VACM.VACM_NO_ACCESS_ENTRY;
325     }
326     if (viewName.length() == 0) {
327       return VACM.VACM_NO_SUCH_VIEW;
328     }
329     return isAccessAllowed(viewName, oid);
330   }
331
332   public OctetString getViewName(OctetString context,
333                                  OctetString securityName,
334                                  int securityModel,
335                                  int securityLevel,
336                                  int viewType) {
337     OctetString groupName = getGroupName(securityName, securityModel);
338     if (groupName == null) {
339       return null;
340     }
341     return getViewNameByGroup(context, securityModel, securityLevel,
342                               viewType, groupName);
343   }
344
345   private OctetString getViewNameByGroup(OctetString context, int securityModel,
346                                          int securityLevel, int viewType,
347                                          OctetString groupName) {
348     List accessEntries = getAccessEntries(groupName);
349
350     if (logger.isDebugEnabled()) {
351       logger.debug("Got views "+accessEntries+
352                    " for group name '"+groupName+"'");
353     }
354
355     MOTableRow possibleMatch = null;
356     boolean foundExactContextMatch = false;
357     boolean foundMatchedSecModel = false;
358     int foundContextPrefixLength = 0;
359     int foundSecLevel = 0;
360
361     for (Iterator it = accessEntries.iterator(); it.hasNext(); ) {
362       MOTableRow row = (MOTableRow) it.next();
363       if (((Integer32)row.getValue(idxVacmAccessRowStatus)).getValue() !=
364           RowStatus.active) {
365         continue;
366       }
367       Variable[] indexValues = vacmAccessIndex.getIndexValues(row.getIndex());
368       OctetString rowContext =
369           (OctetString) indexValues[idxVacmAccessContextPrefix];
370       int rowSecurityModel =
371           ((Integer32)indexValues[idxVacmAccessSecurityModel]).getValue();
372       int rowSecurityLevel =
373           ((Integer32)indexValues[idxVacmAccessSecurityLevel]).getValue();
374       int rowContextMatch =
375           ((Integer32)row.getValue(idxVacmAccessContextMatch)).getValue();
376       boolean exactContextMatch = rowContext.equals(context);
377       boolean prefixMatch = (!exactContextMatch) &&
378           ((rowContextMatch == vacmPrefixMatch) &&
379            (context.startsWith(rowContext)));
380       boolean matchSecModel = (rowSecurityModel == securityModel);
381       boolean matchSecLevel = (rowSecurityLevel <= securityLevel);
382       if ((exactContextMatch || prefixMatch) &&
383           ((matchSecModel) ||
384            (rowSecurityModel == SecurityModel.SECURITY_MODEL_ANY)) &&
385           matchSecLevel) {
386         // check better match
387
if ((possibleMatch == null) ||
388             (((!foundMatchedSecModel) && (matchSecModel)) ||
389              (((!foundMatchedSecModel) || (matchSecModel)) &&
390               ((!foundExactContextMatch) && (exactContextMatch)) ||
391               ((((!foundExactContextMatch) || (exactContextMatch)) &&
392                 (foundContextPrefixLength < rowContext.length())) ||
393                ((foundContextPrefixLength == rowContext.length()) &&
394                 (foundSecLevel < rowSecurityLevel)))))) {
395           possibleMatch = row;
396           foundExactContextMatch = exactContextMatch;
397           if (prefixMatch) {
398             foundContextPrefixLength = rowContext.length();
399           }
400           foundMatchedSecModel = matchSecModel;
401           foundSecLevel = securityLevel;
402         }
403       }
404     }
405     if (possibleMatch != null) {
406       OctetString viewName = null;
407       switch (viewType) {
408         case VACM.VIEW_READ: {
409           viewName =
410               (OctetString)possibleMatch.getValue(idxVacmAccessReadViewName);
411           break;
412         }
413         case VACM.VIEW_WRITE: {
414           viewName = (OctetString)
415               possibleMatch.getValue(idxVacmAccessWriteViewName);
416           break;
417         }
418         case VACM.VIEW_NOTIFY: {
419           viewName = (OctetString)
420               possibleMatch.getValue(idxVacmAccessNotifyViewName);
421           break;
422         }
423       }
424       if (logger.isDebugEnabled()) {
425         logger.debug("Matching view found for group name '"+groupName+"' is '"+
426                      viewName+"'");
427       }
428       return viewName;
429     }
430     return null;
431   }
432
433   private OctetString getGroupName(OctetString securityName,
434                                    int securityModel) {
435     OID index = new OID();
436     index.append(securityModel);
437     index.append(securityName.toSubIndex(false));
438     MOTableRow row = vacmSecurityToGroupTableModel.getRow(index);
439     if (row != null) {
440       OctetString groupName = (OctetString) row.getValue(idxVacmGroupName);
441       if (logger.isDebugEnabled()) {
442         logger.debug("Found group name '"+groupName+"' for secName '"+
443                      securityName+" and secModel "+securityModel);
444       }
445       return groupName;
446     }
447     return null;
448   }
449
450   public int isAccessAllowed(OctetString viewName, OID oid) {
451     List views = getViews(viewName);
452     if (views.size() == 0) {
453       if (logger.isDebugEnabled()) {
454         logger.debug("No view tree family entry for view '" + viewName + "'");
455       }
456       return VACM.VACM_NO_SUCH_VIEW;
457     }
458     // iterate from back to forth because the views list must be ordered by
459
// subtree length (view name is the same for all entries) which is the
460
// criteria to find the appropritate view access entry.
461
for (int v=views.size()-1; v >= 0; v--) {
462       MOTableRow row = (MOTableRow) views.get(v);
463       if (((Integer32)row.getValue(idxVacmViewTreeFamilyRowStatus)).getValue()!=
464           RowStatus.active) {
465         // only active rows are relevant
466
continue;
467       }
468       OID index = row.getIndex();
469       Variable[] indexValues = vacmViewTreeFamilyIndex.getIndexValues(index);
470       OID subtree = (OID) indexValues[idxVacmViewTreeSubtree];
471       if (oid.size() < subtree.size()) {
472         // no match
473
continue;
474       }
475       OctetString mask = (OctetString) row.getValue(idxVacmViewTreeFamilyMask);
476       boolean match = true;
477       for (int i=0; i<subtree.size(); i++) {
478         if ((subtree.get(i) != oid.get(i)) && isBitSet(i, mask)) {
479           match = false;
480           break;
481         }
482       }
483       if (match) {
484         // we found the matching entry
485
if (((Integer32)row.getValue(idxVacmViewTreeFamilyType)).getValue() ==
486             vacmViewIncluded) {
487           if (logger.isDebugEnabled()) {
488             logger.debug("Access allowed for view '"+viewName+"' by subtree "+
489                          subtree+" for OID "+oid);
490           }
491           return VACM.VACM_OK;
492         }
493         else {
494           // excluded
495
if (logger.isDebugEnabled()) {
496             logger.debug("Access denied for view '"+viewName+"' by subtree "+
497                          subtree+" for OID "+oid);
498           }
499           return VACM.VACM_NOT_IN_VIEW;
500         }
501       }
502     }
503     return VACM.VACM_NOT_IN_VIEW;
504   }
505
506   /**
507    * Adds a security model and name to group name mapping to this VACM. Any
508    * already existing mapping for the security name and model will be silently
509    * replaced.
510    * @param securityModel
511    * the security model.
512    * @param securityName
513    * the security name.
514    * @param groupName
515    * the group name.
516    * @param storageType
517    * the storage type for the new entry.
518    */

519   public void addGroup(int securityModel, OctetString securityName,
520                        OctetString groupName, int storageType) {
521     OID index = createGroupIndex(securityModel, securityName);
522     Variable[] values = new Variable[vacmSecurityToGroupTable.getColumnCount()];
523     values[idxVacmGroupName] = groupName;
524     values[idxVacmSecurityToGroupStorageType] = new Integer32(storageType);
525     values[idxVacmSecurityToGroupRowStatus] = new Integer32(RowStatus.active);
526     MOTableRow row = vacmSecurityToGroupTable.createRow(index, values);
527     vacmSecurityToGroupTableModel.addRow(row);
528   }
529
530   private static OID createGroupIndex(int securityModel,
531                                       OctetString securityName) {
532     OID index = new OID();
533     index.append(securityModel);
534     index.append(securityName.toSubIndex(false));
535     return index;
536   }
537
538   /**
539    * Removes a security model and name to group name mapping from this VACM.
540    * @param securityModel
541    * the security model.
542    * @param securityName
543    * the security name.
544    * @return
545    * <code>true</code> when the entry has been removed or <code>false</code>
546    * if such a mapping could not be found.
547    */

548   public boolean removeGroup(int securityModel, OctetString securityName) {
549     OID index = createGroupIndex(securityModel, securityName);
550     return (vacmSecurityToGroupTableModel.removeRow(index) != null);
551   }
552
553   /**
554    * Adds an access entry to this VACM and thus adds access rights for a group.
555    * @param groupName
556    * the group for which access rights are to be added.
557    * @param contextPrefix
558    * the context or context prefix.
559    * @param securityModel
560    * the security model
561    * @param securityLevel
562    * the security level
563    * @param match
564    * indicates whether exact context match ({@link #vacmExactMatch})
565    * or prefix context match ({@link #vacmPrefixMatch}) should
566    * be used by the new entry.
567    * @param readView
568    * the view name for read access (use a zero length OctetString to disable
569    * access).
570    * @param writeView
571    * the view name for write access (use a zero length OctetString to disable
572    * access).
573    * @param notifyView
574    * the view name for notify access (use a zero length OctetString to
575    * disable access).
576    * @param storageType
577    * the {@link StorageType} for this access entry.
578    */

579   public void addAccess(OctetString groupName, OctetString contextPrefix,
580                         int securityModel, int securityLevel,
581                         int match,
582                         OctetString readView, OctetString writeView,
583                         OctetString notifyView, int storageType) {
584     OID index = createAccessIndex(groupName, contextPrefix, securityModel,
585                                   securityLevel);
586     Variable[] values = new Variable[vacmAccessTable.getColumnCount()];
587     values[idxVacmAccessContextMatch] = new Integer32(match);
588     values[idxVacmAccessReadViewName] = readView;
589     values[idxVacmAccessWriteViewName] = writeView;
590     values[idxVacmAccessNotifyViewName] = notifyView;
591     values[idxVacmAccessStorageType] = new Integer32(storageType);
592     values[idxVacmAccessRowStatus] = new Integer32(RowStatus.active);
593     vacmAccessTableModel.addRow(vacmAccessTableModel.createRow(index, values));
594   }
595
596   /**
597    * Removes an access entry from this VACM.
598    * @param groupName
599    * the group for which access rights are to be added.
600    * @param contextPrefix
601    * the context or context prefix.
602    * @param securityModel
603    * the security model
604    * @param securityLevel
605    * the security level
606    * @return
607    * <code>true</code> when the entry has been removed or <code>false</code>
608    * if no such entry could be found.
609    */

610   public boolean removeAccess(OctetString groupName, OctetString contextPrefix,
611                               int securityModel, int securityLevel) {
612     OID index = createAccessIndex(groupName, contextPrefix, securityModel,
613                                   securityLevel);
614     return (vacmAccessTableModel.removeRow(index) != null);
615   }
616
617   private static OID createAccessIndex(OctetString groupName,
618                                        OctetString contextPrefix,
619                                        int securityModel, int securityLevel) {
620     OID index = groupName.toSubIndex(false);
621     index.append(contextPrefix.toSubIndex(false));
622     index.append(securityModel);
623     index.append(securityLevel);
624     return index;
625   }
626
627   /**
628    * Adds a new view to this VACM. An already existing entry with the same
629    * view name and subtree OID will be replaced silently.
630    * @param viewName
631    * the view name.
632    * @param subtree
633    * the subtree OID.
634    * @param mask
635    * the bit mask which, in combination with <code>subtree</code>,
636    * defines a family of view subtrees.
637    * @param type
638    * indicates whether the view defined by <code>subtree</code> and
639    * <code>mask</code> is included ({@link #vacmViewIncluded}) or excluded
640    * (@link #vacmViewExcluded}) from the MIB view.
641    * @param storageType
642    * the {@link StorageType} for this access entry.
643    */

644   public void addViewTreeFamily(OctetString viewName, OID subtree,
645                                 OctetString mask, int type, int storageType) {
646     OID index = createViewIndex(viewName, subtree);
647     Variable[] values = new Variable[vacmViewTreeFamilyTable.getColumnCount()];
648     values[idxVacmViewTreeFamilyMask] = mask;
649     values[idxVacmViewTreeFamilyType] = new Integer32(type);
650     values[idxVacmViewTreeFamilyStorageType] = new Integer32(storageType);
651     values[idxVacmViewTreeFamilyRowStatus] = new Integer32(RowStatus.active);
652     MOTableRow row = vacmViewTreeFamilyTableModel.createRow(index, values);
653     vacmViewTreeFamilyTableModel.addRow(row);
654   }
655
656   /**
657    * Removes a view tree family from this VACM.
658    * @param viewName
659    * the view name.
660    * @param subtree
661    * the subtree OID.
662    * @return
663    * <code>true</code> when the entry has been removed or <code>false</code>
664    * if no such entry could be found.
665    */

666   public boolean removeViewTreeFamily(OctetString viewName, OID subtree) {
667     OID index = createViewIndex(viewName, subtree);
668     return (vacmViewTreeFamilyTableModel.removeRow(index) != null);
669   }
670
671   private static OID createViewIndex(OctetString viewName, OID subtree) {
672     OID index = viewName.toSubIndex(false);
673     index.append(subtree.toSubIndex(false));
674     return index;
675   }
676
677   /**
678    * Checks whether bit n of the supplied OctetString is set or not.
679    * @param n
680    * denotes the bit to check starting from zero.
681    * @param os OctetString
682    * @return boolean
683    */

684   private static boolean isBitSet(final int n, final OctetString os) {
685     if (os.length() <= n/8) {
686       return true;
687     }
688     return (os.get(n/8) & (0x01 << (7 - (n % 8)))) > 0;
689   }
690
691   private List getAccessEntries(OctetString groupName) {
692     OctetString upperBound = new OctetString(groupName);
693     byte last = -1;
694     if (upperBound.length() > 0) {
695       last = upperBound.get(upperBound.length() - 1);
696     }
697     if (last == -1) {
698       upperBound.append((byte)0);
699     }
700     else {
701       upperBound.set(upperBound.length()-1, (byte)(last+1));
702     }
703     OID lowerOID = groupName.toSubIndex(false);
704     OID upperOID = upperBound.toSubIndex(false);
705     List views = vacmAccessTableModel.getRows(lowerOID, upperOID);
706     return views;
707   }
708
709   private List getViews(OctetString viewName) {
710     if (viewName.length() == 0) {
711       return Collections.EMPTY_LIST;
712     }
713     OctetString upperBound = new OctetString(viewName);
714     byte last = upperBound.get(upperBound.length()-1);
715     if (last == -1) {
716       upperBound.append((byte)0);
717     }
718     else {
719       upperBound.set(upperBound.length()-1, (byte)(last+1));
720     }
721     OID lowerOID = viewName.toSubIndex(false);
722     OID upperOID = upperBound.toSubIndex(false);
723     List views = vacmViewTreeFamilyTableModel.getRows(lowerOID, upperOID);
724     return views;
725   }
726
727   public static class VacmContextIterator implements Iterator {
728
729     private int index = 0;
730     private OctetString[] contexts;
731
732     VacmContextIterator(OctetString[] contexts, int offset) {
733       this.contexts = contexts;
734       this.index = offset;
735     }
736
737     public void remove() {
738       throw new UnsupportedOperationException JavaDoc();
739     }
740
741     public boolean hasNext() {
742       return (index < contexts.length);
743     }
744
745     public Object JavaDoc next() {
746       if (index < contexts.length) {
747         OctetString context = contexts[index++];
748         DefaultMOTableRow row =
749             new DefaultMOTableRow(context.toSubIndex(false),
750                                   new Variable[] { context });
751         return row;
752       }
753       throw new NoSuchElementException();
754     }
755
756   }
757
758   private static OctetString getContextFromIndex(OID index) {
759     if (index.size() > 0) {
760       return new OctetString(index.toByteArray(), 1, index.size() - 1);
761     }
762     return new OctetString();
763   }
764
765
766   class VacmContextTableModel implements MOTableModel {
767
768     public int getColumnCount() {
769       return 1;
770     }
771
772     public int getRowCount() {
773       return server.getContexts().length;
774     }
775
776     public boolean containsRow(OID index) {
777       return server.isContextSupported(getContextFromIndex(index));
778     }
779
780     public MOTableRow getRow(OID index) {
781       if (index == null) {
782         return null;
783       }
784       OctetString context = getContextFromIndex(index);
785       if (server.isContextSupported(context)) {
786         DefaultMOTableRow row =
787             new DefaultMOTableRow(index, new Variable[] { context });
788         return row;
789       }
790       return null;
791     }
792
793     public Iterator iterator() {
794       return tailIterator(new OID());
795     }
796
797     public Iterator tailIterator(OID lowerBound) {
798       OctetString[] contexts = server.getContexts();
799       if (contexts == null) {
800         return new VacmContextIterator(new OctetString[0], 0);
801       }
802       Arrays.sort(contexts, new LexicographicOctetStringComparator());
803       int offset = 0;
804       if (lowerBound != null) {
805         offset = Arrays.binarySearch(contexts, getContextFromIndex(lowerBound));
806       }
807       if (offset < 0) {
808         offset = -(offset+1);
809       }
810       return new VacmContextIterator(contexts, offset);
811     }
812
813     public OID lastIndex() {
814       OctetString[] contexts = server.getContexts();
815       if ((contexts == null) || (contexts.length == 0)) {
816         return null;
817       }
818       Arrays.sort(contexts, new LexicographicOctetStringComparator());
819       return contexts[contexts.length-1].toSubIndex(false);
820     }
821
822     public OID firstIndex() {
823       OctetString[] contexts = server.getContexts();
824       if ((contexts == null) || (contexts.length == 0)) {
825         return null;
826       }
827       Arrays.sort(contexts, new LexicographicOctetStringComparator());
828       return contexts[0].toSubIndex(false);
829     }
830
831     public MOTableRow firstRow() {
832       return getRow(firstIndex());
833     }
834
835     public MOTableRow lastRow() {
836       return getRow(lastIndex());
837     }
838   }
839
840 }
841
Popular Tags