aboutsummaryrefslogtreecommitdiff
path: root/goldap/search_request.go
diff options
context:
space:
mode:
Diffstat (limited to 'goldap/search_request.go')
-rw-r--r--goldap/search_request.go246
1 files changed, 246 insertions, 0 deletions
diff --git a/goldap/search_request.go b/goldap/search_request.go
new file mode 100644
index 0000000..9d84f23
--- /dev/null
+++ b/goldap/search_request.go
@@ -0,0 +1,246 @@
+package message
+
+import (
+ "errors"
+ "fmt"
+)
+
+//
+// SearchRequest ::= [APPLICATION 3] SEQUENCE {
+// baseObject LDAPDN,
+// scope ENUMERATED {
+// baseObject (0),
+// singleLevel (1),
+// wholeSubtree (2),
+// ... },
+// derefAliases ENUMERATED {
+// neverDerefAliases (0),
+// derefInSearching (1),
+// derefFindingBaseObj (2),
+// derefAlways (3) },
+// sizeLimit INTEGER (0 .. maxInt),
+// timeLimit INTEGER (0 .. maxInt),
+// typesOnly BOOLEAN,
+// filter Filter,
+// attributes AttributeSelection }
+func readSearchRequest(bytes *Bytes) (searchrequest SearchRequest, err error) {
+ err = bytes.ReadSubBytes(classApplication, TagSearchRequest, searchrequest.readComponents)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readSearchRequest:\n%s", err.Error())}
+ return
+ }
+ return
+}
+func (searchrequest *SearchRequest) readComponents(bytes *Bytes) (err error) {
+ searchrequest.baseObject, err = readLDAPDN(bytes)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.scope, err = readENUMERATED(bytes, EnumeratedSearchRequestScope)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.derefAliases, err = readENUMERATED(bytes, EnumeratedSearchRequestDerefAliases)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.sizeLimit, err = readPositiveINTEGER(bytes)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.timeLimit, err = readPositiveINTEGER(bytes)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.typesOnly, err = readBOOLEAN(bytes)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.filter, err = readFilter(bytes)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ searchrequest.attributes, err = readAttributeSelection(bytes)
+ if err != nil {
+ err = LdapError{fmt.Sprintf("readComponents:\n%s", err.Error())}
+ return
+ }
+ return
+}
+
+//
+// SearchRequest ::= [APPLICATION 3] SEQUENCE {
+// baseObject LDAPDN,
+// scope ENUMERATED {
+// baseObject (0),
+// singleLevel (1),
+// wholeSubtree (2),
+// ... },
+// derefAliases ENUMERATED {
+// neverDerefAliases (0),
+// derefInSearching (1),
+// derefFindingBaseObj (2),
+// derefAlways (3) },
+// sizeLimit INTEGER (0 .. maxInt),
+// timeLimit INTEGER (0 .. maxInt),
+// typesOnly BOOLEAN,
+// filter Filter,
+// attributes AttributeSelection }
+func (s SearchRequest) write(bytes *Bytes) (size int) {
+ size += s.attributes.write(bytes)
+ size += s.filter.write(bytes)
+ size += s.typesOnly.write(bytes)
+ size += s.timeLimit.write(bytes)
+ size += s.sizeLimit.write(bytes)
+ size += s.derefAliases.write(bytes)
+ size += s.scope.write(bytes)
+ size += s.baseObject.write(bytes)
+ size += bytes.WriteTagAndLength(classApplication, isCompound, TagSearchRequest, size)
+ return
+}
+
+//
+// SearchRequest ::= [APPLICATION 3] SEQUENCE {
+// baseObject LDAPDN,
+// scope ENUMERATED {
+// baseObject (0),
+// singleLevel (1),
+// wholeSubtree (2),
+// ... },
+// derefAliases ENUMERATED {
+// neverDerefAliases (0),
+// derefInSearching (1),
+// derefFindingBaseObj (2),
+// derefAlways (3) },
+// sizeLimit INTEGER (0 .. maxInt),
+// timeLimit INTEGER (0 .. maxInt),
+// typesOnly BOOLEAN,
+// filter Filter,
+// attributes AttributeSelection }
+func (s SearchRequest) size() (size int) {
+ size += s.baseObject.size()
+ size += s.scope.size()
+ size += s.derefAliases.size()
+ size += s.sizeLimit.size()
+ size += s.timeLimit.size()
+ size += s.typesOnly.size()
+ size += s.filter.size()
+ size += s.attributes.size()
+ size += sizeTagAndLength(TagSearchRequest, size)
+ return
+}
+func (s *SearchRequest) BaseObject() LDAPDN {
+ return s.baseObject
+}
+func (s *SearchRequest) Scope() ENUMERATED {
+ return s.scope
+}
+func (s *SearchRequest) DerefAliases() ENUMERATED {
+ return s.derefAliases
+}
+func (s *SearchRequest) SizeLimit() INTEGER {
+ return s.sizeLimit
+}
+func (s *SearchRequest) TimeLimit() INTEGER {
+ return s.timeLimit
+}
+func (s *SearchRequest) TypesOnly() BOOLEAN {
+ return s.typesOnly
+}
+func (s *SearchRequest) Attributes() AttributeSelection {
+ return s.attributes
+}
+func (s *SearchRequest) Filter() Filter {
+ return s.filter
+}
+func (s *SearchRequest) FilterString() string {
+ str, _ := s.decompileFilter(s.Filter())
+ return str
+}
+func (s *SearchRequest) decompileFilter(packet Filter) (ret string, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = errors.New("error decompiling filter")
+ }
+ }()
+
+ ret = "("
+ err = nil
+ childStr := ""
+
+ switch f := packet.(type) {
+ case FilterAnd:
+ ret += "&"
+ for _, child := range f {
+ childStr, err = s.decompileFilter(child)
+ if err != nil {
+ return
+ }
+ ret += childStr
+ }
+ case FilterOr:
+ ret += "|"
+ for _, child := range f {
+ childStr, err = s.decompileFilter(child)
+ if err != nil {
+ return
+ }
+ ret += childStr
+ }
+ case FilterNot:
+ ret += "!"
+ childStr, err = s.decompileFilter(f.Filter)
+ if err != nil {
+ return
+ }
+ ret += childStr
+
+ case FilterSubstrings:
+ ret += string(f.Type_())
+ ret += "="
+ for _, fs := range f.Substrings() {
+ switch fsv := fs.(type) {
+ case SubstringInitial:
+ ret += string(fsv) + "*"
+ case SubstringAny:
+ ret += "*" + string(fsv) + "*"
+ case SubstringFinal:
+ ret += "*" + string(fsv)
+ }
+ }
+ case FilterEqualityMatch:
+ ret += string(f.AttributeDesc())
+ ret += "="
+ ret += string(f.AssertionValue())
+ case FilterGreaterOrEqual:
+ ret += string(f.AttributeDesc())
+ ret += ">="
+ ret += string(f.AssertionValue())
+ case FilterLessOrEqual:
+ ret += string(f.AttributeDesc())
+ ret += "<="
+ ret += string(f.AssertionValue())
+ case FilterPresent:
+ // if 0 == len(packet.Children) {
+ // ret += ber.DecodeString(packet.Data.Bytes())
+ // } else {
+ // ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ // }
+ ret += string(f)
+ ret += "=*"
+ case FilterApproxMatch:
+ ret += string(f.AttributeDesc())
+ ret += "~="
+ ret += string(f.AssertionValue())
+ }
+
+ ret += ")"
+ return
+}