1$desc = <<'ESQ'; 2 LDAPMessage ::= SEQUENCE { 3 messageID MessageID, 4 protocolOp CHOICE { 5 bindRequest BindRequest, 6 bindResponse BindResponse, 7 unbindRequest UnbindRequest, 8 searchRequest SearchRequest, 9 searchResEntry SearchResultEntry, 10 searchResDone SearchResultDone, 11 searchResRef SearchResultReference, 12 modifyRequest ModifyRequest, 13 modifyResponse ModifyResponse, 14 addRequest AddRequest, 15 addResponse AddResponse, 16 delRequest DelRequest, 17 delResponse DelResponse, 18 modDNRequest ModifyDNRequest, 19 modDNResponse ModifyDNResponse, 20 compareRequest CompareRequest, 21 compareResponse CompareResponse, 22 abandonRequest AbandonRequest, 23 extendedReq ExtendedRequest, 24 extendedResp ExtendedResponse } 25 controls [0] Controls OPTIONAL } 26 27 MessageID ::= INTEGER -- (0 .. maxInt) 28 29 -- maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) -- 30 31 LDAPString ::= OCTET STRING 32 33 LDAPOID ::= OCTET STRING 34 35 LDAPDN ::= LDAPString 36 37 RelativeLDAPDN ::= LDAPString 38 39 AttributeType ::= LDAPString 40 41 AttributeDescription ::= LDAPString 42 43 AttributeDescriptionList ::= SEQUENCE OF 44 AttributeDescription 45 46 AttributeValue ::= OCTET STRING 47 48 AttributeValueAssertion ::= SEQUENCE { 49 attributeDesc AttributeDescription, 50 assertionValue AssertionValue } 51 52 AssertionValue ::= OCTET STRING 53 54 Attribute ::= SEQUENCE { 55 type AttributeDescription, 56 vals SET OF AttributeValue } 57 58 MatchingRuleId ::= LDAPString 59 60 LDAPResult ::= SEQUENCE { 61 resultCode ENUMERATED { 62 success (0), 63 operationsError (1), 64 protocolError (2), 65 timeLimitExceeded (3), 66 sizeLimitExceeded (4), 67 compareFalse (5), 68 compareTrue (6), 69 authMethodNotSupported (7), 70 strongAuthRequired (8), 71 -- 9 reserved -- 72 referral (10), -- new 73 adminLimitExceeded (11), -- new 74 unavailableCriticalExtension (12), -- new 75 confidentialityRequired (13), -- new 76 saslBindInProgress (14), -- new 77 noSuchAttribute (16), 78 undefinedAttributeType (17), 79 inappropriateMatching (18), 80 constraintViolation (19), 81 attributeOrValueExists (20), 82 invalidAttributeSyntax (21), 83 -- 22-31 unused -- 84 noSuchObject (32), 85 aliasProblem (33), 86 invalidDNSyntax (34), 87 -- 35 reserved for undefined isLeaf -- 88 aliasDereferencingProblem (36), 89 -- 37-47 unused -- 90 inappropriateAuthentication (48), 91 invalidCredentials (49), 92 insufficientAccessRights (50), 93 busy (51), 94 unavailable (52), 95 unwillingToPerform (53), 96 loopDetect (54), 97 -- 55-63 unused -- 98 namingViolation (64), 99 objectClassViolation (65), 100 notAllowedOnNonLeaf (66), 101 notAllowedOnRDN (67), 102 entryAlreadyExists (68), 103 objectClassModsProhibited (69), 104 -- 70 reserved for CLDAP -- 105 affectsMultipleDSAs (71), -- new 106 -- 72-79 unused -- 107 other (80)} 108 -- 81-90 reserved for APIs -- 109 matchedDN LDAPDN, 110 errorMessage LDAPString, 111 referral [3] Referral OPTIONAL } 112 113 Referral ::= SEQUENCE OF LDAPURL 114 115 LDAPURL ::= LDAPString -- limited to characters permitted in URLs 116 117 Controls ::= SEQUENCE OF Control 118 119 Control ::= SEQUENCE { 120 controlType LDAPOID, 121 criticality BOOLEAN , -- DEFAULT FALSE, 122 controlValue OCTET STRING OPTIONAL } 123 124 BindRequest ::= [APPLICATION 0] SEQUENCE { 125 version INTEGER, -- (1 .. 127), 126 name LDAPDN, 127 authentication AuthenticationChoice } 128 129 AuthenticationChoice ::= CHOICE { 130 simple [0] OCTET STRING, 131 -- 1 and 2 reserved 132 sasl [3] SaslCredentials } 133 134 SaslCredentials ::= SEQUENCE { 135 mechanism LDAPString, 136 credentials OCTET STRING OPTIONAL } 137 138 BindResponse ::= [APPLICATION 1] SEQUENCE { 139 COMPONENTS OF LDAPResult, 140 serverSaslCreds [7] OCTET STRING OPTIONAL } 141 142 UnbindRequest ::= [APPLICATION 2] NULL 143 144 SearchRequest ::= [APPLICATION 3] SEQUENCE { 145 baseObject LDAPDN, 146 scope ENUMERATED { 147 baseObject (0), 148 singleLevel (1), 149 wholeSubtree (2) } 150 derefAliases ENUMERATED { 151 neverDerefAliases (0), 152 derefInSearching (1), 153 derefFindingBaseObj (2), 154 derefAlways (3) } 155 sizeLimit INTEGER , -- (0 .. maxInt), 156 timeLimit INTEGER , -- (0 .. maxInt), 157 typesOnly BOOLEAN, 158 filter Filter, 159 attributes AttributeDescriptionList } 160 161 Filter ::= CHOICE { 162 and [0] SET OF Filter, 163 or [1] SET OF Filter, 164 not [2] Filter, 165 equalityMatch [3] AttributeValueAssertion, 166 substrings [4] SubstringFilter, 167 greaterOrEqual [5] AttributeValueAssertion, 168 lessOrEqual [6] AttributeValueAssertion, 169 present [7] AttributeDescription, 170 approxMatch [8] AttributeValueAssertion, 171 extensibleMatch [9] MatchingRuleAssertion } 172 173 SubstringFilter ::= SEQUENCE { 174 type AttributeDescription, 175 -- at least one must be present 176 substrings SEQUENCE OF CHOICE { 177 initial [0] LDAPString, 178 any [1] LDAPString, 179 final [2] LDAPString } } 180 181 MatchingRuleAssertion ::= SEQUENCE { 182 matchingRule [1] MatchingRuleId OPTIONAL, 183 type [2] AttributeDescription OPTIONAL, 184 matchValue [3] AssertionValue, 185 dnAttributes [4] BOOLEAN } -- DEFAULT FALSE } 186 187 SearchResultEntry ::= [APPLICATION 4] SEQUENCE { 188 objectName LDAPDN, 189 attributes PartialAttributeList } 190 191 PartialAttributeList ::= SEQUENCE OF SEQUENCE { 192 type AttributeDescription, 193 vals SET OF AttributeValue } 194 195 SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL 196 197 SearchResultDone ::= [APPLICATION 5] LDAPResult 198 199 ModifyRequest ::= [APPLICATION 6] SEQUENCE { 200 object LDAPDN, 201 modification SEQUENCE OF SEQUENCE { 202 operation ENUMERATED { 203 add (0), 204 delete (1), 205 replace (2) } 206 modification AttributeTypeAndValues } } 207 208 AttributeTypeAndValues ::= SEQUENCE { 209 type AttributeDescription, 210 vals SET OF AttributeValue } 211 212 ModifyResponse ::= [APPLICATION 7] LDAPResult 213 214 AddRequest ::= [APPLICATION 8] SEQUENCE { 215 entry LDAPDN, 216 attributes AttributeList } 217 218 AttributeList ::= SEQUENCE OF SEQUENCE { 219 type AttributeDescription, 220 vals SET OF AttributeValue } 221 222 AddResponse ::= [APPLICATION 9] LDAPResult 223 224 DelRequest ::= [APPLICATION 10] LDAPDN 225 226 DelResponse ::= [APPLICATION 11] LDAPResult 227 228 ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { 229 entry LDAPDN, 230 newrdn RelativeLDAPDN, 231 deleteoldrdn BOOLEAN, 232 newSuperior [0] LDAPDN OPTIONAL } 233 234 ModifyDNResponse ::= [APPLICATION 13] LDAPResult 235 236 CompareRequest ::= [APPLICATION 14] SEQUENCE { 237 entry LDAPDN, 238 ava AttributeValueAssertion } 239 240 CompareResponse ::= [APPLICATION 15] LDAPResult 241 242 AbandonRequest ::= [APPLICATION 16] MessageID 243 244 ExtendedRequest ::= [APPLICATION 23] SEQUENCE { 245 requestName [0] LDAPOID, 246 requestValue [1] OCTET STRING OPTIONAL } 247 248 ExtendedResponse ::= [APPLICATION 24] SEQUENCE { 249 COMPONENTS OF LDAPResult, 250 responseName [10] LDAPOID OPTIONAL, 251 response [11] OCTET STRING OPTIONAL } 252 253 254 VirtualListViewRequest ::= SEQUENCE { 255 beforeCount INTEGER , --(0 .. maxInt), 256 afterCount INTEGER , --(0 .. maxInt), 257 CHOICE { 258 byIndex [0] SEQUENCE { 259 index INTEGER , --(0 .. maxInt), 260 contentCount INTEGER } --(0 .. maxInt) } 261 byValue [1] AssertionValue } 262 -- byValue [1] greaterThanOrEqual assertionValue } 263 contextID OCTET STRING OPTIONAL } 264 265 VirtualListViewResponse ::= SEQUENCE { 266 targetPosition INTEGER , --(0 .. maxInt), 267 contentCount INTEGER , --(0 .. maxInt), 268 virtualListViewResult ENUMERATED { 269 success (0), 270 operatonsError (1), 271 unwillingToPerform (53), 272 insufficientAccessRights (50), 273 busy (51), 274 timeLimitExceeded (3), 275 adminLimitExceeded (11), 276 sortControlMissing (60), 277 indexRangeError (61), 278 other (80) } } 279ESQ 280 281use lib 'lib'; 282use Convert::ASN1 qw(:debug); 283use Convert::ASN1::Debug qw(asn_dump asn_hexdump); 284$asn = Convert::ASN1->new; 285$asn->prepare($desc) or die $asn->error; 286#$asn->dump; 287 288$filter = $asn->find('Filter'); 289 290# A Filter 291# (&(!(desc=value))(|(xx=x*y*)(yy=*1*2))) 292 293$buf = $filter->encode( 294{ 295 and => [ 296 { 297 not => { 298 equalityMatch => { 299 attributeDesc => 'desc', 300 assertionValue => 'value' 301 } 302 } 303 }, 304 { 305 or => [ 306 { 307 substrings => { 308 type => 'xx', 309 substrings => [ 310 { 311 initial => 'x' 312 }, 313 { 314 any => 'y' 315 } 316 ] 317 } 318 }, 319 { 320 substrings => { 321 type => 'yy', 322 substrings => [ 323 { 324 any => 1 325 }, 326 { 327 final => 2 328 } 329 ] 330 } 331 } 332 ] 333 } 334 ] 335} 336) or die $filter->error; 337 338asn_dump($buf); 339 340$ret = $filter->decode($buf) or die $filter->error; 341use Data::Dumper; 342$Data::Dumper::Indent=1; 343$Data::Dumper::Quotekeys=0; 344print Dumper($ret); 345