From 8e5f5e3f05f9d2cd6ef1553deacce88c2a8c4d2e Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Fri, 13 Nov 2009 09:58:20 -0600 Subject: [PATCH] s4:provision - Removed dependency on full Samba 3 schema from FDS --- .../dsdb/samdb/ldb_modules/simple_ldap_map.c | 41 ------- source4/lib/ldb-samba/ldif_handlers.c | 1 + source4/scripting/python/samba/provision.py | 40 ++----- .../python/samba/provisionbackend.py | 108 +++++++++++++----- source4/scripting/python/samba/schema.py | 19 ++- source4/setup/fedorads-dna.ldif | 1 - source4/setup/fedorads.inf | 5 - source4/setup/schema-map-fedora-ds-1.0 | 47 +++----- source4/utils/oLschema2ldif.c | 60 +++++++++- 9 files changed, 170 insertions(+), 152 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c index 2ab448662aa..8d3c78d37fb 100644 --- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c +++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c @@ -611,15 +611,6 @@ static const struct ldb_map_attribute nsuniqueid_attributes[] = } } }, - { - .local_name = "unixHomeDirectory", - .type = LDB_MAP_RENAME, - .u = { - .rename = { - .remote_name = "homeDirectory" - } - } - }, { .local_name = "pwdLastSet", .type = LDB_MAP_RENAME, @@ -740,38 +731,6 @@ static const struct ldb_map_attribute nsuniqueid_attributes[] = /* This objectClass conflicts with builtin classes on FDS */ const struct ldb_map_objectclass nsuniqueid_objectclasses[] = { - { - .local_name = "domain", - .remote_name = "samba4Domain" - }, - { - .local_name = "rFC822LocalPart", - .remote_name = "samba4RFC822LocalPart" - }, - { - .local_name = "mailRecipient", - .remote_name = "samba4MailRecipient" - }, - { - .local_name = "nisMap", - .remote_name = "samba4NisMap" - }, - { - .local_name = "person", - .remote_name = "samba4Person" - }, - { - .local_name = "organizationalPerson", - .remote_name = "samba4OrganizationalPerson" - }, - { - .local_name = "residentialPerson", - .remote_name = "samba4ResidentialPerson" - }, - { - .local_name = "inetOrgPerson", - .remote_name = "samba4InetOrgPerson" - }, { .local_name = NULL } diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c index f2c985e81a2..a74687173ad 100644 --- a/source4/lib/ldb-samba/ldif_handlers.c +++ b/source4/lib/ldb-samba/ldif_handlers.c @@ -855,6 +855,7 @@ static const struct { { "objectGUID", LDB_SYNTAX_SAMBA_GUID }, { "invocationId", LDB_SYNTAX_SAMBA_GUID }, { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID }, + { "oMSyntax", LDB_SYNTAX_SAMBA_INT32 }, { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID }, { "parentGUID", LDB_SYNTAX_SAMBA_GUID }, { "siteGUID", LDB_SYNTAX_SAMBA_GUID }, diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 86e7cec6ab3..e2f7cd79534 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -183,15 +183,6 @@ class ProvisionPaths(object): self.slapdconf = None self.modulesconf = None self.memberofconf = None - self.fedoradsinf = None - self.fedoradspartitions = None - self.fedoradssasl = None - self.fedoradsdna = None - self.fedoradspam = None - self.fedoradsrefint = None - self.fedoradslinkedattributes = None - self.fedoradsindex = None - self.fedoradssamba = None self.olmmron = None self.olmmrserveridsconf = None self.olmmrsyncreplconf = None @@ -334,24 +325,6 @@ def provision_paths_from_lp(lp, dnsdomain): "modules.conf") paths.memberofconf = os.path.join(paths.ldapdir, "memberof.conf") - paths.fedoradsinf = os.path.join(paths.ldapdir, - "fedorads.inf") - paths.fedoradspartitions = os.path.join(paths.ldapdir, - "fedorads-partitions.ldif") - paths.fedoradssasl = os.path.join(paths.ldapdir, - "fedorads-sasl.ldif") - paths.fedoradsdna = os.path.join(paths.ldapdir, - "fedorads-dna.ldif") - paths.fedoradspam = os.path.join(paths.ldapdir, - "fedorads-pam.ldif") - paths.fedoradsrefint = os.path.join(paths.ldapdir, - "fedorads-refint.ldif") - paths.fedoradslinkedattributes = os.path.join(paths.ldapdir, - "fedorads-linked-attributes.ldif") - paths.fedoradsindex = os.path.join(paths.ldapdir, - "fedorads-index.ldif") - paths.fedoradssamba = os.path.join(paths.ldapdir, - "fedorads-samba.ldif") paths.olmmrserveridsconf = os.path.join(paths.ldapdir, "mmr_serverids.conf") paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, @@ -1250,22 +1223,25 @@ def provision(setup_dir, message, session_info, paths=paths, setup_path=setup_path, lp=lp, credentials=credentials, names=names, - message=message, hostname=hostname, + message=message, + domainsid=domainsid, schema=schema, + hostname=hostname, ldapadminpass=ldapadminpass, slapd_path=slapd_path, ldap_backend_extra_port=ldap_backend_extra_port, ldap_dryrun_mode=ldap_dryrun_mode, root=root, - setup_ds_path=setup_ds_path, - domainsid=domainsid) + setup_ds_path=setup_ds_path) elif backend_type == "openldap": provision_backend = OpenLDAPBackend(backend_type, paths=paths, setup_path=setup_path, lp=lp, credentials=credentials, names=names, - message=message, hostname=hostname, + message=message, + domainsid=domainsid, schema=schema, + hostname=hostname, ldapadminpass=ldapadminpass, slapd_path=slapd_path, ldap_backend_extra_port=ldap_backend_extra_port, @@ -1275,7 +1251,7 @@ def provision(setup_dir, message, session_info, else: raise ProvisioningError("Unknown LDAP backend type selected") - provision_backend.setup() + provision_backend.init() provision_backend.start() # only install a new shares config db if there is none diff --git a/source4/scripting/python/samba/provisionbackend.py b/source4/scripting/python/samba/provisionbackend.py index 7ef556c123c..595c1bebbb3 100644 --- a/source4/scripting/python/samba/provisionbackend.py +++ b/source4/scripting/python/samba/provisionbackend.py @@ -40,6 +40,7 @@ import urllib from ldb import SCOPE_BASE, SCOPE_ONELEVEL, LdbError, timestring from credentials import Credentials, DONT_USE_KERBEROS from samba import setup_file +from schema import Schema def setup_db_config(setup_path, dbdir): """Setup a Berkeley database. @@ -70,7 +71,7 @@ class ProvisionBackend(object): # Set a default - the code for "existing" below replaces this self.ldap_backend_type = backend_type - def setup(self): + def init(self): pass def start(self): @@ -94,7 +95,7 @@ class LDBBackend(ProvisionBackend): names=names, message=message) - def setup(self): + def init(self): self.credentials = None self.secrets_credentials = None @@ -115,7 +116,7 @@ class ExistingBackend(ProvisionBackend): self.ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.ldapdir, "ldapi"), safe="") - def setup(self): + def init(self): #Check to see that this 'existing' LDAP backend in fact exists ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials) search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE, @@ -131,8 +132,9 @@ class ExistingBackend(ProvisionBackend): class LDAPBackend(ProvisionBackend): def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None, names=None, message=None, - hostname=None, + domainsid=None, schema=None, + hostname=None, ldapadminpass=None, slapd_path=None, ldap_backend_extra_port=None, @@ -145,9 +147,9 @@ class LDAPBackend(ProvisionBackend): names=names, message=message) - self.hostname = hostname + self.domainsid = domainsid self.schema = schema - + self.hostname = hostname self.ldapadminpass = ldapadminpass self.slapd_path = slapd_path @@ -159,7 +161,10 @@ class LDAPBackend(ProvisionBackend): self.ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.ldapdir, "ldapi"), safe="") - def setup(self): + if not os.path.exists(self.paths.ldapdir): + os.mkdir(self.paths.ldapdir) + + def init(self): # we will shortly start slapd with ldapi for final provisioning. first check with ldapsearch -> rootDSE via self.ldapi_uri # if another instance of slapd is already running try: @@ -261,8 +266,9 @@ class LDAPBackend(ProvisionBackend): class OpenLDAPBackend(LDAPBackend): def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None, names=None, message=None, - hostname=None, + domainsid=None, schema=None, + hostname=None, ldapadminpass=None, slapd_path=None, ldap_backend_extra_port=None, @@ -276,8 +282,9 @@ class OpenLDAPBackend(LDAPBackend): lp=lp, credentials=credentials, names=names, message=message, - hostname=hostname, + domainsid=domainsid, schema=schema, + hostname=hostname, ldapadminpass=ldapadminpass, slapd_path=slapd_path, ldap_backend_extra_port=ldap_backend_extra_port, @@ -286,6 +293,13 @@ class OpenLDAPBackend(LDAPBackend): self.ol_mmr_urls = ol_mmr_urls self.nosync = nosync + self.schema = Schema( + self.setup_path, + self.domainsid, + schemadn=self.names.schemadn, + serverdn=self.names.serverdn, + files=[setup_path("schema_samba4.ldif")]); + def provision(self): # Wipe the directories so we can start shutil.rmtree(os.path.join(self.paths.ldapdir, "db"), True) @@ -513,15 +527,15 @@ class OpenLDAPBackend(LDAPBackend): class FDSBackend(LDAPBackend): def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None, names=None, message=None, - hostname=None, + domainsid=None, schema=None, + hostname=None, ldapadminpass=None, slapd_path=None, ldap_backend_extra_port=None, ldap_dryrun_mode=False, root=None, - setup_ds_path=None, - domainsid=None): + setup_ds_path=None): super(FDSBackend, self).__init__( backend_type=backend_type, @@ -529,8 +543,9 @@ class FDSBackend(LDAPBackend): lp=lp, credentials=credentials, names=names, message=message, - hostname=hostname, + domainsid=domainsid, schema=schema, + hostname=hostname, ldapadminpass=ldapadminpass, slapd_path=slapd_path, ldap_backend_extra_port=ldap_backend_extra_port, @@ -538,7 +553,38 @@ class FDSBackend(LDAPBackend): self.root = root self.setup_ds_path = setup_ds_path - self.domainsid = domainsid + + self.sambadn = "CN=Samba" + + self.fedoradsinf = os.path.join(paths.ldapdir, "fedorads.inf") + self.partitions_ldif = os.path.join(paths.ldapdir, "fedorads-partitions.ldif") + self.sasl_ldif = os.path.join(paths.ldapdir, "fedorads-sasl.ldif") + self.dna_ldif = os.path.join(paths.ldapdir, "fedorads-dna.ldif") + self.pam_ldif = os.path.join(paths.ldapdir, "fedorads-pam.ldif") + self.refint_ldif = os.path.join(paths.ldapdir, "fedorads-refint.ldif") + self.linked_attrs_ldif = os.path.join(paths.ldapdir, "fedorads-linked-attributes.ldif") + self.index_ldif = os.path.join(paths.ldapdir, "fedorads-index.ldif") + self.samba_ldif = os.path.join(paths.ldapdir, "fedorads-samba.ldif") + + self.samba3_schema = self.setup_path("../../examples/LDAP/samba.schema") + self.samba3_ldif = os.path.join(self.paths.ldapdir, "samba3.ldif") + + self.retcode = subprocess.call(["bin/oLschema2ldif", "-H", "NONE", + "-I", self.samba3_schema, + "-O", self.samba3_ldif, + "-b", self.names.domaindn], + close_fds=True, shell=False) + + if self.retcode != 0: + raise Exception("Unable to convert Samba 3 schema.") + + self.schema = Schema( + self.setup_path, + self.domainsid, + schemadn=self.names.schemadn, + serverdn=self.names.serverdn, + files=[setup_path("schema_samba4.ldif"), self.samba3_ldif], + prefixmap=["1000:1.3.6.1.4.1.7165.2.1", "1001:1.3.6.1.4.1.7165.2.2"]) def provision(self): if self.ldap_backend_extra_port is not None: @@ -546,7 +592,7 @@ class FDSBackend(LDAPBackend): else: serverport = "" - setup_file(self.setup_path("fedorads.inf"), self.paths.fedoradsinf, + setup_file(self.setup_path("fedorads.inf"), self.fedoradsinf, {"ROOT": self.root, "HOSTNAME": self.hostname, "DNSDOMAIN": self.names.dnsdomain, @@ -556,23 +602,23 @@ class FDSBackend(LDAPBackend): "LDAPMANAGERPASS": self.ldapadminpass, "SERVERPORT": serverport}) - setup_file(self.setup_path("fedorads-partitions.ldif"), self.paths.fedoradspartitions, + setup_file(self.setup_path("fedorads-partitions.ldif"), self.partitions_ldif, {"CONFIGDN": self.names.configdn, "SCHEMADN": self.names.schemadn, - "SAMBADN": self.names.sambadn, + "SAMBADN": self.sambadn, }) - setup_file(self.setup_path("fedorads-sasl.ldif"), self.paths.fedoradssasl, - {"SAMBADN": self.names.sambadn, + setup_file(self.setup_path("fedorads-sasl.ldif"), self.sasl_ldif, + {"SAMBADN": self.sambadn, }) - setup_file(self.setup_path("fedorads-dna.ldif"), self.paths.fedoradsdna, + setup_file(self.setup_path("fedorads-dna.ldif"), self.dna_ldif, {"DOMAINDN": self.names.domaindn, - "SAMBADN": self.names.sambadn, + "SAMBADN": self.sambadn, "DOMAINSID": str(self.domainsid), }) - setup_file(self.setup_path("fedorads-pam.ldif"), self.paths.fedoradspam) + setup_file(self.setup_path("fedorads-pam.ldif"), self.pam_ldif) lnkattr = self.schema.linked_attributes() @@ -593,8 +639,8 @@ class FDSBackend(LDAPBackend): { "ATTR" : attr }) argnum += 1 - open(self.paths.fedoradsrefint, 'w').write(refint_config) - open(self.paths.fedoradslinkedattributes, 'w').write(memberof_config) + open(self.refint_ldif, 'w').write(refint_config) + open(self.linked_attrs_ldif, 'w').write(memberof_config) attrs = ["lDAPDisplayName"] res = self.schema.ldb.search(expression="(&(objectclass=attributeSchema)(searchFlags:1.2.840.113556.1.4.803:=1))", base=self.names.schemadn, scope=SCOPE_ONELEVEL, attrs=attrs) @@ -608,10 +654,10 @@ class FDSBackend(LDAPBackend): index_config += read_and_sub_file(self.setup_path("fedorads-index.ldif"), { "ATTR" : attr }) - open(self.paths.fedoradsindex, 'w').write(index_config) + open(self.index_ldif, 'w').write(index_config) - setup_file(self.setup_path("fedorads-samba.ldif"), self.paths.fedoradssamba, - {"SAMBADN": self.names.sambadn, + setup_file(self.setup_path("fedorads-samba.ldif"), self.samba_ldif, + {"SAMBADN": self.sambadn, "LDAPADMINPASS": self.ldapadminpass }) @@ -649,16 +695,16 @@ class FDSBackend(LDAPBackend): raise ProvisioningError("Warning: Given Path to slapd does not exist!") # Run the Fedora DS setup utility - retcode = subprocess.call([self.setup_ds_path, "--silent", "--file", self.paths.fedoradsinf], close_fds=True, shell=False) + retcode = subprocess.call([self.setup_ds_path, "--silent", "--file", self.fedoradsinf], close_fds=True, shell=False) if retcode != 0: raise ProvisioningError("setup-ds failed") # Load samba-admin retcode = subprocess.call([ - os.path.join(self.paths.ldapdir, "slapd-samba4", "ldif2db"), "-s", self.names.sambadn, "-i", self.paths.fedoradssamba], + os.path.join(self.paths.ldapdir, "slapd-samba4", "ldif2db"), "-s", self.sambadn, "-i", self.samba_ldif], close_fds=True, shell=False) if retcode != 0: - raise("ldib2db failed") + raise("ldif2db failed") def post_setup(self): ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials) @@ -671,7 +717,7 @@ class FDSBackend(LDAPBackend): dn = str(res[i]["dn"]) ldapi_db.delete(dn) - aci = """(targetattr = "*") (version 3.0;acl "full access to all by samba-admin";allow (all)(userdn = "ldap:///CN=samba-admin,%s");)""" % self.names.sambadn + aci = """(targetattr = "*") (version 3.0;acl "full access to all by samba-admin";allow (all)(userdn = "ldap:///CN=samba-admin,%s");)""" % self.sambadn m = ldb.Message() m["aci"] = ldb.MessageElement([aci], ldb.FLAG_MOD_REPLACE, "aci") diff --git a/source4/scripting/python/samba/schema.py b/source4/scripting/python/samba/schema.py index 2f90ac7122d..6f45859ead4 100644 --- a/source4/scripting/python/samba/schema.py +++ b/source4/scripting/python/samba/schema.py @@ -51,7 +51,7 @@ def get_schema_descriptor(domain_sid): class Schema(object): def __init__(self, setup_path, domain_sid, schemadn=None, - serverdn=None): + serverdn=None, files=None, prefixmap=None): """Load schema for the SamDB from the AD schema files and samba4_schema.ldif :param samdb: Load a schema into a SamDB. @@ -66,7 +66,11 @@ class Schema(object): self.ldb = Ldb() self.schema_data = read_ms_schema(setup_path('ad-schema/MS-AD_Schema_2K8_Attributes.txt'), setup_path('ad-schema/MS-AD_Schema_2K8_Classes.txt')) - self.schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() + + if files is not None: + for file in files: + self.schema_data += open(file, 'r').read() + self.schema_data = substitute_var(self.schema_data, {"SCHEMADN": schemadn}) check_all_substituted(self.schema_data) @@ -81,13 +85,18 @@ class Schema(object): "DESCRIPTOR": descr }) - prefixmap = open(setup_path("prefixMap.txt"), 'r').read() - prefixmap = b64encode(prefixmap) + self.prefixmap_data = open(setup_path("prefixMap.txt"), 'r').read() + + if prefixmap is not None: + for map in prefixmap: + self.prefixmap_data += "%s\n" % map + + self.prefixmap_data = b64encode(self.prefixmap_data) # We don't actually add this ldif, just parse it - prefixmap_ldif = "dn: cn=schema\nprefixMap:: %s\n\n" % prefixmap + prefixmap_ldif = "dn: cn=schema\nprefixMap:: %s\n\n" % self.prefixmap_data self.ldb.set_schema_from_ldif(prefixmap_ldif, self.schema_data) def write_to_tmp_ldb(self, schemadb_path): diff --git a/source4/setup/fedorads-dna.ldif b/source4/setup/fedorads-dna.ldif index f9785f33648..646fec89b38 100644 --- a/source4/setup/fedorads-dna.ldif +++ b/source4/setup/fedorads-dna.ldif @@ -3,7 +3,6 @@ objectClass: top objectClass: extensibleObject cn: Samba SIDs dnaType: sambaSID -dnaMaxValue: 10000 dnaMagicRegen: 0 dnaFilter: (|(objectClass=user)(objectClass=group)) dnaScope: ${DOMAINDN} diff --git a/source4/setup/fedorads.inf b/source4/setup/fedorads.inf index e93913c70fa..2dda1bc9d6b 100644 --- a/source4/setup/fedorads.inf +++ b/source4/setup/fedorads.inf @@ -26,11 +26,6 @@ cert_dir= ${LDAPDIR}/slapd-samba4 start_server= 0 install_full_schema= 0 SchemaFile=${LDAPDIR}/99_ad.ldif -SchemaFile=/etc/dirsrv/schema/10rfc2307.ldif -SchemaFile=/etc/dirsrv/schema/05rfc4523.ldif -SchemaFile=/etc/dirsrv/schema/05rfc4524.ldif -SchemaFile=/etc/dirsrv/schema/06inetorgperson.ldif -SchemaFile=/usr/share/dirsrv/data/60samba3.ldif ConfigFile = ${LDAPDIR}/fedorads-partitions.ldif ConfigFile = ${LDAPDIR}/fedorads-sasl.ldif ConfigFile = ${LDAPDIR}/fedorads-dna.ldif diff --git a/source4/setup/schema-map-fedora-ds-1.0 b/source4/setup/schema-map-fedora-ds-1.0 index 7bb3da3300f..4ed833fa331 100644 --- a/source4/setup/schema-map-fedora-ds-1.0 +++ b/source4/setup/schema-map-fedora-ds-1.0 @@ -12,17 +12,23 @@ description cn dITContentRules top -homePostalAddress -info -displayName -employeeNumber -employeeType -personalTitle -co -userSMIMECertificate + #This should be provided by the LDAP server, only in our schema to permit provision aci + #Skip ObjectClasses +sambaSamAccount +sambaGroupMapping +sambaTrustPassword +sambaTrustedDomainPassword +sambaDomain +sambaUnixIdPool +sambaIdmapEntry +sambaSidEntry +sambaConfig +sambaShare +sambaConfigOption + #MiddleName has a conflicting OID 2.16.840.1.113730.3.1.34:1.3.6.1.4.1.7165.4.255.1 #defaultGroup has a conflicting OID @@ -47,8 +53,6 @@ aci 1.3.6.1.4.1.1466.115.121.1.43:1.3.6.1.4.1.1466.115.121.1.15 #Remap into existing schema -unixHomeDirectory -unixHomeDirectory:homeDirectory pwdLastSet pwdLastSet:sambaPwdLastSet lastLogon @@ -77,26 +81,3 @@ privilegeDisplayName privilegeDisplayName:sambaPrivName objectSid objectSid:sambaSID - -#Resolve conflicting attributes -1.2.840.113556.1.4.484:fRSDirectoryFilter-oid -1.2.840.113556.1.4.483:fRSFileFilter-oid -1.2.840.113556.1.4.485:fRSUpdateTimeout-oid -2.16.840.1.113730.3.1.36:thumbnailLogo-oid -2.16.840.1.113730.3.1.35:thumbnailPhoto-oid -1.2.840.113556.1.4.481:schemaUpdate-oid - -#Resolve conflicting object classes -domain:samba4Domain -rFC822LocalPart:samba4RFC822LocalPart -mailRecipient:samba4MailRecipient -nisMap:samba4NisMap -0.9.2342.19200300.100.4.14:samba4RFC822LocalPart-oid -person:samba4Person -2.5.6.6:samba4Person-oid -organizationalPerson:samba4OrganizationalPerson -2.5.6.7:samba4OrganizationalPerson-oid -residentialPerson:samba4ResidentialPerson -2.5.6.10:samba4ResidentialPerson-oid -inetOrgPerson:samba4InetOrgPerson -2.16.840.1.113730.3.2.2:samba4InetOrgPerson-oid diff --git a/source4/utils/oLschema2ldif.c b/source4/utils/oLschema2ldif.c index 701d2210467..f337432b6b1 100644 --- a/source4/utils/oLschema2ldif.c +++ b/source4/utils/oLschema2ldif.c @@ -35,6 +35,8 @@ #include "ldb.h" #include "tools/cmdline.h" #include "dsdb/samdb/samdb.h" +#include "../lib/crypto/sha256.h" +#include "../librpc/gen_ndr/ndr_misc.h" #define SCHEMA_UNKNOWN 0 #define SCHEMA_NAME 1 @@ -336,6 +338,16 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) char *c, *s; int n; + SHA256_CTX sha256_context; + uint8_t digest[SHA256_DIGEST_LENGTH]; + + struct GUID guid; + struct ldb_val schemaIdGuid; + enum ndr_err_code ndr_err; + + bool isAttribute = false; + bool single_valued = false; + ctx = talloc_new(mem_ctx); msg = ldb_msg_new(ctx); @@ -351,6 +363,7 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) if (strncmp(c, "attributetype", 13) == 0) { c += 13; MSG_ADD_STRING("objectClass", "attributeSchema"); + isAttribute = true; break; } goto failed; @@ -374,7 +387,29 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) /* get attributeID */ n = strcspn(c, " \t"); s = talloc_strndup(msg, c, n); - MSG_ADD_STRING("attributeID", s); + if (isAttribute) { + MSG_ADD_STRING("attributeID", s); + } else { + MSG_ADD_STRING("governsID", s); + } + + SHA256_Init(&sha256_context); + SHA256_Update(&sha256_context, (uint8_t*)s, strlen(s)); + SHA256_Final(digest, &sha256_context); + + memcpy(&guid, digest, sizeof(struct GUID)); + + ndr_err = ndr_push_struct_blob(&schemaIdGuid, ctx, NULL, &guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto failed; + } + + if (ldb_msg_add_value(msg, "schemaIdGuid", &schemaIdGuid, NULL) != 0) { + goto failed; + } + c += n; c = skip_spaces(c); @@ -416,7 +451,7 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) break; case SCHEMA_SINGLE_VALUE: - MSG_ADD_STRING("isSingleValued", "TRUE"); + single_valued = true; break; case SCHEMA_EQUALITY: @@ -433,12 +468,23 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) case SCHEMA_SYNTAX: { - const struct dsdb_syntax *map = - find_syntax_map_by_standard_oid(token->value); + char *syntax_oid; + const struct dsdb_syntax *map; + char *oMSyntax; + + n = strcspn(token->value, "{"); + syntax_oid = talloc_strndup(ctx, token->value, n); + + map = find_syntax_map_by_standard_oid(syntax_oid); if (!map) { break; } + MSG_ADD_STRING("attributeSyntax", map->attributeSyntax_oid); + + oMSyntax = talloc_asprintf(msg, "%d", map->oMSyntax); + MSG_ADD_STRING("oMSyntax", oMSyntax); + break; } case SCHEMA_DESC: @@ -450,6 +496,12 @@ static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) } } + if (isAttribute) { + MSG_ADD_STRING("isSingleValued", single_valued ? "TRUE" : "FALSE"); + } else { + MSG_ADD_STRING("defaultObjectCategory", ldb_dn_get_linearized(msg->dn)); + } + talloc_steal(mem_ctx, msg); talloc_free(ctx); return msg; -- 2.34.1