import sys, string import pythoncom import win32api from win32com.adsi import * verbose_level = 0 server = '' # Must have trailing / local_name = win32api.GetComputerName() def DumpRoot(): "Dumps the root DSE" path = "LDAP://%srootDSE" % server rootdse = ADsGetObject(path) for item in rootdse.Get("SupportedLDAPVersion"): print "%s supports ldap version %s" % (path, item) attributes = ["CurrentTime", "defaultNamingContext"] for attr in attributes: val = rootdse.Get(attr) print " %s=%s" % (attr, val) ############################################### # # Code taken from article titled: # Reading attributeSchema and classSchema Objects def _DumpClass(child): attrs = "Abstract lDAPDisplayName schemaIDGUID schemaNamingContext attributeSyntax oMSyntax" _DumpTheseAttributes(child, string.split(attrs)) def _DumpAttribute(child): attrs = "lDAPDisplayName schemaIDGUID adminDescription adminDisplayName rDNAttID defaultHidingValue defaultObjectCategory systemOnly defaultSecurityDescriptor" _DumpTheseAttributes(child, string.split(attrs)) def _DumpTheseAttributes(child, attrs): for attr in attrs: try: val = child.Get(attr) except pythoncom.com_error, details: continue # ### (hr, msg, exc, arg) = details if exc and exc[2]: msg = exc[2] val = "" % (msg,) if verbose_level >= 2: print " %s: %s=%s" % (child.Class, attr, val) def DumpSchema(): "Dumps the default DSE schema" # Bind to rootDSE to get the schemaNamingContext property. path = "LDAP://%srootDSE" % server rootdse = ADsGetObject(path) name = rootdse.Get("schemaNamingContext") # Bind to the actual schema container. path= "LDAP://" + server + name print "Binding to", path ob = ADsGetObject(path) nclasses = nattr = nsub = nunk = 0 # Enumerate the attribute and class objects in the schema container. for child in ob: # Find out if this is a class, attribute, or subSchema object. class_name = child.Class if class_name == "classSchema": _DumpClass(child) nclasses = nclasses + 1 elif class_name == "attributeSchema": _DumpAttribute(child) nattr = nattr + 1 elif class_name == "subSchema": nsub = nsub + 1 else: print "Unknown class:", class_name nunk = nunk + 1 if verbose_level: print "Processed", nclasses, "classes" print "Processed", nattr, "attributes" print "Processed", nsub, "sub-schema's" print "Processed", nunk, "unknown types" def _DumpObject(ob, level = 0): prefix = " " * level print "%s%s object: %s" % (prefix, ob.Class, ob.Name) # Do the directory object thing try: dir_ob = ADsGetObject(ob.ADsPath, IID_IDirectoryObject) except pythoncom.com_error: dir_ob = None if dir_ob is not None: info = dir_ob.GetObjectInformation() print "%s RDN='%s', ObjectDN='%s'" % (prefix, info.RDN, info.ObjectDN) # Create a list of names to fetch names = ["distinguishedName"] attrs = dir_ob.GetObjectAttributes(names) for attr in attrs: for val, typ in attr.Values: print "%s Attribute '%s' = %s" % (prefix, attr.AttrName, val) for child in ob: _DumpObject(child, level+1) def DumpAllObjects(): "Recursively dump the entire directory!" path = "LDAP://%srootDSE" % server rootdse = ADsGetObject(path) name = rootdse.Get("defaultNamingContext") # Bind to the actual schema container. path= "LDAP://" + server + name print "Binding to", path ob = ADsGetObject(path) # Enumerate the attribute and class objects in the schema container. _DumpObject(ob) ########################################################## # # Code taken from article: # Example Code for Enumerating Schema Classes, Attributes, and Syntaxes # Fill a map with VT_ datatypes, to give us better names: vt_map = {} for name, val in pythoncom.__dict__.iteritems(): if name[:3] == "VT_": vt_map[val] = name def DumpSchema2(): "Dumps the schema using an alternative technique" path = "LDAP://%sschema" % (server,) schema = ADsGetObject(path, IID_IADsContainer) nclass = nprop = nsyntax = 0 for item in schema: item_class = string.lower(item.Class) if item_class == "class": items = [] if item.Abstract: items.append("Abstract") if item.Auxiliary: items.append("Auxiliary") # if item.Structural: items.append("Structural") desc = string.join(items, ", ") import win32com.util iid_name = win32com.util.IIDToInterfaceName(item.PrimaryInterface) if verbose_level >= 2: print "Class: Name=%s, Flags=%s, Primary Interface=%s" % (item.Name, desc, iid_name) nclass = nclass + 1 elif item_class == "property": if item.MultiValued: val_type = "Multi-Valued" else: val_type = "Single-Valued" if verbose_level >= 2: print "Property: Name=%s, %s" % (item.Name, val_type) nprop = nprop + 1 elif item_class == "syntax": data_type = vt_map.get(item.OleAutoDataType, "") if verbose_level >= 2: print "Syntax: Name=%s, Datatype = %s" % (item.Name, data_type) nsyntax = nsyntax + 1 if verbose_level >= 1: print "Processed", nclass, "classes" print "Processed", nprop, "properties" print "Processed", nsyntax, "syntax items" def DumpGC(): "Dumps the GC: object (whatever that is!)" ob = ADsGetObject("GC:", IID_IADsContainer) for sub_ob in ob: print "GC ob: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath) def DumpLocalUsers(): "Dumps the local machine users" path = "WinNT://%s,computer" % (local_name,) ob = ADsGetObject(path, IID_IADsContainer) ob.put_Filter(["User", "Group"]) for sub_ob in ob: print "User/Group: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath) def DumpLocalGroups(): "Dumps the local machine groups" path = "WinNT://%s,computer" % (local_name,) ob = ADsGetObject(path, IID_IADsContainer) ob.put_Filter(["Group"]) for sub_ob in ob: print "Group: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath) # get the members members = sub_ob.Members() for member in members: print " Group member: %s (%s)" % (member.Name, member.ADsPath) def usage(tests): import os print "Usage: %s [-s server ] [-v] [Test ...]" % os.path.basename(sys.argv[0]) print " -v : Verbose - print more information" print " -s : server - execute the tests against the named server" print "where Test is one of:" for t in tests: print t.__name__,":", t.__doc__ print print "If not tests are specified, all tests are run" sys.exit(1) def main(): import getopt, traceback tests = [] for ob in globals().itervalues(): if type(ob)==type(main) and ob.__doc__: tests.append(ob) opts, args = getopt.getopt(sys.argv[1:], "s:hv") for opt, val in opts: if opt=="-s": if val[-1] not in "\\/": val = val + "/" global server server = val if opt=="-h": usage(tests) if opt=="-v": global verbose_level verbose_level = verbose_level + 1 if len(args)==0: print "Running all tests - use '-h' to see command-line options..." dotests = tests else: dotests = [] for arg in args: for t in tests: if t.__name__==arg: dotests.append(t) break else: print "Test '%s' unknown - skipping" % arg if not len(dotests): print "Nothing to do!" usage(tests) for test in dotests: try: test() except: print "Test %s failed" % test.__name__ traceback.print_exc() if __name__=='__main__': main()