def _init_schema(cls): schema = _get_schema() s = Schema() # Follow all of the LDAP SUP entries to find all attributes. def collect_classes(schema, object_class, result): for sup_name in object_class.sup: sup_class = schema.get_obj(ldap.schema.ObjectClass, sup_name) collect_classes(schema, sup_class, result) result.append(object_class) for class_name in cls.objectClass: object_class = schema.get_obj(ldap.schema.ObjectClass, class_name) all_classes = [] collect_classes(schema, object_class, all_classes) for object_class in all_classes: for attr_name in object_class.must + object_class.may: attr = schema.get_obj(ldap.schema.AttributeType, attr_name) if 'objectClass' not in attr.names: s.attributes[attr.names[0]] = attr for name in attr.names: s.attribute_aliases[name] = attr setattr(cls, name, AttrDescriptor(attr)) # Beware that attributes of schema objects do not inherit # the settings of their superiors. single-value does not # appear to be an inherited value in openldap. # For now, objectClass is read-only, otherwise we would have to # dynamically update the descriptors. cls.objectClass = ReadOnlyDescriptor(cls.objectClass) cls._schema = s
def PrintSchemaTree(schema,se_class,se_tree,se_oid,level): """ASCII text output for console""" se_obj = schema.get_obj(se_class,se_oid) if se_obj!=None: print('| '*(level-1)+'+---'*(level>0), \) ', '.join(se_obj.names), \ '(%s)' % se_obj.oid
def backend_openldap_check_finished(*args, **kwargs): """ TODO: please implement http://dev.licorn.org/ticket/327 here. """ if settings.role != roles.SERVER: # Only servers will check / upgrade their local slapd installation. # On other roles, they have no local `slapd`, thus nothing to upgrade. return backend = LMC.backends.openldap ssse, schema = ldap.schema.urlfetch('ldapi:///') schema_attr = schema.get_obj(ldap.schema.AttributeType, 'gecos') if schema_attr.syntax == '1.3.6.1.4.1.1466.115.121.1.26': # The LDAP 'gecos' field is currently ascii only: we need to update the # schema to setup an utf8 field. See backends/openldap.py for more info. try: # we need to bind as root via SASL to replace a schema. backend.sasl_bind() backend.modify_schema('nis-utf8', batch=True, full_display=False) except: logging.exception(_(u'{0}: impossible to reload {1} schema ' u'into {2}!').format(backend.pretty_name, stylize(ST_NAME, 'nis'), stylize(ST_NAME, 'slapd'))) logging.notice(_(u'{0}: updated {1} schema to support utf-8 ' u'gecos.').format(backend.pretty_name, stylize(ST_NAME, 'nis')))
def needed_objectclasses(self, entry): dont_remove = ["organizationalPerson", "univentionPerson"] schema_attrs = ldap.schema.SCHEMA_ATTRS ldap.set_option(ldap.OPT_DEBUG_LEVEL, 0) ldap._trace_level = 0 subschemasubentry_dn, schema = ldap.schema.urlfetch("%s/cn=subschema", self.uri) if subschemasubentry_dn is None: univention.debug.debug(univention.debug.LDAP, univention.debug.INFO, "No sub schema sub entry found!") return None needed_oc = [] for attr_type, schema_class in ldap.schema.SCHEMA_CLASS_MAPPING.items(): if attr_type == "objectClasses": for element_id in schema.listall(schema_class): se_orig = schema.get_obj(schema_class, element_id) attributes = se_orig.may + se_orig.must for i in range(0, len(se_orig.names)): if se_orig.names[i] in entry["objectClass"] and not se_orig.names[i] in needed_oc: for j in attributes: if (j in res[0][1] or j in dont_remove) and not se_orig.names[i] in needed_oc: needed_oc.append(se_orig.names[i]) return needed_oc
def list_classes(uri): # pragma: nocover subschemasubentry_dn, schema = ldap.schema.urlfetch(uri.encode('ascii')) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) ocs = ldap.schema.SCHEMA_CLASS_MAPPING['objectclasses'] for element_id in schema.listall(ocs): obj = schema.get_obj(ocs, element_id) print("%s - %s" % (obj.names[0], obj.desc or "no description"))
def list_classes(uri): subschemasubentry_dn, schema = ldap.schema.urlfetch(uri) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) ocs = ldap.schema.SCHEMA_CLASS_MAPPING['objectclasses'] for element_id in schema.listall(ocs): obj = schema.get_obj(ocs, element_id) print("%s - %s" % (obj.names[0], obj.desc or "no description"))
def getAttrs(oc, attrs): """ recursive. returns all attributes for a objectClass object down the hierarchy """ attrs.extend(oc.may + oc.must) for oc_name in oc.sup: sup_oc = schema.get_obj(ldap.schema.ObjectClass, oc_name) getAttrs(sup_oc, attrs) return attrs
def PrintSchemaTree(schema,se_class,se_tree,se_oid,level): """ASCII text output for console""" se_obj = schema.get_obj(se_class,se_oid) if se_obj!=None: print ('| '*(level-1)+'+---'*(level>0), \ ', '.join(se_obj.names), \ '(%s)' % se_obj.oid) for sub_se_oid in se_tree[se_oid]: print ('| '*(level+1)) PrintSchemaTree(schema,se_class,se_tree,sub_se_oid,level+1)
def test_urlfetch_file(self): freeipa_uri = 'file://{}'.format(TEST_SUBSCHEMA_FILES[0]) dn, schema = ldap.schema.urlfetch(freeipa_uri) self.assertEqual(dn, 'cn=schema') self.assertIsInstance(schema, ldap.schema.subentry.SubSchema) obj = schema.get_obj(ObjectClass, '2.5.6.9') self.assertEqual( str(obj), "( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL MUST cn " "MAY ( member $ businessCategory $ seeAlso $ owner $ ou $ o " "$ description ) )")
def resolve_inherited_attrs(schema, oc): # pragma: nocover res = {'must': [], 'may': []} if oc == 'top': return res noc = schema.get_obj(ldap.schema.ObjectClass, oc) if noc.kind == 0: r = resolve_inherited_attrs(schema, noc.sup[0]) res['must'] += r['must'] res['may'] += r['may'] res['must'] += list(noc.must) res['may'] += list(noc.may) return res
def assertSlapdSchema(self, dn, schema): self.assertEqual(dn, 'cn=Subschema') self.assertIsInstance(schema, ldap.schema.subentry.SubSchema) obj = schema.get_obj(ObjectClass, '1.3.6.1.1.3.1') self.assertEqual( str(obj), "( 1.3.6.1.1.3.1 NAME 'uidObject' DESC 'RFC2377: uid object' " "SUP top AUXILIARY MUST uid )" ) entries = schema.ldap_entry() self.assertIsInstance(entries, dict) self.assertEqual(sorted(entries), [ 'attributeTypes', 'ldapSyntaxes', 'matchingRuleUse', 'matchingRules', 'objectClasses', ])
def HTMLSchemaTree(schema,se_class,se_tree,se_oid,level): """HTML output for browser""" se_obj = schema.get_obj(se_class,se_oid) if se_obj!=None: print (""" <dt><strong>%s (%s)</strong></dt> <dd> %s """ % (', '.join(se_obj.names),se_obj.oid,se_obj.desc)) if se_tree[se_oid]: print ('<dl>') for sub_se_oid in se_tree[se_oid]: HTMLSchemaTree(schema,se_class,se_tree,sub_se_oid,level+1) print ('</dl>') print ('</dd>')
def resolve_inherited_attrs(schema, oc): res = {'must': [], 'may': []} if oc == 'top': return res noc = schema.get_obj(ldap.schema.ObjectClass, oc) if noc.kind == 0: r = resolve_inherited_attrs(schema, noc.sup[0]) res['must'] += r['must'] res['may'] += r['may'] res['must'] += list(noc.must) res['may'] += list(noc.may) return res
def HTMLSchemaTree(schema,se_class,se_tree,se_oid,level): """HTML output for browser""" se_obj = schema.get_obj(se_class,se_oid) if se_obj!=None: print(""" <dt><strong>%s (%s)</strong></dt> <dd> %s """ % (', '.join(se_obj.names),se_obj.oid,se_obj.desc)) if se_tree[se_oid]: print('<dl>') for sub_se_oid in se_tree[se_oid]: HTMLSchemaTree(schema,se_class,se_tree,sub_se_oid,level+1) print('</dl>') print('</dd>')
def test_objectclass_attrs(self): """Check types and values of an ObjectClass object's attributes""" schema = self.get_schema() cls = schema.get_obj(ObjectClass, '2.5.6.9') expected_may = ( 'member', 'businessCategory', 'seeAlso', 'owner', 'ou', 'o', 'description', ) self.assertEqual(cls.oid, '2.5.6.9') self.assertEqual(cls.names, ('groupOfNames',)) self.assertEqual(cls.desc, None) self.assertEqual(cls.obsolete, False) self.assertEqual(cls.must, ('cn',)) self.assertEqual(cls.may, expected_may) self.assertEqual(cls.kind, 0) self.assertEqual(cls.sup, ('top',)) self.assertEqual(cls.x_origin, ('RFC 4519',))
def _resolve_attribute(schema, attr, blank=None): # pragma: nocover if not blank: blank = ldap.schema.AttributeType() blank.syntax_len = None if attr.sup: sup = schema.get_obj(ldap.schema.AttributeType, attr.sup[0]) if sup.syntax: blank.syntax = sup.syntax if sup.syntax_len: blank.syntax_len = sup.syntax_len if sup.equality: blank.equality = sup.equality if sup.substr: blank.substr = sup.substr return _resolve_attribute(schema, sup, blank) return blank
def _resolve_attribute(schema, attr, blank=None): if not blank: blank = ldap.schema.AttributeType() blank.syntax_len = None if attr.sup: sup = schema.get_obj(ldap.schema.AttributeType, attr.sup[0]) if sup.syntax: blank.syntax = sup.syntax if sup.syntax_len: blank.syntax_len = sup.syntax_len if sup.equality: blank.equality = sup.equality if sup.substr: blank.substr = sup.substr return _resolve_attribute(schema, sup, blank) return blank
def test_attributetype_attrs(self): """Check types and values of an AttributeType object's attributes""" schema = self.get_schema() attr = schema.get_obj(AttributeType, '1.3.6.1.4.1.11.1.3.1.1.3') expected_desc = ( 'Maximum time an agent or service allows for a search to complete' ) self.assertEqual(attr.oid, '1.3.6.1.4.1.11.1.3.1.1.3') self.assertEqual(attr.names, ('searchTimeLimit',)) self.assertEqual(attr.desc, expected_desc) self.assertEqual(attr.obsolete, False) self.assertEqual(attr.single_value, True) self.assertEqual(attr.syntax, '1.3.6.1.4.1.1466.115.121.1.27') self.assertEqual(attr.no_user_mod, False) self.assertEqual(attr.equality, 'integerMatch') self.assertEqual(attr.ordering, 'integerOrderingMatch') self.assertEqual(attr.sup, ()) self.assertEqual(attr.x_origin, ('RFC4876', 'user defined'))
def dump_ui(uri, oc, outfile=None, extend=None, rdn=None, contains=None): # pragma: nocover subschemasubentry_dn, schema = ldap.schema.urlfetch(uri) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) oco = schema.get_obj(ldap.schema.ObjectClass, oc) if oco is None: log.error( "unknown objectclass '%s' - please use the --list option to see what's there" % oc) exit(1) # Complete attributes in case of inheritance if oco.kind == 0: r = resolve_inherited_attrs(schema, oco.sup[0]) oco.must = list(set(list(oco.must) + r['must'])) oco.may = list(set(list(oco.may) + r['must'])) # Tabstop and connection collectors ts = [] cs = [] # Build resulting json dump children_must = generate_children(oco.must, schema) children_may = generate_children(oco.may, schema, len(children_must) // 2, children_must) template = { 'type': 'widget', 'class': 'qx.ui.container.Composite', 'layout': 'qx.ui.layout.Grid', 'extensions': { 'tabConfig': { 'title': oc } }, 'children': children_must + children_may } return json.dumps(template, indent=2)
def resolve_attribute(schema, attr): blank = {} attr = schema.get_obj(ldap.schema.AttributeType, attr) if attr.sup: inh = _resolve_attribute(schema, attr) else: inh = None blank['name'] = attr.names[0] blank['desc'] = attr.desc or "no description" blank['sup'] = inh != None blank['type'] = resolve_type(attr.syntax or inh.syntax) blank['syntax'] = attr.syntax or inh.syntax blank['maxlen'] = attr.syntax_len or (inh and inh.syntax_len) or None blank['multivalue'] = not attr.single_value blank['writable'] = not attr.no_user_mod blank['index'] = True if attr.equality or attr.substr or (inh and (inh.equality or inh.substr)) else False return blank
def resolve_attribute(schema, attr): # pragma: nocover blank = {} attr = schema.get_obj(ldap.schema.AttributeType, attr) if attr.sup: inh = _resolve_attribute(schema, attr) else: inh = None blank['name'] = attr.names[0] blank['desc'] = attr.desc or "no description" blank['sup'] = inh != None blank['type'] = resolve_type(attr.syntax or inh.syntax) blank['syntax'] = attr.syntax or inh.syntax blank['maxlen'] = attr.syntax_len or (inh and inh.syntax_len) or None blank['multivalue'] = not attr.single_value blank['writable'] = not attr.no_user_mod blank['index'] = True if attr.equality or attr.substr or ( inh and (inh.equality or inh.substr)) else False return blank
def dump_ui(uri, oc, outfile=None, extend=None, rdn=None, contains=None): # pragma: nocover subschemasubentry_dn, schema = ldap.schema.urlfetch(uri) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) oco = schema.get_obj(ldap.schema.ObjectClass, oc) if oco is None: log.error("unknown objectclass '%s' - please use the --list option to see what's there" % oc) exit(1) # Complete attributes in case of inheritance if oco.kind == 0: r = resolve_inherited_attrs(schema, oco.sup[0]) oco.must = list(set(list(oco.must) + r['must'])) oco.may = list(set(list(oco.may) + r['must'])) # Tabstop and connection collectors ts = [] cs = [] # Build resulting json dump children_must = generate_children(oco.must, schema) children_may = generate_children(oco.may, schema, len(children_must) // 2, children_must) template = { 'type': 'widget', 'class': 'qx.ui.container.Composite', 'layout': 'qx.ui.layout.Grid', 'extensions': { 'tabConfig': { 'title': oc } }, 'children': children_must + children_may } return json.dumps(template, indent=2)
def needed_objectclasses(self, entry): dont_remove = ['organizationalPerson', 'univentionPerson'] schema_attrs = ldap.schema.SCHEMA_ATTRS ldap.set_option(ldap.OPT_DEBUG_LEVEL, 0) ldap._trace_level = 0 subschemasubentry_dn, schema = ldap.schema.urlfetch( '%s/cn=subschema', self.uri) if subschemasubentry_dn is None: univention.debug.debug(univention.debug.LDAP, univention.debug.INFO, 'No sub schema sub entry found!') return None needed_oc = [] for attr_type, schema_class in ldap.schema.SCHEMA_CLASS_MAPPING.items( ): if attr_type == 'objectClasses': for element_id in schema.listall(schema_class): se_orig = schema.get_obj(schema_class, element_id) attributes = se_orig.may + se_orig.must for i in range(0, len(se_orig.names)): if se_orig.names[i] in entry[ 'objectClass'] and not se_orig.names[ i] in needed_oc: for j in attributes: if (j in res[0][1] or j in dont_remove ) and not se_orig.names[i] in needed_oc: needed_oc.append(se_orig.names[i]) return needed_oc
def collect_classes(schema, object_class, result): for sup_name in object_class.sup: sup_class = schema.get_obj(ldap.schema.ObjectClass, sup_name) collect_classes(schema, sup_class, result) result.append(object_class)
def dump_class(uri, oc, outfile=None, extend=None, rdn=None, contains=None): subschemasubentry_dn, schema = ldap.schema.urlfetch(uri) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) oco = schema.get_obj(ldap.schema.ObjectClass, oc) if oco is None: log.error("unknown objectclass '%s' - please use the --list option to see what's there" % oc) exit(1) # Complete attributes in case of inheritance if oco.kind == 0: r = resolve_inherited_attrs(schema, oco.sup[0]) oco.must = list(set(list(oco.must) + r['must'])) oco.may = list(set(list(oco.may) + r['must'])) # Build resulting XML dump e = ElementMaker(namespace="http://www.gonicus.de/Objects", nsmap={None: "http://www.gonicus.de/Objects"}) more = [] if oco.desc: more.append(e.Description(oco.desc)) more.append(e.Backend("LDAP")) if oco.kind == 0: if not rdn: log.error("no RDN provided - please use --rdn <value> to specify one") exit(1) more.append(e.BackendParameters(e.Backend("LDAP", objectClasses=oc, RDN=rdn))) if oco.kind != 0: more.append(e.BaseObject("false")) else: more.append(e.BaseObject("true")) # Build attribute set attrs = [] for mua in oco.must: attr = resolve_attribute(schema, mua) syntax = attr['syntax'] if skip(syntax): continue values = gen_values(syntax) values += gen_validators(syntax) values += gen_index(syntax) attrs.append( e.Attribute( e.Name(attr['name']), e.Description(attr['desc']), e.Type(attr['type']), e.MultiValue("true" if attr['multivalue'] else "false"), e.Mandatory("true"), *values)) for mua in oco.may: attr = resolve_attribute(schema, mua) syntax = attr['syntax'] if skip(syntax): continue values = gen_values(syntax) values += gen_validators(syntax) values += gen_index(syntax) attrs.append( e.Attribute( e.Name(attr['name']), e.Description(attr['desc']), e.Type(attr['type']), e.MultiValue("true" if attr['multivalue'] else "false"), e.Mandatory("false"), *values)) more.append(e.Attributes(*attrs)) # Add container if contains == None: c = [] for typ in contains.split(","): c.append(e.Type(typ)) more.append(e.Container(*c)) # Maintain extension if extend == None: more.append(e.Extends(e.Value(extend))) res = '<?xml version="1.0" encoding="UTF-8"?>\n' data = e.Objects(e.Object(e.Name(oc), e.DisplayName(oc), *more)) res += etree.tostring(data, pretty_print=True) return res
def dump_ui(uri, oc, outfile=None, extend=None, rdn=None, contains=None): subschemasubentry_dn, schema = ldap.schema.urlfetch(uri) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) oco = schema.get_obj(ldap.schema.ObjectClass, oc) if oco is None: log.error("unknown objectclass '%s' - please use the --list option to see what's there" % oc) exit(1) # Complete attributes in case of inheritance if oco.kind == 0: r = resolve_inherited_attrs(schema, oco.sup[0]) oco.must = list(set(list(oco.must) + r['must'])) oco.may = list(set(list(oco.may) + r['must'])) # Tabstop and connection collectors ts = [] cs = [] # Build resulting XML dump e = ElementMaker() n = 0 attrs = [] for mua in oco.must: attr = resolve_attribute(schema, mua) syntax = attr['syntax'] if skip(syntax): continue if not 'widget' in TYPE_MAP[syntax]: continue widget = TYPE_MAP[syntax]['widget'] attrs.append( e.item( e.widget( e.property(e.string(mua), name="text"), CLASS("QLabel"), name="%sLabel*" % mua), row=str(n), column="0")) attrs.append(e.item(e.widget(CLASS(widget), name="%sEdit*" % mua), row=str(n), column="1")) ts.append(e.tabstop(mua)) cs.append(e.connection( e.sender("%sEdit" % mua), e.signal("textChanged(QString)"), e.receiver(oc), e.slot("property_%s()" % mua))) n += 1 for mua in oco.may: if mua in oco.must: continue attr = resolve_attribute(schema, mua) syntax = attr['syntax'] if skip(syntax): continue if not 'widget' in TYPE_MAP[syntax]: continue widget = TYPE_MAP[syntax]['widget'] attrs.append( e.item( e.widget( e.property(e.string(mua), name="text"), CLASS("QLabel"), name="%sLabel" % mua), row=str(n), column="0")) attrs.append(e.item(e.widget(CLASS(widget), name="%sEdit" % mua), row=str(n), column="1")) ts.append(e.tabstop(mua)) cs.append(e.connection( e.sender("%sEdit" % mua), e.signal("textChanged(QString)"), e.receiver(oc), e.slot("property_%s()" % mua))) n += 1 res = '<?xml version="1.0" encoding="UTF-8"?>\n' data = e.ui( e("class", oc), e.widget( e.property(e.rect(e.x("0"), e.y("0"), e.width("400"), e.height("300")), name="geometry"), e.property(e.string(oc), name="windowTitle"), e.layout( e.item( e.layout(CLASS("QFormLayout"), *attrs, name="formLayout"), row="0", column="0"), CLASS("QGridLayout"), name="gridLayout"), CLASS("QWidget"), name=oc), e.tabstops(*ts), e.connections(*cs), version="4.0") res += etree.tostring(data, pretty_print=True) return res
def dump_class(uri, oc, outfile=None, extend=None, rdn=None, contains=None): subschemasubentry_dn, schema = ldap.schema.urlfetch(uri) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) oco = schema.get_obj(ldap.schema.ObjectClass, oc) if oco is None: log.error( "unknown objectclass '%s' - please use the --list option to see what's there" % oc) exit(1) # Complete attributes in case of inheritance if oco.kind == 0: r = resolve_inherited_attrs(schema, oco.sup[0]) oco.must = list(set(list(oco.must) + r['must'])) oco.may = list(set(list(oco.may) + r['must'])) # Build resulting XML dump e = ElementMaker(namespace="http://www.gonicus.de/Objects", nsmap={None: "http://www.gonicus.de/Objects"}) more = [] if oco.desc: more.append(e.Description(oco.desc)) more.append(e.Backend("LDAP")) if oco.kind == 0: if not rdn: log.error( "no RDN provided - please use --rdn <value> to specify one") exit(1) more.append( e.BackendParameters(e.Backend("LDAP", objectClasses=oc, RDN=rdn))) if oco.kind != 0: more.append(e.BaseObject("false")) else: more.append(e.BaseObject("true")) # Build attribute set attrs = [] syntax = None for mua in oco.must: attr = resolve_attribute(schema, mua) syntax = attr['syntax'] if skip(syntax): continue values = gen_values(syntax) values += gen_validators(syntax) values += gen_index(syntax) attrs.append( e.Attribute( e.Name(attr['name']), e.Description(attr['desc']), e.Type(attr['type']), e.MultiValue("true" if attr['multivalue'] else "false"), e.Mandatory("true"), *values)) for mua in oco.may: attr = resolve_attribute(schema, mua) syntax = attr['syntax'] if skip(syntax): continue values = gen_values(syntax) values += gen_validators(syntax) values += gen_index(syntax) attrs.append( e.Attribute( e.Name(attr['name']), e.Description(attr['desc']), e.Type(attr['type']), e.MultiValue("true" if attr['multivalue'] else "false"), e.Mandatory("false"), *values)) more.append(e.Attributes(*attrs)) # Add container if contains == None: c = [] for typ in contains.split(","): c.append(e.Type(typ)) more.append(e.Container(*c)) # Maintain extension if extend == None: more.append(e.Extends(e.Value(extend))) res = '<?xml version="1.0" encoding="UTF-8"?>\n' data = e.Objects(e.Object(e.Name(oc), e.DisplayName(oc), *more)) res += etree.tostring(data, pretty_print=True).decode('utf-8') return res
if subschemasubentry_dn is None: print('No sub schema sub entry found!') sys.exit(1) if schema.non_unique_oids: print('*** Schema errors ***') print('non-unique OIDs:\n', '\r\n'.join(schema.non_unique_oids)) print('*** Schema from', repr(subschemasubentry_dn)) # Display schema for attr_type, schema_class in ldap.schema.SCHEMA_CLASS_MAPPING.items(): print('*' * 20, attr_type, '*' * 20) for element_id in schema.listall(schema_class): se_orig = schema.get_obj(schema_class, element_id) print(attr_type, str(se_orig)) print('*** Testing object class inetOrgPerson ***') drink = schema.get_obj(ldap.schema.AttributeType, 'favouriteDrink') if not drink is None: print('*** drink ***') print('drink.names', repr(drink.names)) print('drink.collective', repr(drink.collective)) inetOrgPerson = schema.get_obj(ldap.schema.ObjectClass, 'inetOrgPerson') if not inetOrgPerson is None: print(inetOrgPerson.must, inetOrgPerson.may) print('*** person,organizationalPerson,inetOrgPerson ***') try:
""" recursive. returns all attributes for a objectClass object down the hierarchy """ attrs.extend(oc.may + oc.must) for oc_name in oc.sup: sup_oc = schema.get_obj(ldap.schema.ObjectClass, oc_name) getAttrs(sup_oc, attrs) return attrs def addAttrs(*ocnames): return tuple(itertools.chain(*[hubocnames_and_attrs[name] for name in ocnames])) isHubOC = lambda oc: oc.names[0].startswith("hub") all_ocs = [schema.get_obj(ldap.schema.ObjectClass, oid) for oid in schema.listall(ldap.schema.ObjectClass)] all_attrs = [schema.get_obj(ldap.schema.AttributeType, oid) for oid in schema.listall(ldap.schema.AttributeType)] multivalue_attrs = tuple(itertools.chain(*[x.names for x in all_attrs if not x.single_value])) hub_ocs = [oc for oc in all_ocs if isHubOC(oc)] hub_ocs = all_ocs hubocnames_and_attrs = dict([(oc.names[0], tuple(getAttrs(oc, []))) for oc in hub_ocs]) # aux_attrs_and_ocnames = dict([(hubocnames_and_attrs[oc.names[0]], oc.names[0]) for oc in hub_ocs if oc.kind == 2]) oc_entries = dict([(oc.names[0], (oc.names + oc.sup)) for oc in hub_ocs]) conn.unbind_s() del all_ocs, conn, isHubOC, schema, all_attrs def getLocalUserDNFromUid(conn, uid): gdn = globaluserdn % uid
def get_att(name,password,host): #if __name__=='__main__': url = ldapurl.LDAPUrl('ldap://', host+':389', '', name) ldap_server = ldap.initialize('ldap://'+host+':389') ldap_server.bind_s(name, password) subentrydn = ldap_server.search_subschemasubentry_s() entry = ldap_server.read_subschemasubentry_s(subentrydn,url.attrs) schema = None attributes = {} objectclass = {} if subentrydn!=None: schema = ldap.schema.SubSchema(entry) attlist = schema.listall(ldap.schema.AttributeType) for item in attlist: a = schema.get_obj(ldap.schema.AttributeType, item) attnamelist = a.names for att in attnamelist: attributes[att.lower()] = {"DESC": a.desc, "SINGLE": a.single_value, "SYNTAX": a.syntax, "NAME": att, "COLLECTIVE": a.collective, "EQUALITY": a.equality, "OBSOLETE": a.obsolete, "OID": a.oid, "ORDERING": a.ordering, "SUP": a.sup, "SYNTAX_LEN": a.syntax_len, "USAGE": a.usage} objlist = schema.listall(ldap.schema.ObjectClass) for oids in objlist: a = schema.get_obj(ldap.schema.ObjectClass, oids) kind = "" if a.kind == 0: kind = "STRUCTURAL" if a.kind == 1: kind = "ABSTRACT" if a.kind == 2: kind = "AUXILIARY" desc = "" if a.desc != None: desc = a.desc must = [] if len(a.must) != 0: must = a.must may = [] if len(a.may) != 0: may = a.may sup = [] for item in a.sup: if item.lower() != 'top': sup.append(item.lower()) numericoid = "" if a.oid != None: numericoid = a.oid for name in a.names: objectclass[name] = {"DESC":desc,"MUST":must,"MAY": may,"NAME": name,"KIND":kind,"SUP":sup,"OID": numericoid} else: schema = None #print attributes ldap_server.unbind() return objectclass
subschemasubentry_dn, schema = ldap.schema.urlfetch(sys.argv[-1]) schema_reverse = ldap.schema.SubSchema(schema.ldap_entry()) if subschemasubentry_dn is None: print "No sub schema sub entry found!" sys.exit(1) print "*** Schema from", repr(subschemasubentry_dn) # Display schema for attr_type, schema_class in ldap.schema.SCHEMA_CLASS_MAPPING.items(): print "*" * 20, attr_type, "*" * 20 for element_id in schema.listall(schema_class): se_orig = schema.get_obj(schema_class, element_id) se_reverse = schema_reverse.get_obj(schema_class, element_id) # assert str(se_orig)==str(se_reverse) print attr_type, str(se_orig) print "*** Testing object class inetOrgPerson ***" inetOrgPerson = schema.get_obj(ldap.schema.ObjectClass, "inetOrgPerson") if not inetOrgPerson is None: print inetOrgPerson.must, inetOrgPerson.may print "*** person,organizationalPerson,inetOrgPerson ***" try: print schema.attribute_types(["person", "organizationalPerson", "inetOrgPerson"]) print schema.attribute_types( ["person", "organizationalPerson", "inetOrgPerson"], attr_type_filter=[("no_user_mod", [0]), ("usage", range(2))],
if subschemasubentry_dn is None: print('No sub schema sub entry found!') sys.exit(1) if schema.non_unique_oids: print('*** Schema errors ***') print('non-unique OIDs:\n','\r\n'.join(schema.non_unique_oids)) print('*** Schema from',repr(subschemasubentry_dn)) # Display schema for attr_type,schema_class in ldap.schema.SCHEMA_CLASS_MAPPING.items(): print('*'*20,attr_type,'*'*20) for element_id in schema.listall(schema_class): se_orig = schema.get_obj(schema_class,element_id) print(attr_type,str(se_orig)) print('*** Testing object class inetOrgPerson ***') drink = schema.get_obj(ldap.schema.AttributeType,'favouriteDrink') if not drink is None: print('*** drink ***') print('drink.names',repr(drink.names)) print('drink.collective',repr(drink.collective)) inetOrgPerson = schema.get_obj(ldap.schema.ObjectClass,'inetOrgPerson') if not inetOrgPerson is None: print(inetOrgPerson.must,inetOrgPerson.may) print('*** person,organizationalPerson,inetOrgPerson ***') try:
def get_attribute_type(self, oid): openldap_uri = 'file://{}'.format(TEST_SUBSCHEMA_FILES[0]) dn, schema = ldap.schema.urlfetch(openldap_uri) return schema.get_obj(AttributeType, oid)
class WorkerThreadFetch(threading.Thread): # TODO MOVE THIS TO LUMACONNECTION def __init__(self, serverMeta): threading.Thread.__init__(self) self.serverMeta = serverMeta self.ldapConnection = None self.FINISHED = False self.exceptionObject = None self.objectClassesDict = {} self.attributeDict = {} self.syntaxDict = {} self.matchingDict = {} def run(self): try: urlschemeVal = "ldap" if self.serverMeta.encryptionMethod == ServerEncryptionMethod.SSL: urlschemeVal = "ldaps" whoVal = None credVal = None if not (self.serverMeta.bindAnon): whoVal = self.serverMeta.bindDN credVal = self.serverMeta.bindPassword url = ldapurl.LDAPUrl(urlscheme=urlschemeVal, hostport=self.serverMeta.hostname + ":" + str(self.serverMeta.port), dn=self.serverMeta.baseDN, who=whoVal, cred=credVal) self.ldapServerObject = ldap.initialize(url.initializeUrl()) self.ldapServerObject.protocol_version = 3 # Check whether we want to validate the server certificate. validateMethod = ldap.OPT_X_TLS_DEMAND if self.serverMeta.checkServerCertificate == ServerCheckCertificate.Demand: validateMethod = ldap.OPT_X_TLS_DEMAND elif self.serverMeta.checkServerCertificate == ServerCheckCertificate.Never: validateMethod = ldap.OPT_X_TLS_NEVER elif self.serverMeta.checkServerCertificate == ServerCheckCertificate.Try: validateMethod = ldap.OPT_X_TLS_TRY elif self.serverMeta.checkServerCertificate == ServerCheckCertificate.Allow: validateMethod = ldap.OPT_X_TLS_ALLOW encryption = False if self.serverMeta.encryptionMethod == ServerEncryptionMethod.SSL: encryption = True elif self.serverMeta.encryptionMethod == ServerEncryptionMethod.TLS: encryption = True if encryption: ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, validateMethod) #self.ldapServerObject.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, validateMethod) # If we're going to present client certificates, this must be set as an option if self.serverMeta.useCertificate and encryption: try: self.ldapServerObject.set_option( ldap.OPT_X_TLS_CERTFILE, self.serverMeta.clientCertFile) self.ldapServerObject.set_option( ldap.OPT_X_TLS_KEYFILE, self.serverMeta.clientCertKeyfile) except Exception, e: message = "Certificate error. Reason:\n" message += "Could not set client certificate and certificate keyfile. " message += str(e) #TODO LOGGING print "Error:", message, "in ObjectClassAttributeInfo.WorkerThreadFetch" print "TODO - proper logging/error-handling" #environment.logMessage(LogObject("Error,",message)) if self.serverMeta.encryptionMethod == ServerEncryptionMethod.TLS: self.ldapServerObject.start_tls_s() # Enable Alias support if self.serverMeta.followAliases: self.ldapServerObject.set_option(ldap.OPT_DEREF, ldap.DEREF_ALWAYS) if self.serverMeta.bindAnon: self.ldapServerObject.simple_bind() elif self.serverMeta.authMethod == ServerAuthMethod.Simple: self.ldapServerObject.simple_bind_s(whoVal, credVal) elif not self.serverMeta == ServerAuthMethod.Simple: sasl_cb_value_dict = {} if not self.serverMeta.authMethod == ServerAuthMethod.SASL_GSSAPI: sasl_cb_value_dict[ldap.sasl.CB_AUTHNAME] = whoVal sasl_cb_value_dict[ldap.sasl.CB_PASS] = credVal sasl_mech = None if self.serverMeta.authMethod == ServerAuthMethod.SASL_PLAIN: sasl_mech = "PLAIN" elif self.serverMeta.authMethod == ServerAuthMethod.SASL_CRAM_MD5: sasl_mech = "CRAM-MD5" elif self.serverMeta.authMethod == ServerAuthMethod.SASL_DIGEST_MD5: sasl_mech = "DIGEST-MD5" elif self.serverMeta.authMethod == ServerAuthMethod.SASL_LOGIN: sasl_mech = "LOGIN" elif self.serverMeta.authMethod == ServerAuthMethod.SASL_GSSAPI: sasl_mech = "GSSAPI" elif self.serverMeta.authMethod == ServerAuthMethod.SASL_EXTERNAL: sasl_mech = "EXTERNAL" sasl_auth = ldap.sasl.sasl(sasl_cb_value_dict, sasl_mech) # If python-ldap has no support for SASL, it doesn't have # sasl_interactive_bind_s as a method. try: if "EXTERNAL" == sasl_mech: #url = ldapurl.LDAPUrl(urlscheme="ldapi", # hostport = self.serverMeta.host.replace("/", "%2f"), # dn = self.serverMeta.baseDN) url = "ldapi://" + self.serverMeta.hostname.replace( "/", "%2F").replace(",", "%2C") #self.ldapServerObject = ldap.initialize(url.initializeUrl()) self.ldapServerObject = ldap.initialize(url) self.ldapServerObject.protocol_version = 3 # Enable Alias support if self.serverMeta.followAliases: self.ldapServerObject.set_option( ldap.OPT_DEREF, ldap.DEREF_ALWAYS) self.ldapServerObject.sasl_interactive_bind_s( "", sasl_auth) except AttributeError, e: self.result = False self.exceptionObject = e self.FINISHED = True return #subschemasubentry_dn = self.ldapServerObject.search_subschemasubentry_s(url.dn) subschemasubentry_dn = self.ldapServerObject.search_subschemasubentry_s( ) if subschemasubentry_dn is None: subschemasubentry_entry = None else: if url.attrs is None: schema_attrs = SCHEMA_ATTRS else: schema_attrs = url.attrs subschemasubentry_entry = self.ldapServerObject.read_subschemasubentry_s( subschemasubentry_dn, attrs=schema_attrs) self.ldapServerObject.unbind_s() schema = None if subschemasubentry_dn != None: schema = ldap.schema.SubSchema(subschemasubentry_entry) else: schema = None # get objectclass information oidList = schema.listall(ldap.schema.ObjectClass) for x in oidList: y = schema.get_obj(ldap.schema.ObjectClass, x) # detect kind of objectclass kind = "" if 0 == y.kind: kind = "STRUCTURAL" elif 1 == y.kind: kind = "ABSTRACT" elif 2 == y.kind: kind = "AUXILIARY" # name of objectclass desc = "" if not (y.desc == None): desc = y.desc # must attributes of the objectclass must = [] if not (len(y.must) == 0): must = y.must # may attributes of the objectclass may = [] if not (len(y.may) == 0): may = y.may # parents of the objectclass # beware that not the whole class chain is given. only # the first class above the current parents = [] for parent in y.sup: # filter out objectclass top. all classes are # derived from top if not ("top" == parent.lower()): parents.append(parent.lower()) oid = "" if not (y.oid == None): oid = y.oid # store values for each name the current class has. # IMPORTANT: the key is always lowercase for name in y.names: self.objectClassesDict[name.lower()] = { "DESC": desc, "MUST": must, "MAY": may, "NAME": name, "KIND": kind, "PARENTS": parents, "OID": oid } # get attribute information oidList = schema.listall(ldap.schema.AttributeType) for x in oidList: y = schema.get_obj(ldap.schema.AttributeType, x) nameList = y.names for z in nameList: self.attributeDict[z.lower()] = { "DESC": y.desc, "SINGLE": y.single_value, "SYNTAX": y.syntax, "NAME": z, "COLLECTIVE": y.collective, "EQUALITY": y.equality, "OBSOLETE": y.obsolete, "OID": y.oid, "ORDERING": y.ordering, "SUP": y.sup, "SYNTAX_LEN": y.syntax_len, "USAGE": y.usage } # get syntax information oidList = schema.listall(ldap.schema.LDAPSyntax) for x in oidList: y = schema.get_obj(ldap.schema.LDAPSyntax, x) self.syntaxDict[x] = {"DESC": y.desc, "OID": y.oid} # get matching information oidList = schema.listall(ldap.schema.MatchingRule) for x in oidList: y = schema.get_obj(ldap.schema.MatchingRule, x) for z in y.names: self.matchingDict[z.lower()] = { "DESC": y.desc, "OID": y.oid, "OBSOLETE": y.obsolete, "SYNTAX": y.syntax, "NAME": z } self.FINISHED = True
def get_object_class(oc): _, schema = ldap.schema.urlfetch(settings.ldap_uri) return schema.get_obj(ldap.schema.ObjectClass, oc)