1# ldap.test - Copyright (C) 2006 Michael Schlenker <mic42@user.sourceforge.net> 2# 3# Tests for the Tcllib ldap package 4# 5# ------------------------------------------------------------------------- 6# See the file "license.terms" for information on usage and redistribution 7# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 8# ------------------------------------------------------------------------- 9# RCS: @(#) $Id: ldap.test,v 1.5 2008/07/20 19:50:55 mic42 Exp $ 10 11# ------------------------------------------------------------------------- 12 13source [file join \ 14 [file dirname [file dirname [file join [pwd] [info script]]]] \ 15 devtools testutilities.tcl] 16 17testsNeedTcl 8.4 18testsNeedTcltest 2.0 19 20testing { 21 useLocal ldap.tcl ldap 22 useLocal ../asn/asn.tcl asn 23} 24 25 26namespace import ::asn::* 27 28# ------------------------------------------------------------------------- 29# Tests 30# ------------------------------------------------------------------------- 31 32test ldap-2.0 {check info ip subcommand error handling 33} -body { 34 ldap::info ip 35} -returnCodes {error} \ 36 -result {Wrong # of arguments. Usage: ldap::info ip handle} 37 38test ldap-2.1 {check info ip subcommand error handling 39} -body { 40 ldap::info ip foobar 41} -returnCodes {error} \ 42 -result {Not a valid LDAP connection handle: foobar} 43 44test ldap-3.0 {check info connections subcommand error handling 45} -body { 46 ldap::info connections foo 47} -returnCodes {error} \ 48 -result {Wrong # of arguments. Usage: ldap::info connections} 49 50test ldap-4.0 {check info bound subcommand error handling 51} -body { 52 ldap::info bound 53} -returnCodes {error} \ 54 -result {Wrong # of arguments. Usage: ldap::info bound handle} 55 56test ldap-4.1 {check info bound subcommand error handling 57} -body { 58 ldap::info bound foobar 59} -returnCodes {error} \ 60 -result {Not a valid LDAP connection handle: foobar} 61 62test ldap-5.0 {check info tls subcommand error handling 63} -body { 64 ldap::info tls 65} -returnCodes {error} \ 66 -result {Wrong # of arguments. Usage: ldap::info tls handle} 67 68test ldap-5.1 {check info tls subcommand error handling 69} -body { 70 ldap::info tls foobar 71} -returnCodes {error} \ 72 -result {Not a valid LDAP connection handle: foobar} 73 74test ldap-6.0 {check info bounduser subcommand error handling 75} -body { 76 ldap::info bounduser 77} -returnCodes {error} \ 78 -result {Wrong # of arguments. Usage: ldap::info bounduser handle} 79 80test ldap-6.1 {check info bounduser subcommand error handling 81} -body { 82 ldap::info bounduser foobar 83} -returnCodes {error} \ 84 -result {Not a valid LDAP connection handle: foobar} 85 86test ldap-7.0 {check info saslmechanisms subcommand error handling 87} -body { 88 ldap::info saslmechanisms 89} -returnCodes {error} \ 90 -result {Wrong # of arguments. Usage: ldap::info saslmechanisms handle} 91 92test ldap-7.1 {check info saslmechanisms subcommand error handling 93} -body { 94 ldap::info saslmechanisms foobar 95} -returnCodes {error} \ 96 -result {Not a valid LDAP connection handle: foobar} 97 98test ldap-8.0 {check info extensions subcommand error handling 99} -body { 100 ldap::info extensions 101} -returnCodes {error} \ 102 -result {Wrong # of arguments. Usage: ldap::info extensions handle} 103 104test ldap-8.1 {check info extensions subcommand error handling 105} -body { 106 ldap::info extensions foobar 107} -returnCodes {error} \ 108 -result {Not a valid LDAP connection handle: foobar} 109 110test ldap-9.0 {check info control subcommand error handling 111} -body { 112 ldap::info control 113} -returnCodes {error} \ 114 -result {Wrong # of arguments. Usage: ldap::info control handle} 115 116test ldap-9.1 {check info control subcommand error handling 117} -body { 118 ldap::info control foobar 119} -returnCodes {error} \ 120 -result {Not a valid LDAP connection handle: foobar} 121 122test ldap-10.0 {check info features subcommand error handling 123} -body { 124 ldap::info features 125} -returnCodes {error} \ 126 -result {Wrong # of arguments. Usage: ldap::info features handle} 127 128test ldap-10.1 {check info features subcommand error handling 129} -body { 130 ldap::info features foobar 131} -returnCodes {error} \ 132 -result {Not a valid LDAP connection handle: foobar} 133 134test ldap-11.0 {check info whoami subcommand error handling 135} -body { 136 ldap::info whoami 137} -returnCodes {error} \ 138 -result {Wrong # of arguments. Usage: ldap::info whoami handle} 139 140test ldap-11.1 {check info whoami subcommand error handling 141} -body { 142 ldap::info whoami foobar 143} -returnCodes {error} \ 144 -result {Not a valid LDAP connection handle: foobar} 145 146test ldap-12.0 {check wrong num args for ldap::connect 147} -body { 148 ldap::connect 149} -returnCodes {error} \ 150 -result [tcltest::wrongNumArgs \ 151 {ldap::connect} {host ?port?} 0] 152 153test ldap-13.0 {check wrong num args for ldap::secure_connect 154} -body { 155 ldap::secure_connect 156} -returnCodes {error} \ 157 -result [tcltest::wrongNumArgs \ 158 {ldap::secure_connect} {host ?port?} 0] 159 160test ldap-14.0 {check wrong num args for ldap::starttls 161} -body { 162 ldap::starttls 163} -returnCodes {error} \ 164 -result [tcltest::wrongNumArgs {ldap::starttls} \ 165 {handle ?cafile? ?certfile? ?keyfile?} 0] 166 167test ldap-15.0 {check wrong num args for ldap::bindSASL 168} -body { 169 ldap::bindSASL 170} -returnCodes {error} \ 171 -result [tcltest::wrongNumArgs {ldap::bindSASL} {handle ?name? ?password?} 0] 172 173test ldap-16.0 {check wrong num args for ldap::bind 174} -body { 175 ldap::bind 176} -returnCodes {error} \ 177 -result [tcltest::wrongNumArgs {ldap::bind} {handle ?name? ?password?} 0] 178 179test ldap-17.0 {check wrong num args for ldap::unbind 180} -body { 181 ldap::unbind 182} -returnCodes {error} \ 183 -result [tcltest::wrongNumArgs {ldap::unbind} {handle} 1 ] 184 185test ldap-18.0 {check wrong num args for ldap::search 186} -body { 187 ldap::search 188} -returnCodes {error} \ 189 -result [tcltest::wrongNumArgs {ldap::search} \ 190 {handle baseObject filterString attributes args} 0] 191 192test ldap-19.0 {check wrong num args for ldap::searchInit 193} -body { 194 ldap::searchInit 195} -returnCodes {error} \ 196 -result [tcltest::wrongNumArgs {ldap::searchInit} \ 197 {handle baseObject filterString attributes opt} 0] 198 199test ldap-20.0 {check wrong num args for ldap::searchNext 200} -body { 201 ldap::searchNext 202} -returnCodes {error} \ 203 -result [tcltest::wrongNumArgs {ldap::searchNext} {handle} 0 ] 204 205test ldap-21.0 {check wrong num args for ldap::searchEnd 206} -body { 207 ldap::searchEnd 208} -returnCodes {error} \ 209 -result [tcltest::wrongNumArgs {ldap::searchEnd} {handle} 0 ] 210 211test ldap-22.0 {check wrong num args for ldap::modify 212} -body { 213 ldap::modify 214} -returnCodes {error} \ 215 -result [tcltest::wrongNumArgs {ldap::modify} \ 216 {handle dn attrValToReplace ?attrToDelete? ?attrValToAdd?} 0 ] 217 218test ldap-23.0 {check wrong num args for ldap::modifyMulti 219} -body { 220 ldap::modifyMulti 221} -returnCodes {error} \ 222 -result [tcltest::wrongNumArgs {ldap::modifyMulti} \ 223 {handle dn attrValToReplace ?attrValToDelete? ?attrValToAdd?} 0 ] 224 225test ldap-24.0 {check wrong num args for ldap::add 226} -body { 227 ldap::add 228} -returnCodes {error} \ 229 -result [tcltest::wrongNumArgs {ldap::add} \ 230 {handle dn attrValueTuples} 0 ] 231 232test ldap-25.0 {check wrong num args for ldap::addMulti 233} -body { 234 ldap::addMulti 235} -returnCodes {error} \ 236 -result [tcltest::wrongNumArgs {ldap::addMulti} \ 237 {handle dn attrValueTuples} 0 ] 238 239test ldap-26.0 {check wrong num args for ldap::delete 240} -body { 241 ldap::delete 242} -returnCodes {error} \ 243 -result [tcltest::wrongNumArgs {ldap::delete} \ 244 {handle dn} 0 ] 245 246test ldap-27.0 {check wrong num args for ldap::modifyDN 247} -body { 248 ldap::modifyDN 249} -returnCodes {error} \ 250 -result [tcltest::wrongNumArgs {ldap::modifyDN} \ 251 {handle dn newrdn ?deleteOld? ?newSuperior?} 0 ] 252 253test ldap-28.0 {check wrong num args for ldap::disconnect 254} -body { 255 ldap::disconnect 256} -returnCodes {error} \ 257 -result [tcltest::wrongNumArgs {ldap::disconnect} \ 258 {handle} 0 ] 259# ------------------------------------------------------------------------- 260# Handling of string representation of filters (RFC 4515): 261# ------------------------------------------------------------------------- 262 263proc glue args { 264 join $args "" 265} 266 267test filter-0.0 {[glue] should concatenate its string arguments} -body { 268 glue a b c d \0 foo 269} -result abcd\0foo 270 271test filter-1.0 {LDAPString produces packed UTF-8} -body { 272 binary scan [ldap::filter::LDAPString \u043a\u0430\u0448\u0430] H* foo 273 set foo 274} -result d0bad0b0d188d0b0 -cleanup { unset foo } 275 276test filter-1.1 {AssertionValue produces packed UTF-8} -body { 277 binary scan [ldap::filter::AssertionValue \u043a\u0430\u0448\u0430] H* foo 278 set foo 279} -result d0bad0b0d188d0b0 -cleanup { unset foo } 280 281test filter-1.2 {AssertionValue produces packed UTF-8 282 but allows embedding of arbitrary bytes via escaping} -body { 283 binary scan [ldap::filter::AssertionValue \u043a\\FF\u0430\\ab\u0448\\de\u0430\\Fe] H* foo 284 set foo 285} -result d0baffd0b0abd188ded0b0fe -cleanup { unset foo } 286 287test filter-1.3 {LDAPString produces packed UTF-8, all characters pass as is} -body { 288 binary scan [ldap::filter::LDAPString \u043a\\FF\u0430\\ab\u0448\\de\u0430\\Fe] H* foo 289 set foo 290} -result d0ba5c4646d0b05c6162d1885c6465d0b05c4665 -cleanup { unset foo } 291 292test filter-2.0 {Backslash escaping in assertion values} -body { 293 set a "" 294 set b "" 295 for {set i 0} {$i <= 255} {incr i} { 296 append a [format \\%02x $i] ;# lowercase hex 297 append b [format %c $i] 298 } 299 string equal [ldap::filter::AssertionValue $a] $b 300} -result 1 -cleanup { unset a b i } 301 302test filter-2.1 {Backslash escaping in assertion values} -body { 303 set a "" 304 set b "" 305 for {set i 0} {$i <= 255} {incr i} { 306 append a [format \\%02X $i] ;# uppercase hex 307 append b [format %c $i] 308 } 309 string equal [ldap::filter::AssertionValue $a] $b 310} -result 1 -cleanup { unset a b i } 311 312test filter-3.1 {Malformed backslash escaping in assertion values} -body { 313 ldap::filter::AssertionValue foo\\0 314} -returnCodes error -result {Invalid filter: malformed assertion value} 315 316test filter-3.2 {Malformed backslash escaping in assertion values} -body { 317 ldap::filter::AssertionValue \\foo 318} -returnCodes error -result {Invalid filter: malformed assertion value} 319 320test filter-3.3 {Malformed backslash escaping in assertion values} -body { 321 ldap::filter::AssertionValue hA\\1x0rz 322} -returnCodes error -result {Invalid filter: malformed assertion value} 323 324test filter-3.4 {Malformed backslash escaping in assertion values} -body { 325 ldap::filter::AssertionValue \\value 326} -returnCodes error -result {Invalid filter: malformed assertion value} 327 328test filter-3.5 {Malformed backslash escaping in assertion values} -body { 329 ldap::filter::AssertionValue end\\ 330} -returnCodes error -result {Invalid filter: malformed assertion value} 331 332test filter-4.0 {Presence match} -body { 333 ldap::filter::encode (Certificates=*) 334} -result [asnChoice 7 [ldap::filter::LDAPString Certificates]] 335 336test filter-4.1 {Presence match + attribute options} -body { 337 ldap::filter::encode (Certificates\;binary\;X-FooBar=*) 338} -result [asnChoice 7 [ldap::filter::LDAPString Certificates\;binary\;X-FooBar]] 339 340test filter-5.0 {Equality match} -body { 341 ldap::filter::encode (foo=bar) 342} -result [asnChoiceConstr 3 [glue \ 343 [asnOctetString [ldap::filter::LDAPString foo]] \ 344 [asnOctetString [ldap::filter::AssertionValue bar]]]] 345 346test filter-5.1 {Equality match with empty assertion value} -body { 347 ldap::filter::encode (seeAlso=) 348} -result [asnChoiceConstr 3 [glue \ 349 [asnOctetString [ldap::filter::LDAPString seeAlso]] \ 350 [asnOctetString [ldap::filter::AssertionValue ""]]]] 351 352test filter-5.2 {Equality match + attribute options} -body { 353 ldap::filter::encode (foo\;X-option=bar) 354} -result [asnChoiceConstr 3 [glue \ 355 [asnOctetString [ldap::filter::LDAPString foo\;X-option]] \ 356 [asnOctetString [ldap::filter::AssertionValue bar]]]] 357 358test filter-5.3 {Equality match, spaces in assertion value} -body { 359 ldap::filter::encode {(personName=Jane W. Random)} 360} -result [asnChoiceConstr 3 [glue \ 361 [asnOctetString [ldap::filter::LDAPString personName]] \ 362 [asnOctetString [ldap::filter::AssertionValue "Jane W. Random"]]]] 363 364test filter-6.0 {Approx match} -body { 365 ldap::filter::encode (descr~=val) 366} -result [asnChoiceConstr 8 [glue \ 367 [asnOctetString [ldap::filter::LDAPString descr]] \ 368 [asnOctetString [ldap::filter::AssertionValue val]]]] 369 370test filter-6.1 {Approx match with empty assertion value} -body { 371 ldap::filter::encode (cn~=) 372} -result [asnChoiceConstr 8 [glue \ 373 [asnOctetString [ldap::filter::LDAPString cn]] \ 374 [asnOctetString [ldap::filter::AssertionValue ""]]]] 375 376test filter-6.2 {Approx match + attribute options} -body { 377 ldap::filter::encode (binaryCert\;binary~=0000) 378} -result [asnChoiceConstr 8 [glue \ 379 [asnOctetString [ldap::filter::LDAPString binaryCert\;binary]] \ 380 [asnOctetString [ldap::filter::AssertionValue 0000]]]] 381 382test filter-7.0 {Less or equal match} -body { 383 ldap::filter::encode (attr<=string) 384} -result [asnChoiceConstr 6 [glue \ 385 [asnOctetString [ldap::filter::LDAPString attr]] \ 386 [asnOctetString [ldap::filter::AssertionValue string]]]] 387 388test filter-7.1 {Less or equal match with empty assertion value} -body { 389 ldap::filter::encode (attr<=) 390} -result [asnChoiceConstr 6 [glue \ 391 [asnOctetString [ldap::filter::LDAPString attr]] \ 392 [asnOctetString [ldap::filter::AssertionValue ""]]]] 393 394test filter-7.2 {Less or equal match + attribute options} -body { 395 ldap::filter::encode (binaryCert\;binary<=01234) 396} -result [asnChoiceConstr 6 [glue \ 397 [asnOctetString [ldap::filter::LDAPString binaryCert\;binary]] \ 398 [asnOctetString [ldap::filter::AssertionValue 01234]]]] 399 400test filter-8.0 {Greater or equal match} -body { 401 ldap::filter::encode (one>=two) 402} -result [asnChoiceConstr 5 [glue \ 403 [asnOctetString [ldap::filter::LDAPString one]] \ 404 [asnOctetString [ldap::filter::AssertionValue two]]]] 405 406test filter-8.1 {Greater or equal match with empty attribute} -body { 407 ldap::filter::encode (one>=) 408} -result [asnChoiceConstr 5 [glue \ 409 [asnOctetString [ldap::filter::LDAPString one]] \ 410 [asnOctetString [ldap::filter::AssertionValue ""]]]] 411 412test filter-8.2 {Greater or equal match + attribute options} -body { 413 ldap::filter::encode (exampleAttr\;X-experimental>=value) 414} -result [asnChoiceConstr 5 [glue \ 415 [asnOctetString [ldap::filter::LDAPString exampleAttr\;X-experimental]] \ 416 [asnOctetString [ldap::filter::AssertionValue value]]]] 417 418test filter-9.0 {Substrings match: only initial string} -body { 419 ldap::filter::encode (sAMAccountName=management-*) 420} -result [asnChoiceConstr 4 [glue \ 421 [asnOctetString [ldap::filter::LDAPString sAMAccountName]] \ 422 [asnSequence [asnChoice 0 [ldap::filter::AssertionValue management-]]]]] 423 424test filter-9.1 {Substrings match: only final string} -body { 425 ldap::filter::encode (User=*ish) 426} -result [asnChoiceConstr 4 [glue \ 427 [asnOctetString [ldap::filter::LDAPString User]] \ 428 [asnSequence [asnChoice 2 [ldap::filter::AssertionValue ish]]]]] 429 430test filter-9.2 {Substrings match: initial and final strings} -body { 431 ldap::filter::encode (OU=F*off) 432} -result [asnChoiceConstr 4 [glue \ 433 [asnOctetString [ldap::filter::LDAPString OU]] \ 434 [asnSequence \ 435 [asnChoice 0 [ldap::filter::AssertionValue F]] \ 436 [asnChoice 2 [ldap::filter::AssertionValue off]]]]] 437 438test filter-9.3 {Substrings match: initial, any and final strings} -body { 439 ldap::filter::encode (mail=Schlenk*@uni-*.de) 440} -result [asnChoiceConstr 4 [glue \ 441 [asnOctetString [ldap::filter::LDAPString mail]] \ 442 [asnSequence \ 443 [asnChoice 0 [ldap::filter::AssertionValue Schlenk]] \ 444 [asnChoice 1 [ldap::filter::AssertionValue @uni-]] \ 445 [asnChoice 2 [ldap::filter::AssertionValue .de]]]]] 446 447test filter-9.4 {Substrings match: multiple any strings} -body { 448 ldap::filter::encode (Something=a*b*c*d*e) 449} -result [asnChoiceConstr 4 [glue \ 450 [asnOctetString [ldap::filter::LDAPString Something]] \ 451 [asnSequence \ 452 [asnChoice 0 [ldap::filter::AssertionValue a]] \ 453 [asnChoice 1 [ldap::filter::AssertionValue b]] \ 454 [asnChoice 1 [ldap::filter::AssertionValue c]] \ 455 [asnChoice 1 [ldap::filter::AssertionValue d]] \ 456 [asnChoice 2 [ldap::filter::AssertionValue e]]]]] 457 458test filter-9.5 {Substrings match: no initial and final strings} -body { 459 ldap::filter::encode (Whatever=*foo*) 460} -result [asnChoiceConstr 4 [glue \ 461 [asnOctetString [ldap::filter::LDAPString Whatever]] \ 462 [asnSequence \ 463 [asnChoice 1 [ldap::filter::AssertionValue foo]]]]] 464 465test filter-9.6 {Substrings match: empty any string prevention} -body { 466 ldap::filter::encode {(Person=J.Ra***m Hacker)} 467} -result [asnChoiceConstr 4 [glue \ 468 [asnOctetString [ldap::filter::LDAPString Person]] \ 469 [asnSequence \ 470 [asnChoice 0 [ldap::filter::AssertionValue J.Ra]] \ 471 [asnChoice 2 [ldap::filter::AssertionValue {m Hacker}]]]]] 472 473test filter-9.7 {Substrings match: empty any string prevention} -body { 474 ldap::filter::encode (SomeType=***foo***bar***baz**********) 475} -result [asnChoiceConstr 4 [glue \ 476 [asnOctetString [ldap::filter::LDAPString SomeType]] \ 477 [asnSequence \ 478 [asnChoice 1 [ldap::filter::AssertionValue foo]] \ 479 [asnChoice 1 [ldap::filter::AssertionValue bar]] \ 480 [asnChoice 1 [ldap::filter::AssertionValue baz]]]]] 481 482test filter-9.8 {Substrings match: parsing to zero parts} -body { 483 ldap::filter::encode (SomeType=**) 484} -returnCodes error -result {Invalid filter: substrings match parses to zero parts} 485 486test filter-9.10 {Substrings match: parsing to zero parts} -body { 487 ldap::filter::encode (SomeOtherType=*****) 488} -returnCodes error -result {Invalid filter: substrings match parses to zero parts} 489 490test filter-9.11 {Substrings match: spaces in assertion value} -body { 491 ldap::filter::encode {(Something=Jane Random*and*J. Random Hacker)} 492} -result [asnChoiceConstr 4 [glue \ 493 [asnOctetString [ldap::filter::LDAPString Something]] \ 494 [asnSequence \ 495 [asnChoice 0 [ldap::filter::AssertionValue "Jane Random"]] \ 496 [asnChoice 1 [ldap::filter::AssertionValue and]] \ 497 [asnChoice 2 [ldap::filter::AssertionValue "J. Random Hacker"]]]]] 498 499test filter-10.0 {Extensible match: only attribute description} -body { 500 ldap::filter::encode (AttrDesc:=10) 501} -result [asnChoiceConstr 9 [glue \ 502 [asnChoice 2 [ldap::filter::LDAPString AttrDesc]] \ 503 [asnChoice 3 [ldap::filter::AssertionValue 10]]]] 504 505test filter-10.1 {Extensible match: attribute description + matching rule} -body { 506 ldap::filter::encode (personKind:caseIgnoreMatch:=bad) 507} -result [asnChoiceConstr 9 [glue \ 508 [asnChoice 1 [ldap::filter::LDAPString caseIgnoreMatch]] \ 509 [asnChoice 2 [ldap::filter::LDAPString personKind]] \ 510 [asnChoice 3 [ldap::filter::AssertionValue bad]]]] 511 512test filter-10.2 {Extensible match: attribute description 513 + matching rule in form of numericoid} -body { 514 ldap::filter::encode (personKind:1.3.6.1.4.1.1466.115.121.1.15:=good) 515} -result [asnChoiceConstr 9 [glue \ 516 [asnChoice 1 [ldap::filter::LDAPString 1.3.6.1.4.1.1466.115.121.1.15]] \ 517 [asnChoice 2 [ldap::filter::LDAPString personKind]] \ 518 [asnChoice 3 [ldap::filter::AssertionValue good]]]] 519 520test filter-10.3 {Extensible match: attribute description + DN flag} -body { 521 ldap::filter::encode (Foobar:dn:=345) 522} -result [asnChoiceConstr 9 [glue \ 523 [asnChoice 2 [ldap::filter::LDAPString Foobar]] \ 524 [asnChoice 3 [ldap::filter::AssertionValue 345]] \ 525 [asnChoice 4 [binary format cc 1 1]]]] 526 527test filter-10.4 {Extensible match: attribute description + DN flag + matching rule} -body { 528 ldap::filter::encode (NamelessOne:dn:caseIgnoreIA5Match:=who) 529} -result [asnChoiceConstr 9 [glue \ 530 [asnChoice 1 [ldap::filter::LDAPString caseIgnoreIA5Match]] \ 531 [asnChoice 2 [ldap::filter::LDAPString NamelessOne]] \ 532 [asnChoice 3 [ldap::filter::AssertionValue who]] \ 533 [asnChoice 4 [binary format cc 1 1]]]] 534 535test filter-10.5 {Extensible match: attribute description + DN flag 536 + matching rule numericoid} -body { 537 ldap::filter::encode (OU:dn:111.222.333.444:=test) 538} -result [asnChoiceConstr 9 [glue \ 539 [asnChoice 1 [ldap::filter::LDAPString 111.222.333.444]] \ 540 [asnChoice 2 [ldap::filter::LDAPString OU]] \ 541 [asnChoice 3 [ldap::filter::AssertionValue test]] \ 542 [asnChoice 4 [binary format cc 1 1]]]] 543 544test filter-10.6 {Extensible match: matching rule alone} -body { 545 ldap::filter::encode (:caseIgnoreIA5Match:=they) 546} -result [asnChoiceConstr 9 [glue \ 547 [asnChoice 1 [ldap::filter::LDAPString caseIgnoreIA5Match]] \ 548 [asnChoice 3 [ldap::filter::AssertionValue they]]]] 549 550test filter-10.7 {Extensible match: matching rule alone, in form of numericoid} -body { 551 ldap::filter::encode (:874.274.378.432:=value) 552} -result [asnChoiceConstr 9 [glue \ 553 [asnChoice 1 [ldap::filter::LDAPString 874.274.378.432]] \ 554 [asnChoice 3 [ldap::filter::AssertionValue value]]]] 555 556test filter-10.8 {Extensible match: matching rule + DN flag} -body { 557 ldap::filter::encode (:dn:caseIgnoreIA5Match:=they) 558} -result [asnChoiceConstr 9 [glue \ 559 [asnChoice 1 [ldap::filter::LDAPString caseIgnoreIA5Match]] \ 560 [asnChoice 3 [ldap::filter::AssertionValue they]] \ 561 [asnChoice 4 [binary format cc 1 1]]]] 562 563test filter-10.9 {Extensible match: matching rule (numericoid) + DN flag} -body { 564 ldap::filter::encode (:dn:111.222.333.444:=value) 565} -result [asnChoiceConstr 9 [glue \ 566 [asnChoice 1 [ldap::filter::LDAPString 111.222.333.444]] \ 567 [asnChoice 3 [ldap::filter::AssertionValue value]] \ 568 [asnChoice 4 [binary format cc 1 1]]]] 569 570test filter-10.10 {Extensible match: empty assertion value} -body { 571 ldap::filter::encode (AttrDesc:=) 572} -result [asnChoiceConstr 9 [glue \ 573 [asnChoice 2 [ldap::filter::LDAPString AttrDesc]] \ 574 [asnChoice 3 [ldap::filter::AssertionValue ""]]]] 575 576test filter-10.11 {Extensible match: empty assertion value, DN flag} -body { 577 ldap::filter::encode (AttrDesc:dn:=) 578} -result [asnChoiceConstr 9 [glue \ 579 [asnChoice 2 [ldap::filter::LDAPString AttrDesc]] \ 580 [asnChoice 3 [ldap::filter::AssertionValue ""]] \ 581 [asnChoice 4 [binary format cc 1 1]]]] 582 583test filter-10.11 {Extensible match: matching rule with empty assertion value} -body { 584 ldap::filter::encode (:caseIgnoreIA5Match:=) 585} -result [asnChoiceConstr 9 [glue \ 586 [asnChoice 1 [ldap::filter::LDAPString caseIgnoreIA5Match]] \ 587 [asnChoice 3 [ldap::filter::AssertionValue ""]]]] 588 589test filter-10.12 {Extensible match: empty LHS} -body { 590 ldap::filter::encode (:=foo) 591} -returnCodes error -result {Invalid filter: malformed attribute description} 592 593test filter-10.12 {Extensible match: empty DN flag or matching rule OID} -body { 594 ldap::filter::encode (attrDesc::=bar) 595} -returnCodes error -result {Invalid filter: malformed attribute description} 596 597test filter-10.12 {Extensible match: empty matching rule OID} -body { 598 ldap::filter::encode (attrDesc:dn::=baz) 599} -returnCodes error -result {Invalid filter: malformed attribute description} 600 601test filter-10.13 {Extensible match: empty DN flag} -body { 602 ldap::filter::encode (attrDesc::caseIgnoreMatch:=quux) 603} -returnCodes error -result {Invalid filter: malformed attribute description} 604 605test filter-10.14 {Extensible match: empty DN flag} -body { 606 ldap::filter::encode (::caseIgnoreMatch:=foo) 607} -returnCodes error -result {Invalid filter: malformed attribute description} 608 609test filter-10.15 {Extensible match: empty matching rule OID} -body { 610 ldap::filter::encode (::=bar) 611} -returnCodes error -result {Invalid filter: malformed attribute description} 612 613test filter-10.16 {Extensible match: malformed matching rule numericoid} -body { 614 ldap::filter::encode (:111.222.333.xxx:=baz) 615} -returnCodes error -result {Invalid filter: malformed attribute description} 616 617test filter-10.17 {Extensible match: malformed matching rule numericoid} -body { 618 ldap::filter::encode (userCategory:111.222.333.444\;binary:=baz) 619} -returnCodes error -result {Invalid filter: malformed attribute description} 620 621test filter-10.18 {Extensible match: malformed matching rule numericoid} -body { 622 ldap::filter::encode (userCategory:dn:111.222.333.444\;x-bar:=foo) 623} -returnCodes error -result {Invalid filter: malformed attribute description} 624 625test filter-10.19 {Extensible match: malformed matching rule numericoid} -body { 626 ldap::filter::encode (:caseIgnoreIA5Match\;lang-ru:=quux) 627} -returnCodes error -result {Invalid filter: malformed attribute description} 628 629test filter-10.20 {Extensible match: camel-cased DN flag} -body { 630 ldap::filter::encode (attrDesc:Dn:caseIgnoreMatch:=quux) 631} -returnCodes error -result {Invalid filter: malformed attribute description} 632 633test filter-10.21 {Extensible match: prohibited character in attribute description} -body { 634 ldap::filter::encode (4cast:=foo) 635} -returnCodes error -result {Invalid filter: malformed attribute description} 636 637test filter-10.22 {Extensible match: gibberish in place of DN flag} -body { 638 ldap::filter::encode (OU:gibberish:caseIgnoreIA5Match:=bar) 639} -returnCodes error -result {Invalid filter: malformed attribute description} 640 641test filter-10.23 {Extensible match: options in attribute description} -body { 642 ldap::filter::encode (personAge\;lang-ru\;x-foo:numericMatch:=99) 643} -result [asnChoiceConstr 9 [glue \ 644 [asnChoice 1 [ldap::filter::LDAPString numericMatch]] \ 645 [asnChoice 2 [ldap::filter::LDAPString personAge\;lang-ru\;x-foo]] \ 646 [asnChoice 3 [ldap::filter::AssertionValue 99]]]] 647 648test filter-10.24 {Extensible match: options in attribute description} -body { 649 ldap::filter::encode (111.222.333.444\;x-bar:dn:555.666.777.888:=foo) 650} -result [asnChoiceConstr 9 [glue \ 651 [asnChoice 1 [ldap::filter::LDAPString 555.666.777.888]] \ 652 [asnChoice 2 [ldap::filter::LDAPString 111.222.333.444\;x-bar]] \ 653 [asnChoice 3 [ldap::filter::AssertionValue foo]] \ 654 [asnChoice 4 [binary format cc 1 1]]]] 655 656test filter-11.1 {Prohibited characters in argument value} -body { 657 ldap::filter::encode (foo=bar(and)baz) 658} -returnCodes error -result {Invalid filter: malformed assertion value} 659 660test filter-11.2 {Prohibited characters in argument value} -body { 661 ldap::filter::encode (zero=lurks\0here) 662} -returnCodes error -result {Invalid filter: malformed assertion value} 663 664test filter-11.3 {Prohibited characters in argument value} -body { 665 ldap::filter::encode (extensible:=asterisk*) 666} -returnCodes error -result {Invalid filter: malformed assertion value} 667 668test filter-12.0 {Malformed attribute description: empty} -body { 669 ldap::filter::encode (=foo) 670} -returnCodes error -result {Invalid filter: malformed attribute description} 671 672test filter-12.1 {Malformed attribute description: doesn't start with a letter} -body { 673 ldap::filter::encode (2forTheRoad=bar) 674} -returnCodes error -result {Invalid filter: malformed attribute description} 675 676test filter-12.2 {Malformed attribute description: mix of descr and numericoid} -body { 677 ldap::filter::encode (foo.12.13=bar) 678} -returnCodes error -result {Invalid filter: malformed attribute description} 679 680test filter-12.3 {Malformed attribute description: bad numericoid} -body { 681 ldap::filter::encode (.11.12.13=bar) 682} -returnCodes error -result {Invalid filter: malformed attribute description} 683 684test filter-12.4 {Malformed attribute description: bad numericoid} -body { 685 ldap::filter::encode (11.12.13.=bar) 686} -returnCodes error -result {Invalid filter: malformed attribute description} 687 688test filter-12.5 {Malformed attribute description: prohibited character in descr} -body { 689 ldap::filter::encode (cn_2=bar) 690} -returnCodes error -result {Invalid filter: malformed attribute description} 691 692test filter-12.6 {Malformed attribute description: prohibited character in option} -body { 693 ldap::filter::encode (OU\;lang_en=bar) 694} -returnCodes error -result {Invalid filter: malformed attribute description} 695 696test filter-12.7 {Malformed attribute description: 697 colon in an LHS part of a rule which doesn't represent an extensible match} -body { 698 ldap::filter::encode (phoneNumber:dn=value) 699} -returnCodes error -result {Invalid filter: malformed attribute description} 700 701test filter-12.8 {Malformed attribute description: empty option} -body { 702 ldap::filter::encode (CN\;\;lang-ru=?) 703} -returnCodes error -result {Invalid filter: malformed attribute description} 704 705test filter-13.1 {Malformed assertion value: prohibited characters} -body { 706 ldap::filter::encode (foo<=*) 707} -returnCodes error -result {Invalid filter: malformed assertion value} 708 709test filter-13.2 {Malformed assertion value: prohibited characters} -body { 710 ldap::filter::encode (foo=() 711} -returnCodes error -result {Invalid filter: malformed assertion value} 712 713test filter-13.3 {Malformed assertion value: prohibited characters} -body { 714 ldap::filter::encode (foo=)) 715} -returnCodes error -result {Invalid filter: malformed assertion value} 716 717test filter-13.4 {Malformed assertion value: prohibited characters} -body { 718 ldap::filter::encode (foo=\\) 719} -returnCodes error -result {Invalid filter: malformed assertion value} 720 721test filter-13.5 {Malformed assertion value: prohibited characters} -body { 722 ldap::filter::encode (foo=\0) 723} -returnCodes error -result {Invalid filter: malformed assertion value} 724 725test filter-15.0 {No match rule operator} -body { 726 ldap::filter::encode () 727} -returnCodes error -result {Invalid filter: no match operator in item} 728 729test filter-15.1 {No match rule operator} -body { 730 ldap::filter::encode (11.12.14~value) 731} -returnCodes error -result {Invalid filter: no match operator in item} 732 733test filter-16.0 {Duplicated match rule operator} -body { 734 ldap::filter::encode (attrDesc=foo=bar) 735} -result [asnChoiceConstr 3 [glue \ 736 [asnOctetString [ldap::filter::LDAPString attrDesc]] \ 737 [asnOctetString [ldap::filter::AssertionValue foo=bar]]]] 738 739test filter-16.1 {Duplicated match rule operator} -body { 740 ldap::filter::encode (attrDesc~=foo~=) 741} -result [asnChoiceConstr 8 [glue \ 742 [asnOctetString [ldap::filter::LDAPString attrDesc]] \ 743 [asnOctetString [ldap::filter::AssertionValue foo~=]]]] 744 745test filter-16.2 {Duplicated match rule operator} -body { 746 ldap::filter::encode (attrDesc<=<=bar) 747} -result [asnChoiceConstr 6 [glue \ 748 [asnOctetString [ldap::filter::LDAPString attrDesc]] \ 749 [asnOctetString [ldap::filter::AssertionValue <=bar]]]] 750 751test filter-16.3 {Duplicated match rule operator} -body { 752 ldap::filter::encode (attrDesc>=>=>=) 753} -result [asnChoiceConstr 5 [glue \ 754 [asnOctetString [ldap::filter::LDAPString attrDesc]] \ 755 [asnOctetString [ldap::filter::AssertionValue >=>=]]]] 756 757test filter-16.4 {Duplicated match rule operator} -body { 758 ldap::filter::encode (AttrDesc:=:=what?:=) 759} -result [asnChoiceConstr 9 [glue \ 760 [asnChoice 2 [ldap::filter::LDAPString AttrDesc]] \ 761 [asnChoice 3 [ldap::filter::AssertionValue :=what?:=]]]] 762 763test filter-17.0 {Compound filters: negation} -body { 764 ldap::filter::encode (!(foo=bar)) 765} -result [asnChoiceConstr 2 [asnChoiceConstr 3 [glue \ 766 [asnOctetString [ldap::filter::LDAPString foo]] \ 767 [asnOctetString [ldap::filter::AssertionValue bar]]]]] 768 769test filter-17.1 {Compound filters: AND} -body { 770 ldap::filter::encode (&(one=two)(three<=four)(five>=six)) 771} -result [asnChoiceConstr 0 [glue \ 772 [asnChoiceConstr 3 [glue \ 773 [asnOctetString [ldap::filter::LDAPString one]] \ 774 [asnOctetString [ldap::filter::AssertionValue two]]]] \ 775 [asnChoiceConstr 6 [glue \ 776 [asnOctetString [ldap::filter::LDAPString three]] \ 777 [asnOctetString [ldap::filter::AssertionValue four]]]] \ 778 [asnChoiceConstr 5 [glue \ 779 [asnOctetString [ldap::filter::LDAPString five]] \ 780 [asnOctetString [ldap::filter::AssertionValue six]]]]]] 781 782test filter-17.2 {Compound filters: OR} -body { 783 ldap::filter::encode (|(foo=bar)(baz:fuzzyMatch:=quux)(key~=value)) 784} -result [asnChoiceConstr 1 [glue \ 785 [asnChoiceConstr 3 [glue \ 786 [asnOctetString [ldap::filter::LDAPString foo]] \ 787 [asnOctetString [ldap::filter::AssertionValue bar]]]] \ 788 [asnChoiceConstr 9 [glue \ 789 [asnChoice 1 [ldap::filter::LDAPString fuzzyMatch]] \ 790 [asnChoice 2 [ldap::filter::LDAPString baz]] \ 791 [asnChoice 3 [ldap::filter::AssertionValue quux]]]] \ 792 [asnChoiceConstr 8 [glue \ 793 [asnOctetString [ldap::filter::LDAPString key]] \ 794 [asnOctetString [ldap::filter::AssertionValue value]]]]]] 795 796test filter-17.3 {Compound filters: AND, spaces in assertion values} -body { 797 ldap::filter::encode {(&(OU=Research & Development)(DN=Rube Goldberg))} 798} -result [asnChoiceConstr 0 [glue \ 799 [asnChoiceConstr 3 [glue \ 800 [asnOctetString [ldap::filter::LDAPString OU]] \ 801 [asnOctetString [ldap::filter::AssertionValue "Research & Development"]]]] \ 802 [asnChoiceConstr 3 [glue \ 803 [asnOctetString [ldap::filter::LDAPString DN]] \ 804 [asnOctetString [ldap::filter::AssertionValue "Rube Goldberg"]]]]]] 805 806test filter-18.1 {Compound filters: unbalanced parenthesis} -body { 807 ldap::filter::encode (&(foo=bar)(baz=quux) 808} -returnCodes error -result {Invalid filter: unbalanced parenthesis} 809 810test filter-18.2 {Compound filters: unbalanced parenthesis} -body { 811 ldap::filter::encode (!(&(a=b)c=d)) 812} -returnCodes error -result {Invalid filter: malformed compound filter expression} 813 814test filter-18.2 {Compound filters: unbalanced parenthesis} -body { 815 ldap::filter::encode (!(&(a=b)))c=d)) 816} -returnCodes error -result {Invalid filter: malformed compound filter expression} 817 818test filter-18.3 {Compound filters: unbalanced parenthesis} -body { 819 ldap::filter::encode (!() 820} -returnCodes error -result {Invalid filter:\ 821 filter expression must be surrounded by parentheses} 822 823test filter-19.1 {Compound filters: junk in expression} -body { 824 ldap::filter::encode {(& (foo=bar)(baz=quux))} 825} -returnCodes error -result {Invalid filter: malformed compound filter expression} 826 827test filter-19.2 {Compound filters: junk in expression} -body { 828 ldap::filter::encode {(&(foo=bar) (baz=quux))} 829} -returnCodes error -result {Invalid filter: malformed compound filter expression} 830 831test filter-19.3 {Compound filters: junk in expression} -body { 832 ldap::filter::encode {(|(foo=bar)(baz=quux) )} 833} -returnCodes error -result {Invalid filter: malformed compound filter expression} 834 835test filter-19.3 {Compound filters: junk in expression} -body { 836 ldap::filter::encode {(&&(foo=bar)(baz=quux))} 837} -returnCodes error -result {Invalid filter: malformed compound filter expression} 838 839test filter-19.4 {Compound filters: junk in expression} -body { 840 ldap::filter::encode {((foo=bar)&(baz=quux))} 841} -returnCodes error -match glob -result {Invalid filter: malformed attribute *} 842 843test filter-20.0 {Missing elements in filter composition} -body { 844 ldap::filter::encode (!) 845} -returnCodes error -result {Invalid filter:\ 846 filter expression must be surrounded by parentheses} 847 848test filter-20.1 {Missing elements in filter composition} -body { 849 ldap::filter::encode (&) 850} -returnCodes error -result {Invalid filter: malformed compound filter expression} 851 852test filter-20.2 {Missing elements in filter composition} -body { 853 ldap::filter::encode (|) 854} -returnCodes error -result {Invalid filter: malformed compound filter expression} 855 856test filter-21.0 {Torture test} -body { 857 ldap::filter::encode [regsub -all \\s+ { 858 (| 859 (& 860 (userName=Jane\20Random\00) 861 (userCategory;x-lang-ru~=human) 862 ) 863 (! 864 (| 865 (! 866 (salary=*) 867 ) 868 (& 869 (personAge>=80) 870 (yearsEmployed<=70) 871 (employeeName=Joe*a**nd**Hacker) 872 ) 873 ) 874 ) 875 (| 876 (11.22.33.44;x-files:dn:=value) 877 (:567.34.56:=\28\2a\29) 878 ) 879 (foo=bar) 880 ) 881 } ""] 882} -result [asnChoiceConstr 1 [glue \ 883 [asnChoiceConstr 0 [glue \ 884 [asnChoiceConstr 3 [glue \ 885 [asnOctetString [ldap::filter::LDAPString userName]] \ 886 [asnOctetString [encoding convertto utf-8 "Jane Random\0"]]]] \ 887 [asnChoiceConstr 8 [glue \ 888 [asnOctetString [ldap::filter::LDAPString userCategory\;x-lang-ru]] \ 889 [asnOctetString [ldap::filter::AssertionValue human]]]]]] \ 890 [asnChoiceConstr 2 \ 891 [asnChoiceConstr 1 [glue \ 892 [asnChoiceConstr 2 \ 893 [asnChoice 7 [ldap::filter::LDAPString salary]]] \ 894 [asnChoiceConstr 0 [glue \ 895 [asnChoiceConstr 5 [glue \ 896 [asnOctetString [ldap::filter::LDAPString personAge]] \ 897 [asnOctetString [ldap::filter::AssertionValue 80]]]] \ 898 [asnChoiceConstr 6 [glue \ 899 [asnOctetString [ldap::filter::LDAPString yearsEmployed]] \ 900 [asnOctetString [ldap::filter::AssertionValue 70]]]] \ 901 [asnChoiceConstr 4 [glue \ 902 [asnOctetString [ldap::filter::LDAPString employeeName]] \ 903 [asnSequence [glue \ 904 [asnChoice 0 [ldap::filter::AssertionValue Joe]] \ 905 [asnChoice 1 [ldap::filter::AssertionValue a]] \ 906 [asnChoice 1 [ldap::filter::AssertionValue nd]] \ 907 [asnChoice 2 [ldap::filter::AssertionValue Hacker]]]]]]]]]]] \ 908 [asnChoiceConstr 1 [glue \ 909 [asnChoiceConstr 9 [glue \ 910 [asnChoice 2 [ldap::filter::LDAPString 11.22.33.44\;x-files]] \ 911 [asnChoice 3 [ldap::filter::AssertionValue value]] \ 912 [asnChoice 4 [binary format cc 1 1]]]] \ 913 [asnChoiceConstr 9 [glue \ 914 [asnChoice 1 [ldap::filter::LDAPString 567.34.56]] \ 915 [asnChoice 3 [encoding convertto utf-8 (*)]]]]]] \ 916 [asnChoiceConstr 3 [glue \ 917 [asnOctetString [ldap::filter::LDAPString foo]] \ 918 [asnOctetString [ldap::filter::AssertionValue bar]]]] \ 919 ]] 920 921# ------------------------------------------------------------------------- 922testsuiteCleanup 923 924# Local Variables: 925# mode: tcl 926# indent-tabs-mode: nil 927# End: 928# vim:ts=8:sw=4:sts=4:noet:syntax=tcl 929