#!/usr/bin/env python

import sys
import ldap

base = ""
scope = ldap.SCOPE_BASE
filter = "(objectClass=*)"
attrs = ['supportedExtension','supportedControl','supportedCapabilities','supportedFeatures']

mech = {}
controls = {}
extensions = {}
capabilities = {}
features = {}

extensions['1.3.6.1.1.8'] = 'Cancel Operation'
extensions['1.3.6.1.4.1.1466.101.119.1'] = 'Dynamic Refresh'
extensions['1.3.6.1.4.1.4203.1.11.1'] = 'Modify Password'
extensions['1.3.6.1.4.1.1466.20037'] = 'Start TLS' 
extensions['1.3.6.1.4.1.4203.1.11.1'] = 'Modify Password'
extensions['1.3.6.1.4.1.4203.1.11.3'] = 'Who am I?'

features['1.3.6.1.1.14'] = 'Modify-Increment'
features['1.3.6.1.4.1.4203.1.5.1'] = 'All Op Attrs' 
features['1.3.6.1.4.1.4203.1.5.2'] = 'OC AD Lists'
features['1.3.6.1.4.1.4203.1.5.3'] = 'True/False filters'
features['1.3.6.1.4.1.4203.1.5.4'] = 'Language Tag Options' 
features['1.3.6.1.4.1.4203.1.5.5'] = 'Language Range Options'

capabilities['1.2.840.113556.1.4.800'] = 'LDAP Capabilities Active Directory' 
capabilities['1.2.840.113556.1.4.1791'] = 'LDAP Capabilities Active Directory LDAP Integration'

controls['1.2.826.0.1.3344810.2.3'] = 'Matched Values Control' 
controls['1.2.840.113556.1.4.319'] = 'Paged Results Control'
controls['1.2.840.113556.1.4.417'] = 'LDAP Server Show Deleted'
controls['1.2.840.113556.1.4.473'] = 'LDAP Server Sort Result'
controls['1.2.840.113556.1.4.474'] = 'Sort Response'
controls['1.2.840.113556.1.4.521'] = 'LDAP Server Cross Domain Move Target'
controls['1.2.840.113556.1.4.528'] = 'LDAP Server Notification'
controls['1.2.840.113556.1.4.529'] = 'LDAP Server Extended DN'
controls['1.2.840.113556.1.4.619'] = 'LDAP Server Lazy Commit'
controls['1.2.840.113556.1.4.801'] = 'LDAP Server Security Descriptor Flags'
controls['1.2.840.113556.1.4.805'] = 'LDAP Server Tree Delete'
controls['1.2.840.113556.1.4.841'] = 'LDAP Server DirSync'
controls['1.2.840.113556.1.4.970'] = 'LDAP Server Query Time Statistics'
controls['1.2.840.113556.1.4.1338'] = 'LDAP Server Verify name'
controls['1.2.840.113556.1.4.1339'] = 'LDAP Server Domain Scope'
controls['1.2.840.113556.1.4.1340'] = 'LDAP Server Search Options'
controls['1.2.840.113556.1.4.1413'] = 'LDAP Server Permissive Modify'
controls['1.3.6.1.1.7.1'] = 'LCUP Sync Request Control'
controls['1.3.6.1.1.7.2'] = 'LCUP Sync Update Control'
controls['1.3.6.1.1.7.3'] = 'LCUP Sync Done Control'
controls['1.3.6.1.1.12'] = 'Assertion Control' 
controls['1.3.6.1.1.13.1'] = 'LDAP Pre-read Control'
controls['1.3.6.1.1.13.2'] = 'LDAP Post-read Control'
controls['1.3.6.1.4.1.42.2.27.8.5.1'] = 'Password Policy Request/Response Control' 
controls['1.3.6.1.4.1.42.2.27.9.5.2'] = 'Get Effective Rights Request Control'
controls['1.3.6.1.4.1.1466.29539.12'] = 'LDAP Server Chaining Loop Detection'
controls['1.3.6.1.4.1.4203.1.9.1.1'] = 'LDAP Content Synchronization Control'
controls['1.3.6.1.4.1.4203.1.10.1'] = 'Subentries'
controls['2.16.840.1.113730.3.4.2'] = 'Manage DSA IT LDAPv3 Control'
controls['2.16.840.1.113730.3.4.3'] = 'Persistent Search LDAPv3 Control'
controls['2.16.840.1.113730.3.4.4'] = 'Netscape Password Expired LDAPv3 Control'
controls['2.16.840.1.113730.3.4.5'] = 'Netscape Password Expiring LDAPv3 Control'
controls['2.16.840.1.113730.3.4.9'] = 'VLV Request LDAPv3 Control' 
controls['2.16.840.1.113730.3.4.12'] = 'Proxied Authorization (version 1) Control'
controls['2.16.840.1.113730.3.4.13'] = 'iPlanet Directory Server Replication Update Information Control'
controls['2.16.840.1.113730.3.4.14'] = 'iPlanet Directory Server "search on specific backend" Control'
controls['2.16.840.1.113730.3.4.15'] = 'Authorization Identity Response Control' 
controls['2.16.840.1.113730.3.4.16'] = 'Authorization Identity Request Control'
controls['2.16.840.1.113730.3.4.17'] = 'Real Attributes Only Request Control'
controls['2.16.840.1.113730.3.4.18'] = 'Proxied Authorization (version 2) Control'
controls['2.16.840.1.113730.3.4.19'] = 'Virtual Attributes Only Request Control' 
controls['2.16.840.1.113730.3.4.20'] = 'Use One Backend'
controls['1.2.826.0.1.334810.2.3'] = 'Values return-filter'

mech['supportedExtension'] = extensions
mech['supportedControl'] = controls
mech['supportedCapabilities'] = capabilities
mech['supportedFeatures'] = features

def usage():
    print "Usage:"
    print sys.argv[0], "<ldap-url>"
    print sys.argv[0], "--help   (this page)"
    print "Example: " , sys.argv[0] , " ldap://remotehost.domain.com" 
    print ""
    print "Written in 2005, by Bjorn Ove Grotan <bgrotan@grotan.com."
    print "Rewritten from perl-script get_capabilities by Mike Jackson  <mj@sci.fi>"

def main(uri):
    print "Server: " + uri
    l = ldap.initialize(uri)
    l.simple_bind_s("","")
    res = l.search_s(base,scope,filter,attrs)
    supported = res[0][1]
    for s in attrs:
        print s + " :"
        try:
            for mechanism in supported[s]:
                try:
                    print "\t",mech[s][mechanism]
                except:
                    print "\t",mechanism
        except:
            print "\tNot found"

if __name__=='__main__':
    args = sys.argv
    if (len(args) == 1):
        usage()
        sys.exit()
    if ('--help' in args):
        usage()
        sys.exit()
    main(args[1])
    sys.exit()
