mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
13.42.2011 e9558df199c35c488de80b8a2acd7d4149d46db1
Preparation work for OPENDJ-308: Implement access log filtering and configurable message format

Implement log filtering based on connection, user, request, and response criteria. Also performed minor refactoring of AddressMask class in order to avoid performing unnecessary reverse lookups during log filtering.


8 files modified
1169 ■■■■■ changed files
opends/resource/schema/02-config.ldif 72 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/AccessLogFilteringCriteriaConfiguration.xml 451 ●●●●● patch | view | raw | blame | history
opends/src/admin/messages/AccessLogFilteringCriteriaCfgDefn.properties 54 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/networkgroups/IPConnectionCriteria.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java 528 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java 8 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AddressMask.java 44 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java 3 ●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif
@@ -2676,6 +2676,74 @@
  NAME 'ds-cfg-log-record-type'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.32
  NAME 'ds-cfg-client-address-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.33
  NAME 'ds-cfg-client-address-not-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.34
  NAME 'ds-cfg-client-protocol-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.35
  NAME 'ds-cfg-client-port-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.36
  NAME 'ds-cfg-user-dn-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.37
  NAME 'ds-cfg-user-dn-not-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.38
  NAME 'ds-cfg-user-is-member-of'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.39
  NAME 'ds-cfg-user-is-not-member-of'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.40
  NAME 'ds-cfg-request-target-dn-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.41
  NAME 'ds-cfg-request-target-dn-not-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.42
  NAME 'ds-cfg-response-result-code-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.43
  NAME 'ds-cfg-response-result-code-not-equal-to'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.44
  NAME 'ds-cfg-response-etime-greater-than'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.45
  NAME 'ds-cfg-response-etime-less-than'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.46
  NAME 'ds-cfg-search-response-nentries-greater-than'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.47
  NAME 'ds-cfg-search-response-nentries-less-than'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.48
  NAME 'ds-cfg-search-response-is-indexed'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler'
  SUP top
@@ -4472,5 +4540,7 @@
  SUP top
  STRUCTURAL
  MUST ( cn )
  MAY ( ds-cfg-log-record-type )
  MAY ( ds-cfg-log-record-type $
        ds-cfg-base-dn $
        ds-cfg-scope )
  X-ORIGIN 'OpenDJ Directory Server' )
opends/src/admin/defn/org/opends/server/admin/std/AccessLogFilteringCriteriaConfiguration.xml
@@ -43,10 +43,13 @@
  </adm:profile>
  <adm:property name="log-record-type" multi-valued="true">
    <adm:synopsis>
      Filters log records based on their type.
    </adm:synopsis>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>All records</adm:synopsis>
        <adm:synopsis>
          The log record type will be ignored during filtering.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
@@ -95,4 +98,450 @@
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="client-address-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with connections which match at least one
      of the specified client host names or address masks.
    </adm:synopsis>
    <adm:description>
      Valid values include a host name, a fully qualified domain name, a
      domain name, an IP address, or a subnetwork with subnetwork mask.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on client address equality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:ip-address-mask />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-client-address-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="client-address-not-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with connections which do not match any
      of the specified client host names or address masks.
    </adm:synopsis>
    <adm:description>
      Valid values include a host name, a fully qualified domain name, a
      domain name, an IP address, or a subnetwork with subnetwork mask.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on client address inequality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:ip-address-mask />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-client-address-not-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="client-protocol-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with connections which match any
      of the specified protocols.
    </adm:synopsis>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on the protocol.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:enumeration>
        <adm:value name="ldap">
          <adm:synopsis>LDAP clients</adm:synopsis>
        </adm:value>
        <adm:value name="ldaps">
          <adm:synopsis>LDAPS clients</adm:synopsis>
        </adm:value>
        <adm:value name="jmx">
          <adm:synopsis>JMX clients</adm:synopsis>
        </adm:value>
      </adm:enumeration>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-client-protocol-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="client-port-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with connections to any of the specified
      listener port numbers.
    </adm:synopsis>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on the port.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer lower-limit="1" upper-limit="65535" />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-client-port-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="user-dn-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with users matching at least one of the
      specified DN patterns.
    </adm:synopsis>
    <adm:description>
      Valid DN filters are strings composed of zero or more wildcards. A double
      wildcard ** replaces one or more RDN components (as in
      uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a
      whole RDN, or a whole type, or a value substring (as in
      uid=bj*,ou=people,dc=example,dc=com).
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on user DN equality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-user-dn-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="user-dn-not-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with users which do not match any of the
      specified DN patterns.
    </adm:synopsis>
    <adm:description>
      Valid DN filters are strings composed of zero or more wildcards. A double
      wildcard ** replaces one or more RDN components (as in
      uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a
      whole RDN, or a whole type, or a value substring (as in
      uid=bj*,ou=people,dc=example,dc=com).
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on user DN inequality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-user-dn-not-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="user-is-member-of" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with users which are members of at least
      one of the specified groups.
    </adm:synopsis>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on group membership.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:dn />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-user-is-member-of</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="user-is-not-member-of" multi-valued="true">
    <adm:synopsis>
      Filters log records associated with users which are not members of any
      of the specified groups.
    </adm:synopsis>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on group non-membership.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:dn />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-user-is-not-member-of</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="request-target-dn-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters operation log records associated with operations which target
      entries matching at least one of the specified DN patterns.
    </adm:synopsis>
    <adm:description>
      Valid DN filters are strings composed of zero or more wildcards. A double
      wildcard ** replaces one or more RDN components (as in
      uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a
      whole RDN, or a whole type, or a value substring (as in
      uid=bj*,ou=people,dc=example,dc=com).
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on target DN equality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-request-target-dn-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="request-target-dn-not-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters operation log records associated with operations which target
      entries matching none of the specified DN patterns.
    </adm:synopsis>
    <adm:description>
      Valid DN filters are strings composed of zero or more wildcards. A double
      wildcard ** replaces one or more RDN components (as in
      uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a
      whole RDN, or a whole type, or a value substring (as in
      uid=bj*,ou=people,dc=example,dc=com).
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on target DN inequality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-request-target-dn-not-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="response-result-code-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters operation response log records associated with operations which
      include any of the specified result codes.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on result code equality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-response-result-code-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="response-result-code-not-equal-to" multi-valued="true">
    <adm:synopsis>
      Filters operation response log records associated with operations which
      do not include any of the specified result codes.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on result code inequality.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-response-result-code-not-equal-to</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="response-etime-greater-than">
    <adm:synopsis>
      Filters operation response log records associated with operations which
      took longer than the specified number of milli-seconds to complete.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on the etime.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer>
        <adm:unit-synopsis>milli-seconds</adm:unit-synopsis>
      </adm:integer>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-response-etime-greater-than</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="response-etime-less-than">
    <adm:synopsis>
      Filters operation response log records associated with operations which
      took less than the specified number of milli-seconds to complete.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on the etime.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer>
        <adm:unit-synopsis>milli-seconds</adm:unit-synopsis>
      </adm:integer>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-response-etime-less-than</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="search-response-nentries-greater-than">
    <adm:synopsis>
      Filters search operation response log records associated with searches
      which returned more than the specified number of entries.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on the number of search results returned.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer>
        <adm:unit-synopsis>entries</adm:unit-synopsis>
      </adm:integer>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-search-response-nentries-greater-than</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="search-response-nentries-less-than">
    <adm:synopsis>
      Filters search operation response log records associated with searches
      which returned less than the specified number of entries.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on the number of search results returned.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer>
        <adm:unit-synopsis>entries</adm:unit-synopsis>
      </adm:integer>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-search-response-nentries-less-than</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="search-response-is-indexed">
    <adm:synopsis>
      Filters search operation response log records associated with searches
      which were either indexed or unindexed.
    </adm:synopsis>
    <adm:description>
      It is recommended to only use this criteria in conjunction with the
      "combined" output mode of the access logger, since this filter criteria
      is only applied to response log messages.
    </adm:description>
    <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
          Do not filter based on whether or not a search was indexed.
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:boolean/>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-search-response-is-indexed</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/admin/messages/AccessLogFilteringCriteriaCfgDefn.properties
@@ -1,8 +1,21 @@
user-friendly-name=Access Log Filtering Criteria
user-friendly-plural-name=Access Log Filtering Criteria
synopsis=A set of rules which together determine whether a log record should be logged or not.
property.log-record-type.synopsis=
property.log-record-type.default-behavior.alias.synopsis=All records
property.client-address-equal-to.synopsis=Filters log records associated with connections which match at least one of the specified client host names or address masks.
property.client-address-equal-to.description=Valid values include a host name, a fully qualified domain name, a domain name, an IP address, or a subnetwork with subnetwork mask.
property.client-address-equal-to.default-behavior.alias.synopsis=Do not filter based on client address equality.
property.client-address-not-equal-to.synopsis=Filters log records associated with connections which do not match any of the specified client host names or address masks.
property.client-address-not-equal-to.description=Valid values include a host name, a fully qualified domain name, a domain name, an IP address, or a subnetwork with subnetwork mask.
property.client-address-not-equal-to.default-behavior.alias.synopsis=Do not filter based on client address inequality.
property.client-port-equal-to.synopsis=Filters log records associated with connections to any of the specified listener port numbers.
property.client-port-equal-to.default-behavior.alias.synopsis=Do not filter based on the port.
property.client-protocol-equal-to.synopsis=Filters log records associated with connections which match any of the specified protocols.
property.client-protocol-equal-to.default-behavior.alias.synopsis=Do not filter based on the protocol.
property.client-protocol-equal-to.syntax.enumeration.value.jmx.synopsis=JMX clients
property.client-protocol-equal-to.syntax.enumeration.value.ldap.synopsis=LDAP clients
property.client-protocol-equal-to.syntax.enumeration.value.ldaps.synopsis=LDAPS clients
property.log-record-type.synopsis=Filters log records based on their type.
property.log-record-type.default-behavior.alias.synopsis=The log record type will be ignored during filtering.
property.log-record-type.syntax.enumeration.value.abandon.synopsis=Abandon operations
property.log-record-type.syntax.enumeration.value.add.synopsis=Add operations
property.log-record-type.syntax.enumeration.value.bind.synopsis=Bind operations
@@ -15,3 +28,40 @@
property.log-record-type.syntax.enumeration.value.rename.synopsis=Rename operations
property.log-record-type.syntax.enumeration.value.search.synopsis=Search operations
property.log-record-type.syntax.enumeration.value.unbind.synopsis=Unbind operations
property.request-target-dn-equal-to.synopsis=Filters operation log records associated with operations which target entries matching at least one of the specified DN patterns.
property.request-target-dn-equal-to.description=Valid DN filters are strings composed of zero or more wildcards. A double wildcard ** replaces one or more RDN components (as in uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a whole RDN, or a whole type, or a value substring (as in uid=bj*,ou=people,dc=example,dc=com).
property.request-target-dn-equal-to.default-behavior.alias.synopsis=Do not filter based on target DN equality.
property.request-target-dn-not-equal-to.synopsis=Filters operation log records associated with operations which target entries matching none of the specified DN patterns.
property.request-target-dn-not-equal-to.description=Valid DN filters are strings composed of zero or more wildcards. A double wildcard ** replaces one or more RDN components (as in uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a whole RDN, or a whole type, or a value substring (as in uid=bj*,ou=people,dc=example,dc=com).
property.request-target-dn-not-equal-to.default-behavior.alias.synopsis=Do not filter based on target DN inequality.
property.response-etime-greater-than.synopsis=Filters operation response log records associated with operations which took longer than the specified number of milli-seconds to complete.
property.response-etime-greater-than.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.response-etime-greater-than.default-behavior.alias.synopsis=Do not filter based on the etime.
property.response-etime-less-than.synopsis=Filters operation response log records associated with operations which took less than the specified number of milli-seconds to complete.
property.response-etime-less-than.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.response-etime-less-than.default-behavior.alias.synopsis=Do not filter based on the etime.
property.response-result-code-equal-to.synopsis=Filters operation response log records associated with operations which include any of the specified result codes.
property.response-result-code-equal-to.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.response-result-code-equal-to.default-behavior.alias.synopsis=Do not filter based on result code equality.
property.response-result-code-not-equal-to.synopsis=Filters operation response log records associated with operations which do not include any of the specified result codes.
property.response-result-code-not-equal-to.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.response-result-code-not-equal-to.default-behavior.alias.synopsis=Do not filter based on result code inequality.
property.search-response-is-indexed.synopsis=Filters search operation response log records associated with searches which were either indexed or unindexed.
property.search-response-is-indexed.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.search-response-is-indexed.default-behavior.alias.synopsis=Do not filter based on whether or not a search was indexed.
property.search-response-nentries-greater-than.synopsis=Filters search operation response log records associated with searches which returned more than the specified number of entries.
property.search-response-nentries-greater-than.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.search-response-nentries-greater-than.default-behavior.alias.synopsis=Do not filter based on the number of search results returned.
property.search-response-nentries-less-than.synopsis=Filters search operation response log records associated with searches which returned less than the specified number of entries.
property.search-response-nentries-less-than.description=It is recommended to only use this criteria in conjunction with the "combined" output mode of the access logger, since this filter criteria is only applied to response log messages.
property.search-response-nentries-less-than.default-behavior.alias.synopsis=Do not filter based on the number of search results returned.
property.user-dn-equal-to.synopsis=Filters log records associated with users matching at least one of the specified DN patterns.
property.user-dn-equal-to.description=Valid DN filters are strings composed of zero or more wildcards. A double wildcard ** replaces one or more RDN components (as in uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a whole RDN, or a whole type, or a value substring (as in uid=bj*,ou=people,dc=example,dc=com).
property.user-dn-equal-to.default-behavior.alias.synopsis=Do not filter based on user DN equality.
property.user-dn-not-equal-to.synopsis=Filters log records associated with users which do not match any of the specified DN patterns.
property.user-dn-not-equal-to.description=Valid DN filters are strings composed of zero or more wildcards. A double wildcard ** replaces one or more RDN components (as in uid=dmiller,**,dc=example,dc=com). A simple wildcard * replaces either a whole RDN, or a whole type, or a value substring (as in uid=bj*,ou=people,dc=example,dc=com).
property.user-dn-not-equal-to.default-behavior.alias.synopsis=Do not filter based on user DN inequality.
property.user-is-member-of.synopsis=Filters log records associated with users which are members of at least one of the specified groups.
property.user-is-member-of.default-behavior.alias.synopsis=Do not filter based on group membership.
property.user-is-not-member-of.synopsis=Filters log records associated with users which are not members of any of the specified groups.
property.user-is-not-member-of.default-behavior.alias.synopsis=Do not filter based on group non-membership.
opends/src/server/org/opends/server/core/networkgroups/IPConnectionCriteria.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.core.networkgroups;
@@ -77,13 +78,10 @@
  public boolean matches(ClientConnection connection)
  {
    InetAddress ipAddr = connection.getRemoteAddress();
    byte[] address = ipAddr.getAddress();
    String hostName = ipAddr.getHostName();
    if (deniedClients.length > 0)
    {
      if (AddressMask
          .maskListContains(address, hostName, deniedClients))
      if (AddressMask.maskListContains(ipAddr, deniedClients))
      {
        return false;
      }
@@ -91,8 +89,7 @@
    if (allowedClients.length > 0)
    {
      if (!AddressMask.maskListContains(address, hostName,
          allowedClients))
      if (!AddressMask.maskListContains(ipAddr, allowedClients))
      {
        return false;
      }
opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java
@@ -30,11 +30,15 @@
import static org.opends.messages.ConfigMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.server.util.StaticUtils.getFileForPath;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import static org.opends.server.util.StaticUtils.toLowerCase;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.*;
import org.opends.messages.Message;
@@ -50,8 +54,11 @@
import org.opends.server.api.AccessLogPublisher;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ExtendedOperationHandler;
import org.opends.server.api.Group;
import org.opends.server.authorization.dseecompat.PatternDN;
import org.opends.server.config.ConfigException;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.util.TimeThread;
@@ -65,7 +72,6 @@
    AccessLogPublisher<FileBasedAccessLogPublisherCfg> implements
    ConfigurationChangeListener<FileBasedAccessLogPublisherCfg>
{
  /**
   * Criteria based filter.
   */
@@ -75,6 +81,15 @@
    private final boolean logConnectRecords;
    private final boolean logDisconnectRecords;
    private final EnumSet<OperationType> logOperationRecords;
    private final AddressMask[] clientAddressEqualTo;
    private final AddressMask[] clientAddressNotEqualTo;
    private final PatternDN[] userDNEqualTo;
    private final PatternDN[] userDNNotEqualTo;
    private final PatternDN[] targetDNEqualTo;
    private final PatternDN[] targetDNNotEqualTo;
    private final DN[] userIsMemberOf;
    private final DN[] userIsNotMemberOf;
    private final String attachmentName;
@@ -83,11 +98,18 @@
     *
     * @param cfg
     *          The access log filter criteria.
     * @throws DirectoryException
     *           If the configuration cannot be parsed.
     */
    CriteriaFilter(final AccessLogFilteringCriteriaCfg cfg)
        throws DirectoryException
    {
      this.cfg = cfg;
      // Generate a unique identifier for attaching partial results to
      // operations.
      attachmentName = this.getClass().getName() + "#" + hashCode();
      // Pre-parse the log record types for more efficient queries.
      if (cfg.getLogRecordType().isEmpty())
      {
@@ -98,10 +120,10 @@
      }
      else
      {
        logConnectRecords =
          cfg.getLogRecordType().contains(LogRecordType.CONNECT);
        logDisconnectRecords =
          cfg.getLogRecordType().contains(LogRecordType.DISCONNECT);
        logConnectRecords = cfg.getLogRecordType().contains(
            LogRecordType.CONNECT);
        logDisconnectRecords = cfg.getLogRecordType().contains(
            LogRecordType.DISCONNECT);
        logOperationRecords = EnumSet.noneOf(OperationType.class);
        for (final LogRecordType type : cfg.getLogRecordType())
@@ -143,6 +165,43 @@
          }
        }
      }
      clientAddressEqualTo = cfg.getClientAddressEqualTo().toArray(
          new AddressMask[0]);
      clientAddressNotEqualTo = cfg.getClientAddressNotEqualTo().toArray(
          new AddressMask[0]);
      userDNEqualTo = new PatternDN[cfg.getUserDNEqualTo().size()];
      int i = 0;
      for (final String s : cfg.getUserDNEqualTo())
      {
        userDNEqualTo[i++] = PatternDN.decode(s);
      }
      userDNNotEqualTo = new PatternDN[cfg.getUserDNNotEqualTo().size()];
      i = 0;
      for (final String s : cfg.getUserDNNotEqualTo())
      {
        userDNNotEqualTo[i++] = PatternDN.decode(s);
      }
      userIsMemberOf = cfg.getUserIsMemberOf().toArray(new DN[0]);
      userIsNotMemberOf = cfg.getUserIsNotMemberOf().toArray(new DN[0]);
      targetDNEqualTo = new PatternDN[cfg.getRequestTargetDNEqualTo().size()];
      i = 0;
      for (final String s : cfg.getRequestTargetDNEqualTo())
      {
        targetDNEqualTo[i++] = PatternDN.decode(s);
      }
      targetDNNotEqualTo = new PatternDN[cfg.getRequestTargetDNNotEqualTo()
          .size()];
      i = 0;
      for (final String s : cfg.getRequestTargetDNNotEqualTo())
      {
        targetDNNotEqualTo[i++] = PatternDN.decode(s);
      }
    }
@@ -157,7 +216,10 @@
        return false;
      }
      // TODO: other checks.
      if (!filterClientConnection(connection))
      {
        return false;
      }
      return true;
    }
@@ -174,7 +236,15 @@
        return false;
      }
      // TODO: other checks.
      if (!filterClientConnection(connection))
      {
        return false;
      }
      if (!filterUser(connection))
      {
        return false;
      }
      return true;
    }
@@ -186,14 +256,17 @@
     */
    public boolean isRequestLoggable(final Operation operation)
    {
      if (!logOperationRecords.contains(operation.getOperationType()))
      {
        return false;
      }
      final ClientConnection connection = operation.getClientConnection();
      final boolean matches = logOperationRecords.contains(operation
          .getOperationType())
          && filterClientConnection(connection)
          && filterUser(connection) && filterRequest(operation);
      // TODO: other checks.
      // Cache the result so that it does not need to be recomputed for the
      // response.
      operation.setAttachment(attachmentName, matches);
      return true;
      return matches;
    }
@@ -203,20 +276,435 @@
     */
    public boolean isResponseLoggable(final Operation operation)
    {
      if (!logOperationRecords.contains(operation.getOperationType()))
      // First check the result that was computed for the initial request.
      Boolean requestMatched = (Boolean) operation
          .getAttachment(attachmentName);
      if (requestMatched == null)
      {
        // This should not happen.
        if (debugEnabled())
        {
          TRACER.debugWarning(
              "Operation attachment %s not found while logging response",
              attachmentName);
        }
        requestMatched = isRequestLoggable(operation);
      }
      if (!requestMatched)
      {
        return false;
      }
      // TODO: other checks.
      // Check the response parameters.
      if (!filterResponse(operation))
      {
        return false;
      }
      return true;
    }
    private boolean filterClientConnection(final ClientConnection connection)
    {
      // Check client address.
      final InetAddress ipAddr = connection.getRemoteAddress();
      if (clientAddressNotEqualTo.length > 0)
      {
        if (AddressMask.maskListContains(ipAddr, clientAddressNotEqualTo))
        {
          return false;
        }
      }
      if (clientAddressEqualTo.length > 0)
      {
        if (!AddressMask.maskListContains(ipAddr, clientAddressEqualTo))
        {
          return false;
        }
      }
      // Check server port.
      if (!cfg.getClientPortEqualTo().isEmpty())
      {
        if (!cfg.getClientPortEqualTo().contains(connection.getServerPort()))
        {
          return false;
        }
      }
      // Check protocol.
      if (!cfg.getClientProtocolEqualTo().isEmpty())
      {
        if (!cfg.getClientProtocolEqualTo().contains(
            toLowerCase(connection.getProtocol())))
        {
          return false;
        }
      }
      return true;
  }
    private boolean filterRequest(final Operation operation)
    {
      // Check target DN.
      if (targetDNNotEqualTo.length > 0 || targetDNEqualTo.length > 0)
      {
        if (!filterRequestTargetDN(operation))
        {
          return false;
        }
      }
      // TODO: check required controls.
      return true;
    }
    private boolean filterRequestTargetDN(final Operation operation)
    {
      // Obtain both the parsed and unparsed target DNs. Requests are logged
      // before parsing so usually only the raw unparsed target DN will be
      // present, and it may even be invalid.
      DN targetDN = null;
      ByteString rawTargetDN = null;
      switch (operation.getOperationType())
      {
      case ABANDON:
      case UNBIND:
        // These operations don't have parameters which we can filter so
        // always match them.
        return true;
      case EXTENDED:
        // These operations could have parameters which can be filtered but
        // we'd need to decode the request in order to find out. This is
        // beyond the scope of the access log. Therefore, treat extended
        // operations like abandon/unbind.
        return true;
      case ADD:
        targetDN = ((AddOperation) operation).getEntryDN();
        rawTargetDN = ((AddOperation) operation).getRawEntryDN();
        break;
      case BIND:
        // For SASL bind operations the bind DN, if provided, will require the
        // SASL credentials to be decoded which is beyond the scope of the
        // access log.
        targetDN = ((BindOperation) operation).getBindDN();
        rawTargetDN = ((BindOperation) operation).getRawBindDN();
        break;
      case COMPARE:
        targetDN = ((CompareOperation) operation).getEntryDN();
        rawTargetDN = ((CompareOperation) operation).getRawEntryDN();
        break;
      case DELETE:
        targetDN = ((DeleteOperation) operation).getEntryDN();
        rawTargetDN = ((DeleteOperation) operation).getRawEntryDN();
        break;
      case MODIFY:
        targetDN = ((ModifyOperation) operation).getEntryDN();
        rawTargetDN = ((ModifyOperation) operation).getRawEntryDN();
        break;
      case MODIFY_DN:
        targetDN = ((ModifyDNOperation) operation).getEntryDN();
        rawTargetDN = ((ModifyDNOperation) operation).getRawEntryDN();
        break;
      case SEARCH:
        targetDN = ((SearchOperation) operation).getBaseDN();
        rawTargetDN = ((SearchOperation) operation).getRawBaseDN();
        break;
      }
      // Attempt to parse the raw target DN if needed.
      if (targetDN == null)
      {
        try
        {
          targetDN = DN.decode(rawTargetDN);
        }
        catch (final DirectoryException e)
        {
          // The DN raw target DN was invalid. It will never match any
          // not-equal-to nor equal-to patterns, so return appropriate result.
          if (targetDNEqualTo.length != 0)
          {
            // Invalid DN will never match equal-to patterns.
            return false;
          }
          else
          {
            // Invalid DN does not match any not-equal-to patterns.
            return true;
          }
        }
      }
      if (targetDNNotEqualTo.length > 0)
      {
        for (final PatternDN pattern : targetDNNotEqualTo)
        {
          if (pattern.matchesDN(targetDN))
          {
            return false;
          }
        }
      }
      if (targetDNEqualTo.length > 0)
      {
        for (final PatternDN pattern : targetDNNotEqualTo)
        {
          if (pattern.matchesDN(targetDN))
          {
            return true;
          }
        }
      }
      // The target DN did not match.
      return false;
    }
    private boolean filterResponse(final Operation operation)
    {
      // Check response code.
      final Integer resultCode = operation.getResultCode().getIntValue();
      if (!cfg.getResponseResultCodeNotEqualTo().isEmpty())
      {
        if (cfg.getResponseResultCodeNotEqualTo().contains(resultCode))
        {
          return false;
        }
      }
      if (!cfg.getResponseResultCodeEqualTo().isEmpty())
      {
        if (!cfg.getResponseResultCodeNotEqualTo().contains(resultCode))
        {
          return false;
        }
      }
      // Check etime.
      final long etime = operation.getProcessingTime();
      final Integer etimeGT = cfg.getResponseEtimeLessThan();
      if (etimeGT != null)
      {
        if (etime <= ((long) etimeGT))
        {
          return false;
        }
      }
      final Integer etimeLT = cfg.getResponseEtimeLessThan();
      if (etimeLT != null)
      {
        if (etime >= ((long) etimeLT))
        {
          return false;
        }
      }
      // Check search response fields.
      if (operation instanceof SearchOperation)
      {
        final SearchOperation searchOperation = (SearchOperation) operation;
        final Boolean isIndexed= cfg.isSearchResponseIsIndexed();
        if (isIndexed != null)
        {
          boolean wasUnindexed = false;
          for (final AdditionalLogItem item : operation.getAdditionalLogItems())
          {
            if (item.getKey().equals("unindexed"))
            {
              wasUnindexed = true;
              break;
            }
          }
          if (isIndexed)
          {
            if (wasUnindexed)
            {
              return false;
            }
          }
          else
          {
            if (!wasUnindexed)
            {
              return false;
            }
          }
        }
        final int nentries = searchOperation.getEntriesSent();
        final Integer nentriesGT = cfg.getSearchResponseNentriesGreaterThan();
        if (nentriesGT != null)
        {
          if (nentries <= nentriesGT)
          {
            return false;
          }
        }
        final Integer nentriesLT = cfg.getSearchResponseNentriesLessThan();
        if (nentriesLT != null)
        {
          if (nentries >= nentriesLT)
          {
            return false;
          }
        }
      }
      return true;
    }
    private boolean filterUser(final ClientConnection connection)
    {
      // Check user DN.
      if (userDNNotEqualTo.length > 0 || userDNEqualTo.length > 0)
      {
        if (!filterUserBindDN(connection))
        {
          return false;
        }
      }
      // Check group membership.
      if (userIsNotMemberOf.length > 0 || userIsNotMemberOf.length > 0)
      {
        if (!filterUserIsMemberOf(connection))
        {
          return false;
        }
      }
      return true;
    }
    private boolean filterUserBindDN(final ClientConnection connection)
    {
      final DN userDN = connection.getAuthenticationInfo()
          .getAuthenticationDN();
      // Fast-path for unauthenticated clients.
      if (userDN == null)
      {
        return userDNEqualTo.length == 0;
      }
      if (userDNNotEqualTo.length > 0)
      {
        for (final PatternDN pattern : userDNNotEqualTo)
        {
          if (pattern.matchesDN(userDN))
          {
            return false;
          }
        }
      }
      if (userDNEqualTo.length > 0)
      {
        for (final PatternDN pattern : userDNNotEqualTo)
        {
          if (pattern.matchesDN(userDN))
          {
            return true;
          }
        }
      }
      // The user DN did not match.
      return false;
    }
    private boolean filterUserIsMemberOf(final ClientConnection connection)
    {
      final Entry userEntry = connection.getAuthenticationInfo()
          .getAuthenticationEntry();
      // Fast-path for unauthenticated clients.
      if (userEntry == null)
      {
        return userIsMemberOf.length == 0;
      }
      final GroupManager groupManager = DirectoryServer.getGroupManager();
      if (userIsNotMemberOf.length > 0)
      {
        for (final DN groupDN : userIsNotMemberOf)
        {
          final Group<?> group = groupManager.getGroupInstance(groupDN);
          try
          {
            if ((group != null) && group.isMember(userEntry))
            {
              return false;
            }
          }
          catch (final DirectoryException e)
          {
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
          }
        }
      }
      if (userIsMemberOf.length > 0)
      {
        for (final DN groupDN : userIsMemberOf)
        {
          final Group<?> group = groupManager.getGroupInstance(groupDN);
          try
          {
            if ((group != null) && group.isMember(userEntry))
            {
              return true;
            }
          }
          catch (final DirectoryException e)
          {
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
          }
        }
      }
      // The user entry did not match.
      return false;
    }
  }
  // TODO: update assigned OIDs WIKI page when complete.
  /**
   * Log message filter predicate.
   */
@@ -612,6 +1100,11 @@
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  /**
   * The category to use when logging responses.
   */
  private static final String CATEGORY_RESPONSE = "RES";
@@ -1992,6 +2485,11 @@
          // TODO: Unable to decode this access log criteria, so log a warning
          // and continue.
        }
        catch (final DirectoryException e)
        {
          // TODO: Unable to decode this access log criteria, so log a warning
          // and continue.
        }
      }
    }
    final Filter orFilter = new OrFilter(subFilters.toArray(new Filter[0]));
opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -1112,9 +1112,7 @@
    // Check to see if the client is on the denied list.
    // If so, then reject it immediately.
    if ((deniedClients.length > 0)
        && AddressMask.maskListContains(clientAddr
        .getAddress(), clientAddr.getHostName(),
        deniedClients)) {
        && AddressMask.maskListContains(clientAddr, deniedClients)) {
      clientConnection.disconnect(
          DisconnectReason.CONNECTION_REJECTED,
          currentConfig.isSendRejectionNotice(),
@@ -1127,9 +1125,7 @@
    // there is whether the client is on that list. If
    // not, then reject the connection.
    if ((allowedClients.length > 0)
        && (!AddressMask.maskListContains(clientAddr
        .getAddress(), clientAddr.getHostName(),
        allowedClients))) {
        && (!AddressMask.maskListContains(clientAddr, allowedClients))) {
      clientConnection.disconnect(
          DisconnectReason.CONNECTION_REJECTED,
          currentConfig.isSendRejectionNotice(),
opends/src/server/org/opends/server/types/AddressMask.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types;
import org.opends.messages.Message;
@@ -376,24 +377,25 @@
        return new AddressMask(maskString);
    }
    /**
     * Indicates whether provided address or hostname matches one of
     * the address masks in the provided array.
     * Indicates whether provided address matches one of the address masks in
     * the provided array.
     *
     * @param remoteAddr The remote address byte array.
     * @param remoteName The remote host name string.
     * @param masks      An array of address masks to check.
     * @return <CODE>true</CODE> if the provided address or hostname
     *          does match one of the given address masks, or
     *         <CODE>false</CODE> if it does not.
     * @param address
     *          The address to check.
     * @param masks
     *          An array of address masks to check.
     * @return <CODE>true</CODE> if the provided address matches one of the
     *         given address masks, or <CODE>false</CODE> if it does not.
     */
    public  static boolean maskListContains(byte[] remoteAddr,
                                            String remoteName,
    public  static boolean maskListContains(InetAddress address,
                                            AddressMask[] masks)
    {
        for (AddressMask mask : masks) {
            if(mask.match(remoteAddr, remoteName))
                return true;
      for (AddressMask mask : masks)
      {
        if (mask.match(address)) return true;
        }
        return false;
    }
@@ -412,12 +414,12 @@
    /**
     * Main match function that determines which rule-type match
     * function to use.
     * @param remoteAddr The remote client address byte array.
     * @param remoteName The remote client host name.
     * @param address
     *          The address to check.
     * @return <CODE>true</CODE>if one of the match functions found
     *         a match or <CODE>false</CODE>if not.
     */
    private boolean match(byte[] remoteAddr, String remoteName)
    private boolean match(InetAddress address)
    {
        boolean ret=false;
@@ -425,24 +427,24 @@
        case IPv6:
        case IPv4:
            //this Address mask is an IPv4 rule
            ret=matchAddress(remoteAddr);
            ret=matchAddress(address.getAddress());
            break;
        case HOST:
            // HOST rule use hostname
            ret=matchHostName(remoteName);
            ret=matchHostName(address.getHostName());
            break;
        case HOSTPATTERN:
            //HOSTPATTERN rule
            ret=matchPattern(remoteName);
            ret=matchPattern(address.getHostName());
            break;
        case ALLWILDCARD:
            //first try  ipv4 addr match, then hostname
            ret=matchAddress(remoteAddr);
            ret=matchAddress(address.getAddress());
            if(!ret)
                ret=matchHostName(remoteName);
                ret=matchHostName(address.getHostName());
            break;
        }
        return ret;
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types;
@@ -257,7 +258,7 @@
    for(int j = 0; j < addrs.length; j++) {
      try  {
        InetAddress addr = InetAddress.getByName(addrs[j]);
        if(!AddressMask.maskListContains(addr.getAddress(), hostNames[j], m)) {
        if(!AddressMask.maskListContains(addr, m)) {
          ret=false;
          break;
        }