1#compdef ldap
2
3local -a commands scopes
4commands=(
5  search:'search a directory'
6)
7scopes=(
8  base:'base object only'
9  one:'one level'
10  sub:subtree
11)
12
13_ldap_url() {
14  local nm=$compstate[nmatches]
15  local -a expl protocols suf_proto suf_scope tags
16  protocols=(
17    ldap:'TCP in plaintext'
18    ldaps:'TLS'
19    ldap+tls:'TCP and use StartTLS'
20    ldapi:'connect to a socket'
21  )
22
23  # [protocol://]host[:port][/basedn[?[attribute,...][?[scope][?[filter]]]]]
24  if ! compset -P '*://'; then
25    tags=(protocol)
26    compset -S ':*' || suf_proto=( -S :// )
27  fi
28
29  if ! compset -P '*/'; then
30    if compset -P '*:'; then
31      tags=(port)
32      compset -S '/*'
33    else
34      if ! compset -S '://*'; then
35        tags+=(host)
36        compset -S '[:/]*'
37      fi
38    fi
39  else
40    case $PREFIX in
41      *\?*\?*\?*) tags=(filter);;
42      *\?*\?*) tags=(scope); [[ -suffix \?* ]] || suf_scope=( -qS \? );;
43      *\?*) tags=(attribute);;
44      *) tags=(basedn);;
45    esac
46    compset -P '*\?'
47    compset -S '\?*'
48  fi
49
50  _tags $tags
51  while _tags; do
52    _requested protocol && _describe -t protocol protocol protocols $suf_proto
53    _requested host && _hosts -S ''
54    _requested port expl port
55    _requested basedn expl 'base DN'
56    _requested attribute expl attribute
57    _requested scope && _describe -t scope scope scopes $suf_scope
58    _requested filter expl filter
59    [[ nm -ne compstate[nmatches] ]] && return 0
60  done
61}
62
63if (( CURRENT == 2 )); then
64  _describe command commands
65else
66  shift words; (( CURRENT-- ))
67  case $words[1] in
68    search)
69      _arguments -s -S -A '-*' \
70        '-b+[specify base DN]:base DN:' \
71        '-c+[specify CA file]:CA file:' \
72        '-D+[specify bind DN]:bind DN:' \
73        '-H+[specify URL]: :_ldap_url' \
74        '-L[output in LDIF]' \
75        '-l+[specify time limit or 0 for no limit]:time limit [0]:' \
76        '-s+[specify scope]:scope [sub]:(($scopes))' \
77        '-v[be verbose]' \
78        '-W[prompt for bind secret]' \
79        '-w+[specify bind secret]:bind secret:' \
80        '-x[use simple authentication]' \
81        '-Z[use StartTLS]' \
82        '-z+[specify maximum number of results or 0 for no limit]:size limit [0]:' \
83        '::filter:' \
84        '*:attribute:'
85      ;;
86  esac
87fi
88