LDB

From SambaWiki

LDB

Introduction

LDB is the database engine used within Samba. LDB is an an embedded LDAP-Like database library, but not completely LDAP compliant. It can store its database in regular files (using TDB), or talk to a standard LDAP server. LDB is a core part of Samba4. There has been work using it for Samba3's group mapping database.


Raw LDB is not even close to LDAP compliant, we use modules to ensure compliance. We aim for LDAP compliance where possible, although Samba’s higher priority is Active Directory compliance. We do aim for LDAP compliance where it doesn’t conflict.


LDB is transactional (allowing multiple changes to be made to ensure that changes all are applied as expected prior to committing them to the database, if an error occurs all changes are backed out and the database is left “untouched”) and modular (allowing different information or functionality to be added or removed according to how a database is needed to perform).


The main LDB website is located at https://ldb.samba.org/


All of the examples listed below will be using the ldb databases created by the self test suite included with Samba. These databases are located at {samba_build_directory}/st/dc/private/

What is LDAP?

Lightweight Directory Access Protocol is the dominant database used by organisations around the world to manage their, well, organisation – eg all of their directory services (things such as person information, IT information (machine details, print services, etc), all information pertaining to the business that would need to be “directoried”). Many large companies use LDAP within their server and business tools, eg IBM, Oracle, HP, Novell to name but a few.


LDAP is an incredibly complex protocol, and there are many books and RFCs available to read about it. The RFC probably most of note is this one: RFC4511 – Lightweight Directory Access Protocol (LDAP): The Protocol


Since this post aims to address LDB, I’ll go further into LDAP and how we use it at a later date. For now, some basic LDAP information (and some nice links) are available here: http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol


Active Directory

Active Directory is a Microsoft product, based around LDAP, but uses other pieces to make up the whole such as Kerberosv5, DNS, MS-RPC, SMB (CIFS). Other protocols are used within Active Directory, but these form the major components.


These components are used as follows:

LDAP database

kerberos authentication system

dns machine names – not as trivial as may be expected, this forms a fairly large part of AD and will probably warrant its own post in the near future. If you want this, and I forget, ping me!! Really :)

MS-RPC remote procedure calls, if you can’t do **something** over LDAP you can generally use MS-RPC. With MS-RPC, you create a protocol specification using IDL files, compiled using IDL compilers, which creates a remote protocol procedure for RPC calls. This also warrants its own post to demonstrate why, how, where, etc. Soon!

SMB/CIFS for file sharing


There are several sources of information available on Active Directory. Microsoft has many useful documents available here: http://msdn.microsoft.com/en-us/library/gg258393%28v=PROT.13%29.aspx


And probably the one of most use, particularly within the Samba team, is the Active Directory Technical Specification. For example, this document gives valuable information about the database schema which is useful for ensuring compatibility with data sources within Samba (see section 3.1.1.3.1.1 Schema, page 123 of 521, using version 30.0 of the document, released 23rd September 2011) http://msdn.microsoft.com/en-us/library/cc223122%28v=PROT.13%29.aspx


TDB

TDB is the Trivial DataBase. This is a very simple key/value pair database (where each record has a key and some data associated with that key). TDB stores data in binary format, and supports transactions.


The main TDB website is located at http://tdb.samba.org

Some basic operations

tdb_open Opens a database

tdb_close Closes a database

tdb_delete Deletes a record with a given key

tdb_exists Checks for existence of a record with a given key

tdb_fetch Retrieves a record with a given key

tdb_store Allows insertion, modification or replacement of a record


TDB also has other functionality such as enumerating all records by asking for a list of all keys, start a transaction, do any number of operations and then cancel or commit transaction, etc.


Some typical tdb data might look as follows (taken from the samba secrets.ldb database used with the self test suite). This clearly displays the key and value pair of each record, with each record delimited by curly braces (in a dump format):


   username@computername:~/Samba/samba-master$ tdbdump st/dc/private/secrets.ldb
   {
   key(12) = "DN=@MODULES\00"
   data(45) = "g\19\01&\01\00\00\00@MODULES\00@LIST\00\01\00\00\00\0D\00\00\00samba_secrets\00"
   }
   {
   key(43) = "DN=FLATNAME=SAMBADOMAIN,CN=PRIMARY DOMAINS\00"
   data(702) = "g\19\01&\11\00\00\00flatname=SAMBADOMAIN,cn=Primary Domains\00msDS-KeyVersionNumber\00\01\00\00\00\01\00\00\001\00objectClass\00\03\00\00\00\03\00\00\00top\00\0D\00\00\00primaryDomain\00\0E\00\00\00kerberosSecret\00objectSid\00\01\00\00\00\18\00\00\00\01\04\00\00\00\00\00\05\15\00\00\00\013\BE\F5\DB\E8\C33\B4\9C\1E\ED\00privateKeytab\00\01\00\00\00\0E\00\00\00secrets.keytab\00realm\00\01\00\00\00\11\00\00\00SAMBA.EXAMPLE.COM\00saltPrincipal\00\01\00\00\000\00\00\00host/localdc.samba.example.com@SAMBA.EXAMPLE.COM\00samAccountName\00\01\00\00\00\08\00\00\00LOCALDC$\00secret\00\01\00\00\00\11\00\00\00machinelocDCpass1\00secureChannelType\00\01\00\00\00\01\00\00\006\00servicePrincipalName\00\02\00\00\00\0C\00\00\00HOST/localdc\00\1E\00\00\00HOST/localdc.samba.example.com\00objectGUID\00\01\00\00\00\10\00\00\00H\D9_\D5+\E3\C0G\B7\CF\F6\FB\B1m\EB\1E\00whenCreated\00\01\00\00\00\11\00\00\0020111005000140.0Z\00whenChanged\00\01\00\00\00\11\00\00\0020111005000140.0Z\00uSNCreated\00\01\00\00\00\01\00\00\007\00uSNChanged\00\01\00\00\00\01\00\00\007\00name\00\01\00\00\00\0B\00\00\00SAMBADOMAIN\00flatname\00\01\00\00\00\0B\00\00\00SAMBADOMAIN\00"
   }
   {
   key(31) = "DN=@INDEX:FLATNAME:SAMBADOMAIN\00"
   data(111) = "g\19\01&\02\00\00\00@INDEX:FLATNAME:SAMBADOMAIN\00@IDXVERSION\00\01\00\00\00\01\00\00\002\00@IDX\00\01\00\00\00'\00\00\00flatname=SAMBADOMAIN,cn=Primary Domains\00"
   }
   {
   key(15) = "DN=@ATTRIBUTES\00"
   data(153) = "g\19\01&\04\00\00\00@ATTRIBUTES\00cn\00\01\00\00\00\10\00\00\00CASE_INSENSITIVE\00flatname\00\01\00\00\00\10\00\00\00CASE_INSENSITIVE\00realm\00\01\00\00\00\10\00\00\00CASE_INSENSITIVE\00sAMAccountName\00\01\00\00\00\10\00\00\00CASE_INSENSITIVE\00"
   }


Note: this contains only a small section of the data returned from the secrets.ldb database.


Within Samba, the key is always the distinguished name (DN) for an object, and the data contains all of the attributes for that object. Every object in LDAP has a distinguished name that distinguishes it from any other (unique, as the name would suggest ;) ).


How LDB uses TDB

LDB basically sits on top of TDB and manipulates the data into an LDAP-like structure. As a very basic example, we can imagine a stack like structure with TDB residing at the base, then LDB modules are stacked on top that describe the functionality or rules required for this database (for example, schema information), and the LDB API sits on top taking and servicing requests.


So where TDB uses a key/value pair that is quite confusing to look at:


   {
   key(43) = "DN=FLATNAME=SAMBADOMAIN,CN=PRIMARY DOMAINS\00"
   data(702) = "g\19\01&\11\00\00\00flatname=SAMBADOMAIN,cn=Primary Domains\00msDS-KeyVersionNumber\00\01\00\00\00\01\00\00\001\00objectClass\00\03\00\00\00\03\00\00\00top\00\0D\00\00\00primaryDomain\00\0E\00\00\00kerberosSecret\00objectSid\00\01\00\00\00\18\00\00\00\01\04\00\00\00\00\00\05\15\00\00\00\013\BE\F5\DB\E8\C33\B4\9C\1E\ED\00privateKeytab\00\01\00\00\00\0E\00\00\00secrets.keytab\00realm\00\01\00\00\00\11\00\00\00SAMBA.EXAMPLE.COM\00saltPrincipal\00\01\00\00\000\00\00\00host/localdc.samba.example.com@SAMBA.EXAMPLE.COM\00samAccountName\00\01\00\00\00\08\00\00\00LOCALDC$\00secret\00\01\00\00\00\11\00\00\00machinelocDCpass1\00secureChannelType\00\01\00\00\00\01\00\00\006\00servicePrincipalName\00\02\00\00\00\0C\00\00\00HOST/localdc\00\1E\00\00\00HOST/localdc.samba.example.com\00objectGUID\00\01\00\00\00\10\00\00\00H\D9_\D5+\E3\C0G\B7\CF\F6\FB\B1m\EB\1E\00whenCreated\00\01\00\00\00\11\00\00\0020111005000140.0Z\00whenChanged\00\01\00\00\00\11\00\00\0020111005000140.0Z\00uSNCreated\00\01\00\00\00\01\00\00\007\00uSNChanged\00\01\00\00\00\01\00\00\007\00name\00\01\00\00\00\0B\00\00\00SAMBADOMAIN\00flatname\00\01\00\00\00\0B\00\00\00SAMBADOMAIN\00"
   }


LDB would output the same data as follows, in a much more readable fashion:

   dn: flatname=SAMBADOMAIN,cn=Primary Domains
   msDS-KeyVersionNumber: 1
   objectClass: top
   objectClass: primaryDomain
   objectClass: kerberosSecret
   objectSid: S-1-5-21-4122882817-868477147-3978206388
   privateKeytab: secrets.keytab
   realm: SAMBA.EXAMPLE.COM
   saltPrincipal: host/localdc.samba.example.com@SAMBA.EXAMPLE.COM
   samAccountName: LOCALDC$
   secret: machinelocDCpass1
   secureChannelType: 6
   servicePrincipalName: HOST/localdc
   servicePrincipalName: HOST/localdc.samba.example.com
   objectGUID: d55fd948-e32b-47c0-b7cf-f6fbb16deb1e
   whenCreated: 20111005000140.0Z
   whenChanged: 20111005000140.0Z
   uSNCreated: 7
   uSNChanged: 7
   name: SAMBADOMAIN
   flatname: SAMBADOMAIN
   distinguishedName: flatname=SAMBADOMAIN,cn=Primary Domains


LDB Modules

Modules can be stacked on top of each other to add rules or functionality. As an example a schema can be added as a module to a database to ensure that the data therein complies with set rules (so a database can be forced to be entirely LDAP compliant, as an example).


Another example of a module used with LDB is the password hash module. This sits between the database and the LDB API and ensures that passwords match password policies, and also performs any required encryption/decryption thereof.


More on Schemas

Raw LDB is schema-less, but it is designed to allow modules to enforce schema and add functionality. To begin with, there are no rules and regulations, and the LDB API allows for fast and easy setup of a database with minimal overheads. Further overheads can be added as required using modules (as mentioned above), and schema support can be added in this way.


It is through these schemas that we ensure that our databases are LDAP compliant. In this way, we can use LDB within Samba to allow us to communicate with other LDAP databases, and (what we are really aiming for) Active Directory.


Schema-less

an example of a schema-less database used within Samba is the secrets.ldb database. The reason that secrets.ldb doesn’t need a schema is because it is used only internally within Samba, so there is no need for the overhead of a schema. Because there is no schema attached, arbitrary data can be inserted into the database, for example we can modify a record to include a new attribute called “pet” with a value of our choosing, eg “cat”, and this is a perfectly acceptable thing to do. It is also possible that I have a thing for cats ;)

   # editing 1 records
   # record 1
   
   dn: samAccountName=dns-localdc,CN=Principals
   msDS-KeyVersionNumber: 1
   objectClass: top
   objectClass: secret
   objectClass: kerberosSecret
   privateKeytab: dns.keytab
   realm: SAMBA.EXAMPLE.COM
   sAMAccountName: dns-localdc
   secret: DZCb)wH]7uoDEd:q+ZmoC#P==0YAP(7.Dbz$6RA0l!KLx3sr#0]oV>eij3,=y@StOKNCn?k28ik%McPo&tPLnoyt0koqxm@NFe(aRn;YyD4fIkK4w>K=zBjUkv_LEGUCcoK_:7Q#0UC2CZx0WOV6pHu$aO
   servicePrincipalName: DNS/samba.example.com
   servicePrincipalName: DNS/localdc.samba.example.com
   objectGUID: 2f1d38f3-49b2-4baa-b77c-14c5daebadc0
   whenCreated: 20111005000141.0Z
   uSNCreated: 8
   name: dns-localdc
   pet: cat
   whenChanged: 20111005004406.0Z
   uSNChanged: 9
   distinguishedName: samAccountName=dns-localdc,CN=Principals

(note the sneaky inclusion of the new attribute just after the name attribute. Also note the plain text way in which the data has been written, this is called LDIF – LDAP Data Interchange Format. More on this in a later post)


Schema controlled

We can add a schema module to a database to ensure that it follows set rules. A schema would generally include information about what attributes are allowed, and constraints on data type, size, etc. Within Samba, the sam.ldb database is controlled by a schema. Schemas are only needed where the database communicates externally, so a schema provides valuable protection to ensure data compatibility. If we were to make an attempt to include the same pet: cat attribute and value pair within the sam.ldb database, the following error would be returned:

   Controllers,DC=samba,DC=example,DC=com - objectclass_attrs: attribute 'pet' on entry 'CN=LOCALDC,OU=Domain Controllers,DC=samba,DC=example,DC=com' was not found in the schema!


The schema for the sam.ldb database is compatible with the schema described within the Microsoft Active Directory Technical Specification http://msdn.microsoft.com/en-us/library/cc223122%28v=PROT.13%29.aspx


The schemas used are available for viewing online via the http accessible copy of Samba code.


http://samba.org/ftp/unpacked/samba_4_0_test/source4/setup/ad-schema/MS-AD_Schema_2K8_R2_Attributes.txt defines the attributes regardless of objectClass. The classes file determines which attributes are associated with each class


http://samba.org/ftp/unpacked/samba_4_0_test/source4/setup/ad-schema/MS-AD_Schema_2K8_R2_Classes.txt defines the objectClass and what attributes are allowed for a given class


LDB Tools

Each of the LDB tools is named appropriately to be quite self-explanatory in its functionality.


Common input (utilised by some or all of the tools):

-H ldburl (the local database or the url to it) eg -H st/dc/private/secrets.ldb

-H ldap://localhost

-H ldaps://hostname (ldap with ssl, runs on a different port number)

-H ldapi://path/ (unix domain sockets, i means internal (?), unix domain socket is a file that gives a communication path to a process on a unix box. Only within a machine, not over a network)


-s [one|sub|base] search scope, can be one level, subtree or base


-b basedn the distinguished name at which a search begins


LDAP-style search expression

A search expression can be as simple as (for example) seeking an object with a given distinguished name, or can become quite complex. Standard logic operators (and &, or |, not !) are able to be used within search expressions, with an arbitrary length of searches able to be done using each or any of these operators. Additional search parameters can be added by inserting further search strings within braces.


Using the & operator

(&(search expression 1)(search expression 2)(search expression 3)…(search expression n))


Using the | operator

(|(search expression 1)(search expression 2)(search expression 3)…(search expression n))


Using the ! operator

(!search expression 1)

The ! operator takes a single input


Using a mixture

(&(search expression 1)(search expression 2)(!search expression 3))

(|(search expression 1)(&(search expression 2)(search expression 3)))


Wildcard searches can also be performed using an * character, eg "samAccountName=kel*". A simple presence test can be performed by checking that an attribute has a value – any value – using a wildcard search: attribute=*


attributes

which attributes from the dataset to display, will display all if none selected. These are written to the end of the ldbsearch line with spaces between each attribute name (eg dn name realm objectGUID).


ldbsearch

This searches an LDB database for records that match the given parameters. LDB has a built in query optimiser that will attempt to use any indexed part of the search expression to reduce the reach of the search.


Common input parameters

-h help (displays a list of available options)

-H ldburl (database to connect to)

-s [one|base|sub] search scope (one-level, subtree or base)

-b basedn

-i read search expressions from stdin

LDAP-style search expression

(eg, ‘(&(objectclass=kerberossecret)(samaccountname=dns-localdc))’)

Attributes

which attributes from the dataset to display, will display not quite all if none selected (some are hidden, more on this later). These are written to the end of the ldbsearch line with spaces between each attribute name (eg name realm objectGUID)


as an example, an entire search command may look like this:

   bin/ldbsearch -H st/dc/private/secrets.ldb '(&(objectclass=kerberossecret)(samaccountname=dns-localdc))' name realm objectGUID

which would, in turn, produce the following information:

   # record 1
   
   dn: samAccountName=dns-localdc,CN=Principals
   realm: SAMBA.EXAMPLE.COM
   objectGUID: 2f1d38f3-49b2-4baa-b77c-14c5daebadc0
   name: dns-localdc
   
   # returned 1 records
   # 1 entries
   # 0 referrals

LDB pretty prints – eg, objectGUID is saved in binary form, but displayed in useful format


The following example returns the same database as our earlier tdbdump example. The data is in a much more readable format, and returned as a tree-like structure using LDAP style objects, attributes and values.

   username@computername:~/Samba/samba-master$ bin/ldbsearch -H st/dc/private/secrets.ldb
   
   # record 1
   dn: flatname=SAMBADOMAIN,cn=Primary Domains
   msDS-KeyVersionNumber: 1
   objectClass: top
   objectClass: primaryDomain
   objectClass: kerberosSecret
   objectSid: S-1-5-21-4122882817-868477147-3978206388
   privateKeytab: secrets.keytab
   realm: SAMBA.EXAMPLE.COM
   saltPrincipal: host/localdc.samba.example.com@SAMBA.EXAMPLE.COM
   samAccountName: LOCALDC$
   secret: machinelocDCpass1
   secureChannelType: 6
   servicePrincipalName: HOST/localdc
   servicePrincipalName: HOST/localdc.samba.example.com
   objectGUID: d55fd948-e32b-47c0-b7cf-f6fbb16deb1e
   whenCreated: 20111005000140.0Z
   whenChanged: 20111005000140.0Z
   uSNCreated: 7
   uSNChanged: 7
   name: SAMBADOMAIN
   flatname: SAMBADOMAIN
   distinguishedName: flatname=SAMBADOMAIN,cn=Primary Domains
   
   # record 2
   dn: CN=LSA Secrets
   cn: LSA Secrets
   objectClass: top
   objectClass: container
   objectGUID: 09bef02e-5144-4753-b133-59c2d3a445f1
   whenCreated: 20111005000046.0Z
   whenChanged: 20111005000046.0Z
   uSNCreated: 5
   uSNChanged: 5
   name: LSA Secrets
   distinguishedName: CN=LSA Secrets


The following examples return records of a specific objectClass – in this case person.


This example displays all information returned by default (albeit with some records removed for the sake of space)

   username@computername:~/Samba/samba-master$ bin/ldbsearch -H st/dc/private/sam.ldb '(objectclass=person)'
   # record 1
   dn: CN=LOCALDC,OU=Domain Controllers,DC=samba,DC=example,DC=com
   objectClass: top
   objectClass: person
   objectClass: organizationalPerson
   objectClass: user
   objectClass: computer
   cn: LOCALDC
   instanceType: 4
   whenCreated: 20111005000123.0Z
   uSNCreated: 3600
   name: LOCALDC
   objectGUID: 01cb8349-ff11-49ea-ab9d-6011afb44c95
   userAccountControl: 532480
   badPwdCount: 0
   codePage: 0
   countryCode: 0
   badPasswordTime: 0
   lastLogoff: 0
   lastLogon: 0
   localPolicyFlags: 0
   pwdLastSet: 129622464830000000
   primaryGroupID: 516
   objectSid: S-1-5-21-4122882817-868477147-3978206388-1000
   accountExpires: 9223372036854775807
   logonCount: 0
   sAMAccountName: LOCALDC$
   sAMAccountType: 805306369
   operatingSystem: Samba
   operatingSystemVersion: 4.0.0alpha18-DEVELOPERBUILD
   dNSHostName: localdc.samba.example.com
   objectCategory: CN=Computer,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=
    com
   isCriticalSystemObject: TRUE
   rIDSetReferences: CN=RID Set,CN=LOCALDC,OU=Domain Controllers,DC=samba,DC=exam
   ple,DC=com
   serverReferenceBL: CN=LOCALDC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,C
   N=Configuration,DC=samba,DC=example,DC=com
   msDS-SupportedEncryptionTypes: 31
   servicePrincipalName: HOST/localdc.samba.example.com
   servicePrincipalName: HOST/localdc.samba.example.com/SAMBADOMAIN
   servicePrincipalName: ldap/localdc.samba.example.com/SAMBADOMAIN
   servicePrincipalName: GC/localdc.samba.example.com/samba.example.com
   servicePrincipalName: ldap/localdc.samba.example.com
   servicePrincipalName: HOST/localdc.samba.example.com/samba.example.com
   servicePrincipalName: ldap/localdc.samba.example.com/samba.example.com
   servicePrincipalName: HOST/LOCALDC
   servicePrincipalName: E3514235-4B06-11D1-AB04-00C04FC2DCD2/9735e6ca-672f-44be-
   95ab-21014e97a26a/samba.example.com
   servicePrincipalName: ldap/9735e6ca-672f-44be-95ab-21014e97a26a._msdcs.samba.e
   xample.com
   servicePrincipalName: ldap/LOCALDC
   servicePrincipalName: RestrictedKrbHost/LOCALDC
   servicePrincipalName: RestrictedKrbHost/localdc.samba.example.com
   servicePrincipalName: ldap/localdc.samba.example.com/DomainDnsZones.samba.exam
   ple.com
   servicePrincipalName: ldap/localdc.samba.example.com/ForestDnsZones.samba.exam
   ple.com
   whenChanged: 20111005000213.0Z
   uSNChanged: 3734
   distinguishedName: CN=LOCALDC,OU=Domain Controllers,DC=samba,DC=example,DC=com
   
   # record 2
   dn: CN=LOCALRPCPROXY,CN=Computers,DC=samba,DC=example,DC=com
   objectClass: top
   objectClass: person
   objectClass: organizationalPerson
   objectClass: user
   objectClass: computer
   cn: LOCALRPCPROXY
   instanceType: 4
   whenCreated: 20111005002050.0Z
   uSNCreated: 6719
   name: LOCALRPCPROXY
   objectGUID: ea7e2e4f-830e-4cf1-9f84-a3a1c604d8aa
   badPwdCount: 0
   codePage: 0
   countryCode: 0
   badPasswordTime: 0
   lastLogoff: 0
   lastLogon: 0
   objectSid: S-1-5-21-4122882817-868477147-3978206388-1221
   accountExpires: 9223372036854775807
   logonCount: 0
   sAMAccountName: LOCALRPCPROXY$
   objectCategory: CN=Computer,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=
    com
   sAMAccountType: 805306369
   isCriticalSystemObject: FALSE
   primaryGroupID: 515
   pwdLastSet: 129622476500000000
   displayName: LOCALRPCPROXY$
   servicePrincipalName: HOST/localrpcproxy.samba.example.com
   servicePrincipalName: HOST/LOCALRPCPROXY
   dNSHostName: localrpcproxy.samba.example.com
   msDS-SupportedEncryptionTypes: 31
   userAccountControl: 16781312
   msDS-AllowedToDelegateTo: cifs/localdc
   whenChanged: 20111005002054.0Z
   uSNChanged: 6732
   distinguishedName: CN=LOCALRPCPROXY,CN=Computers,DC=samba,DC=example,DC=com
   
   # record 3
   dn: CN=RODC,OU=Domain Controllers,DC=samba,DC=example,DC=com
   objectClass: top
   objectClass: person
   objectClass: organizationalPerson
   objectClass: user
   objectClass: computer
   cn: RODC
   instanceType: 4
   whenCreated: 20111005002342.0Z
   displayName: RODC$
   uSNCreated: 6747
   name: RODC
   objectGUID: 2f32fc2c-04e6-4693-b8bc-d2721d8b6ec1
   badPwdCount: 0
   codePage: 0
   countryCode: 0
   badPasswordTime: 0
   lastLogoff: 0
   lastLogon: 0
   primaryGroupID: 521
   objectSid: S-1-5-21-4122882817-868477147-3978206388-1223
   accountExpires: 9223372036854775807
   logonCount: 0
   sAMAccountName: RODC$
   sAMAccountType: 805306369
   dNSHostName: RODC.samba.example.com
   managedBy: CN=Administrator,CN=Users,DC=samba,DC=example,DC=com
   objectCategory: CN=Computer,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=
   com
   isCriticalSystemObject: TRUE
   msDS-NeverRevealGroup: CN=Denied RODC Password Replication Group,CN=Users,DC=s
   amba,DC=example,DC=com
   msDS-NeverRevealGroup: CN=Administrators,CN=Builtin,DC=samba,DC=example,DC=com
   msDS-NeverRevealGroup: CN=Server Operators,CN=Builtin,DC=samba,DC=example,DC=c
   om
   msDS-NeverRevealGroup: CN=Backup Operators,CN=Builtin,DC=samba,DC=example,DC=c
   om
   msDS-NeverRevealGroup: CN=Account Operators,CN=Builtin,DC=samba,DC=example,DC=
   com
   msDS-RevealOnDemandGroup: CN=Allowed RODC Password Replication Group,CN=Users,
   DC=samba,DC=example,DC=com
   msDS-SupportedEncryptionTypes: 31
   whenChanged: 20111005002343.0Z
   msDS-KrbTgtLink: CN=krbtgt_2438,CN=Users,DC=samba,DC=example,DC=com
   serverReferenceBL: CN=RODC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=C
   onfiguration,DC=samba,DC=example,DC=com
   msDFSR-ComputerReferenceBL: CN=RODC,CN=Topology,CN=Domain System Volume,CN=DFS
   R-GlobalSettings,CN=System,DC=samba,DC=example,DC=com
   servicePrincipalName: HOST/RODC
   servicePrincipalName: HOST/RODC.samba.example.com
   servicePrincipalName: GC/RODC.samba.example.com/samba.example.com
   servicePrincipalName: RestrictedKrbHost/RODC
   servicePrincipalName: RestrictedKrbHost/RODC.samba.example.com
   pwdLastSet: 129622478230000000
   userAccountControl: 83890176
   uSNChanged: 6781
   distinguishedName: CN=RODC,OU=Domain Controllers,DC=samba,DC=example,DC=com
   
   …
   
   # Referral
   ref: ldap://samba.example.com/CN=Configuration,DC=samba,DC=example,DC=com
   
   # returned 10 records
   # 9 entries
   # 1 referrals 

This example is using the same search expression as above, although requesting only the name and managedBy attributes. Because managedBy is only used within some records, the others will not attempt to display it.

   username@computername:~/Samba/samba-master$ bin/ldbsearch -H st/dc/private/sam.ldb '(objectclass=person)' name managedby
   # record 1
   dn: CN=LOCALDC,OU=Domain Controllers,DC=samba,DC=example,DC=com
   name: LOCALDC
   
   # record 2
   dn: CN=LOCALRPCPROXY,CN=Computers,DC=samba,DC=example,DC=com
   name: LOCALRPCPROXY
   
   # record 3
   dn: CN=RODC,OU=Domain Controllers,DC=samba,DC=example,DC=com
   name: RODC
   managedBy: CN=Administrator,CN=Users,DC=samba,DC=example,DC=com
   
   # record 4
   dn: CN=Administrator,CN=Users,DC=samba,DC=example,DC=com
   name: Administrator
   
   # record 5
   dn: CN=S4MEMBER,CN=Computers,DC=samba,DC=example,DC=com
   name: S4MEMBER
   
   # record 6
   dn: CN=dns-localdc,CN=Users,DC=samba,DC=example,DC=com
   name: dns-localdc
   
   # record 7
   dn: CN=krbtgt_2438,CN=Users,DC=samba,DC=example,DC=com
   name: krbtgt_2438
   
   # record 8
   dn: CN=krbtgt,CN=Users,DC=samba,DC=example,DC=com
   name: krbtgt
   
   # record 9
   dn: CN=Guest,CN=Users,DC=samba,DC=example,DC=com
   name: Guest
   
   # Referral
   ref: ldap://samba.example.com/CN=Configuration,DC=samba,DC=example,DC=com
   
   # returned 10 records
   # 9 entries
   # 1 referrals 


ldbmodify

Modifies a database according to the contents of an input file of LDIF composition


Common input parameters:

-h help

-H ldburl

LDIF file

Example of usage:

   username@computername:~/Samba/samba-master$ bin/ldbmodify -H st/dc/private/secrets.ldb LDIFfilename

The LDIF files used with ldbmodify are a special form of LDIF that specify what is to be changed, where, how, etc. An example is displayed below:

  dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga
   n,c=TEST
  changetype: modify
  add: drink
  drink: mango lassi
  -
  add: drink
  drink: lemonade
  -
  delete: pager
  -
  replace: telephonenumber
  telephonenumber: +61 2 6260 6012
  telephonenumber: +61 412 666 929
  -
  delete: telephonenumber
  telephonenumber: +61 2 6260 6012
  -
  delete: telephonenumber
  telephonenumber: +61 412 666 929
  -
  add: telephonenumber
  telephonenumber: +61 412 666 929


Note: Any line beginning with a space character is a continuation of the line immediately preceeding it. Comments are denoted by # (eg, # I am a comment). There are more example LDIF files used within the samba test suites available in <samba-source-directory>/lib/ldb/tests. The dn attribute determines which record is to be modified.


ldbedit

Allows editing of record/s within an ldb database. Instead of feeding it a premade LDIF file as per ldbmodify, ldbedit takes a bunch of parameters (including search strings if desired) and generates an LDIF file on the fly that can then be modified using the editor of your choice (given with the -e input). The edited LDIF file then forms the input for the ldbmodify operation.


Common input parameters:

-h help

-H ldburl

-s [one|sub|base] search scope

-b basedn

-a all

-e editor of choice (eg, vim, emacs, etc)

-verbose

LDAP style search expression

attributes

Example of usage:

   username@computername:~/Samba/samba-master$ bin/ldbedit -e vim -H st/dc/private/sam.ldb '(samaccountname=guest)'

Would generate the following LDIF file, and display it within vim (ready for editing):

  # editing 1 records
  # record 1
  dn: CN=Guest,CN=Users,DC=samba,DC=example,DC=com
  objectClass: top
  objectClass: person
  objectClass: organizationalPerson
  objectClass: user
  cn: Guest
  description: Built-in account for guest access to the computer/domain
  instanceType: 4
  whenCreated: 20111005000123.0Z
  whenChanged: 20111005000123.0Z
  uSNCreated: 3563
  uSNChanged: 3563
  name: Guest
  objectGUID: c6be74bb-1b6f-411d-aba9-9efbe465136f
  userAccountControl: 66082
  badPwdCount: 0
  codePage: 0
  countryCode: 0
  badPasswordTime: 0
  lastLogoff: 0
  lastLogon: 0
  pwdLastSet: 0
  primaryGroupID: 514
  objectSid: S-1-5-21-4122882817-868477147-3978206388-501
  accountExpires: 9223372036854775807
  logonCount: 0
  sAMAccountName: Guest
  sAMAccountType: 805306368
  objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=samba,DC=example,DC=co
   m
  isCriticalSystemObject: TRUE
  memberOf: CN=Guests,CN=Builtin,DC=samba,DC=example,DC=com
  distinguishedName: CN=Guest,CN=Users,DC=samba,DC=example,DC=com

Once the contents of this file have been changed and saved, the modify takes place. The generated LDIF file has comments denoting how many records are within it, and the beginning of each new record.


ldbadd

This function takes an LDIF file and uses the contents to insert a new record into the LDB database. The distinguished name must be unique to all others within the database, and the LDIF file must comply with any applicable schema.

Common input parameters:

-h help

-H ldburl

LDIF file/s

Example of usage:

   username@computername:~/Samba/samba-master$ bin/ldbadd -H st/dc/private/secrets.ldb LDIFfilename


ldbdel

The function removes records from the database according to the distinguished name. An arbitrary number of records can be removed by way of additional dns on the command line, or use of wildcards. Common input parameters:

-h help

-H ldburl -r recursive. Can also use --recursive control

dn of record/s to be deleted

Example of usage:

   username@computername:~/Samba/samba-master$ bin/ldbmodify -H st/dc/private/secrets.ldb [dn1] [dn2*] [dn...]


Hidden Attributes

All operational attributes are hidden, but not all hidden attributes are operational. These attributes are not particularly well hidden, they just don’t show up in * search. You need to specify the name to get them.

Operation attributes are generated, not static. The data that they hold is generated from other attributes or from system information. They are read-only.

There are some non-operational, but hidden attributes which may be read-only, read-write or there are even some that are write-only (for example, changing password).

The database schema information contains an attribute called “SystemFlags”, which allows multiple values. If one of the values within this field is ‘FLAG_ATTR_IS_OPERATIONAL’ then this is a hidden or operational attribute.

Some hidden attributes are:

   replPropertyMetaData
   nTSecurityDescriptor
   msDS-BridgeHeadServersUsed
   msDS-Entry-Time-To-Die
   msDS-USNLastSyncSuccess

For example, we can view the ntSecurityDescriptor data for a record as follows:

   kelly@fizzgig:~/work/Samba/samba-master$ bin/ldbsearch -H st/dc/private/sam.ldb '(&(objectclass=person)(name=Guest))' name ntsecuritydescriptor
   
   # record 1
   dn: CN=Guest,CN=Users,DC=samba,DC=example,DC=com
   nTSecurityDescriptor: O:DAG:DAD:AI(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWP
   CRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;AO)(A;;RPLCLORC;
   ;;PS)(OA;;CR;ab721a53-1e2f-11d0-9819-00aa0040529b;;PS)(OA;;CR;ab721a54-1e2f-1
   1d0-9819-00aa0040529b;;PS)(OA;;CR;ab721a56-1e2f-11d0-9819-00aa0040529b;;PS)(O
   A;;RPWP;77b5b886-944a-11d1-aebd-0000f80367c1;;PS)(OA;;RPWP;e45795b2-9455-11d1
   -aebd-0000f80367c1;;PS)(OA;;RPWP;e45795b3-9455-11d1-aebd-0000f80367c1;;PS)(OA
   ;;RP;037088f8-0ae1-11d2-b422-00a0c968f939;;RS)(OA;;RP;4c164200-20c0-11d0-a768
   -00aa006e0529;;RS)(OA;;RP;bc0ac240-79a9-11d0-9020-00c04fc2d4cf;;RS)(A;;RC;;;A
   U)(OA;;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;;AU)(OA;;RP;77b5b886-944a-11d1
   -aebd-0000f80367c1;;AU)(OA;;RP;e45795b3-9455-11d1-aebd-0000f80367c1;;AU)(OA;;
   RP;e48d0154-bcf8-11d1-8702-00c04fb96050;;AU)(OA;;CR;ab721a53-1e2f-11d0-9819-0
   0aa0040529b;;WD)(OA;;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;;RS)(OA;;RPWP;bf
   967a7f-0de6-11d0-a285-00aa003049e2;;CA)(OA;;RP;46a9b11d-60ae-405a-b7e8-ff8a58
   d456d2;;S-1-5-32-560)(OA;;RPWP;6db69a1c-9422-11d1-aebd-0000f80367c1;;S-1-5-32
   -561)(OA;;RPWP;5805bc62-bdc9-4428-a5e2-856a0f4c185e;;S-1-5-32-561)(OA;CIID;RP
   ;4c164200-20c0-11d0-a768-00aa006e0529;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU
   )(OA;CIID;RP;4c164200-20c0-11d0-a768-00aa006e0529;bf967aba-0de6-11d0-a285-00a
   a003049e2;RU)(OA;CIID;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;4828cc14-1437-4
   5bc-9b07-ad6f015e5f28;RU)(OA;CIID;RP;5f202010-79a5-11d0-9020-00c04fc2d4cf;bf9
   67aba-0de6-11d0-a285-00aa003049e2;RU)(OA;CIID;RP;bc0ac240-79a9-11d0-9020-00c0
   4fc2d4cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)(OA;CIID;RP;bc0ac240-79a9-11
   d0-9020-00c04fc2d4cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)(OA;CIID;RP;59ba
   2f42-79a2-11d0-9020-00c04fc2d3cf;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)(OA;
   CIID;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;bf967aba-0de6-11d0-a285-00aa0030
   49e2;RU)(OA;CIID;RP;037088f8-0ae1-11d2-b422-00a0c968f939;4828cc14-1437-45bc-9
   b07-ad6f015e5f28;RU)(OA;CIID;RP;037088f8-0ae1-11d2-b422-00a0c968f939;bf967aba
   -0de6-11d0-a285-00aa003049e2;RU)(OA;CIID;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f
   608;bf967a86-0de6-11d0-a285-00aa003049e2;ED)(OA;CIID;RP;b7c69e6d-2cc7-11d2-85
   4e-00a0c983f608;bf967a9c-0de6-11d0-a285-00aa003049e2;ED)(OA;CIID;RP;b7c69e6d-
   2cc7-11d2-854e-00a0c983f608;bf967aba-0de6-11d0-a285-00aa003049e2;ED)(OA;CIID;
   RPLCLORC;;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)(OA;CIID;RPLCLORC;;bf967a9c
   -0de6-11d0-a285-00aa003049e2;RU)(OA;CIID;RPLCLORC;;bf967aba-0de6-11d0-a285-00
   aa003049e2;RU)(OA;CIID;RPWPCR;91e647de-d96f-4b70-9557-d63ff4f3ccd8;;PS)(A;CII
   D;RPWPCRCCDCLCLORCWOWDSDDTSW;;;EA)(A;CIID;LC;;;RU)(A;CIID;RPWPCRCCLCLORCWOWDS
   DSW;;;BA)S:AI(OU;CIIDSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6
   -11d0-a285-00aa003049e2;WD)(OU;CIIDSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1
   ;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)
   name: Guest
   
   # Referral
   ref: ldap://samba.example.com/CN=Configuration,DC=samba,DC=example,DC=com
   
   # returned 2 records
   # 1 entries
   # 1 referrals 

The ntSecurityDescriptor field is saved in binary format, and we can view it in readable format by using the –show-binary operator on the command line as follows:

   username@computername:~/Samba/samba-master$ bin/ldbsearch -H st/dc/private/sam.ldb '(&(objectclass=person)(name=Guest))' name ntsecuritydescriptor --show-binary
   
   # record 1
   dn: CN=Guest,CN=Users,DC=samba,DC=example,DC=com
   nTSecurityDescriptor: NDR: struct security_descriptor
   revision : SECURITY_DESCRIPTOR_REVISION_1 (1)
   type : 0x8c17 (35863)
   1: SEC_DESC_OWNER_DEFAULTED
   1: SEC_DESC_GROUP_DEFAULTED
   1: SEC_DESC_DACL_PRESENT
   0: SEC_DESC_DACL_DEFAULTED
   1: SEC_DESC_SACL_PRESENT
   0: SEC_DESC_SACL_DEFAULTED
   0: SEC_DESC_DACL_TRUSTED
   0: SEC_DESC_SERVER_SECURITY
   0: SEC_DESC_DACL_AUTO_INHERIT_REQ
   0: SEC_DESC_SACL_AUTO_INHERIT_REQ
   1: SEC_DESC_DACL_AUTO_INHERITED
   1: SEC_DESC_SACL_AUTO_INHERITED
   0: SEC_DESC_DACL_PROTECTED
   0: SEC_DESC_SACL_PROTECTED
   0: SEC_DESC_RM_CONTROL_VALID
   1: SEC_DESC_SELF_RELATIVE
   owner_sid : *
   owner_sid : S-1-5-21-4122882817-868477147-3978206388-512
   group_sid : *
   group_sid : S-1-5-21-4122882817-868477147-3978206388-512
   sacl : *
   sacl: struct security_acl
   revision : SECURITY_ACL_REVISION_ADS (4)
   size : 0x0078 (120)
   num_aces : 0x00000002 (2)
   aces: ARRAY(2)
   aces: struct security_ace
   type : SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT (7)
   flags : 0x52 (82)
   0: SEC_ACE_FLAG_OBJECT_INHERIT
   1: SEC_ACE_FLAG_CONTAINER_INHERIT
   0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
   0: SEC_ACE_FLAG_INHERIT_ONLY
   1: SEC_ACE_FLAG_INHERITED_ACE
   0x02: SEC_ACE_FLAG_VALID_INHERIT (2)
   1: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
   0: SEC_ACE_FLAG_FAILED_ACCESS
   size : 0x0038 (56)
   access_mask : 0x00000020 (32)
   object : union security_ace_object_ctr(case 7)
   object: struct security_ace_object
   flags : 0x00000003 (3)
   1: SEC_ACE_OBJECT_TYPE_PRESENT
   1: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
   type : union security_ace_object_type(case 1)
   type : f30e3bbe-9ff0-11d1-b603-0000f80367c1
   inherited_type : union security_ace_object_inherited_type(case 2)
   inherited_type : bf967aa5-0de6-11d0-a285-00aa003049e2
   trustee : S-1-1-0
   aces: struct security_ace
   type : SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT (7)
   flags : 0x52 (82)
   0: SEC_ACE_FLAG_OBJECT_INHERIT
   1: SEC_ACE_FLAG_CONTAINER_INHERIT
   0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
   0: SEC_ACE_FLAG_INHERIT_ONLY
   1: SEC_ACE_FLAG_INHERITED_ACE
   0x02: SEC_ACE_FLAG_VALID_INHERIT (2)
   1: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
   0: SEC_ACE_FLAG_FAILED_ACCESS
   size : 0x0038 (56)
   access_mask : 0x00000020 (32)
   object : union security_ace_object_ctr(case 7)
   object: struct security_ace_object
   flags : 0x00000003 (3)
   1: SEC_ACE_OBJECT_TYPE_PRESENT
   1: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
   type : union security_ace_object_type(case 1)
   type : f30e3bbf-9ff0-11d1-b603-0000f80367c1
   inherited_type : union security_ace_object_inherited_type(case 2)
   inherited_type : bf967aa5-0de6-11d0-a285-00aa003049e2
   trustee : S-1-1-0
   dacl : *
   dacl: struct security_acl
   revision : SECURITY_ACL_REVISION_ADS (4)
   size : 0x07d4 (2004)
   num_aces : 0x0000002c (44)
   aces: ARRAY(44)
   aces: struct security_ace
   type : SEC_ACE_TYPE_ACCESS_ALLOWED (0)
   flags : 0x00 (0)
   0: SEC_ACE_FLAG_OBJECT_INHERIT
   0: SEC_ACE_FLAG_CONTAINER_INHERIT
   0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
   0: SEC_ACE_FLAG_INHERIT_ONLY
   0: SEC_ACE_FLAG_INHERITED_ACE
   0x00: SEC_ACE_FLAG_VALID_INHERIT (0)
   0: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
   0: SEC_ACE_FLAG_FAILED_ACCESS
   size : 0x0024 (36)
   access_mask : 0x000f01ff (983551)
   object : union security_ace_object_ctr(case 0)
   trustee : S-1-5-21-4122882817-868477147-3978206388-512
   aces: struct security_ace
   type : SEC_ACE_TYPE_ACCESS_ALLOWED (0)
   flags : 0x00 (0)
   0: SEC_ACE_FLAG_OBJECT_INHERIT
   0: SEC_ACE_FLAG_CONTAINER_INHERIT
   0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
   0: SEC_ACE_FLAG_INHERIT_ONLY
   0: SEC_ACE_FLAG_INHERITED_ACE
   0x00: SEC_ACE_FLAG_VALID_INHERIT (0)
   0: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
   0: SEC_ACE_FLAG_FAILED_ACCESS
   size : 0x0014 (20)
   access_mask : 0x000f01ff (983551)
   object : union security_ace_object_ctr(case 0)
   trustee : S-1-5-18
   ##MASSIVE SNIP!!!
   name: Guest
   
   # Referral
   ref: ldap://samba.example.com/CN=Configuration,DC=samba, DC=example,DC=com
   
   # returned 2 records
   # 1 entries
   # 1 referrals 

Note the MASSIVE SNIP – this contains a LOT of information, only a very small section is displayed above. We will go into detail on what this data means and how it is used within Samba in a later post.

Following, some example on operation attributes and their use.

msDS-User-Account-Control-Computed

Official documentation on this attribute on ms-DS-User-Account-Control-Computed attribute.

This attribute contain some computed field that return the state of the account, like UF_LOCKOUT (account locked) or UF_PASSWORD_EXPIRED.
It is preferred to use this attribute and their field to check account status because the internal computation take into account the applied policy, even the Password Settings Objects.

Because this is an operational attribute, is by definition readonly, eg you can check account status but not alter it (eg: look for a locked account, but not unlock it).
Remaining in this example, to check for a locked account:

username@computername:~/Samba/samba-master$ bin/ldbsearch -H st/dc/private/sam.ldb '(&(objectclass=person)(name=Guest))' msDS-User-Account-Control-Computed

and look at proper bits in the attribute.

To forcibly unlock a locked account, the better way to act are to zero the lockoutTime attribute, see also Lockout-Time attribute on official documentation.

How LDB Indexing works

Indexing allows for faster searching of the database, and a database can generally be modified to include any relevant field or attribute of importance that may be frequently searched upon. LDB is no different. LDB keeps its indexing information in the @INDEXLIST record. The @INDEXLIST record can have multiple values that can be indexed, and each of these is listed as an @IDXATTR attribute.

Indexes can be viewed, modified, inserted or deleted as per other database components. A schema defines which attributes should be indexed. Edit the schema if you wish to edit the index list, or edit the @INDEXLIST if using a schema-less database. A database containing a full schema completely overrides the @INDEXLIST, which then becomes only an approximation of the index listing. The schema provides more detailed indexing instructions, such as how to sort/compare each attribute type.

LDB offers two types of indexing: Attribute indexing or one level indexing. Attribute indexing increases speed for a search on a specific value for an attribute. One level indexing improves speed of searching all child objects of a given object. To perform this, we keep an index of every DN within the database and any child DNs thereof.

A planned addition to indexing is range indexing, where records within a range of integer values can be requested. This will be added to increase speed of a search used within replication, and will be discussed further when we get into replication.

LDB does not currently support prefix indexing, eg searching for “name=kell*”. This was decided as the loss in write performance was not worth the gain in read performance. It may be added in future versions if prefix searches are frequently required.

   username@computername:~/Samba/samba-master$ bin/ldbsearch -H st/dc/private/secrets.ldb -s base -b @INDEXLIST
   
   # record 1
   dn: @INDEXLIST
   @IDXATTR: cn
   @IDXATTR: flatname
   @IDXATTR: realm
   distinguishedName: @INDEXLIST
   
   # returned 1 records
   # 1 entries
   # 0 referrals

rootDSE

The rootDSE provides user accessible metadata about the database. Some parts are pointers into the database, some parts are external references, some parts are information required to gather further information or to gain access to further information.


The rootDSE is the only record that can be accessed without authentication.


Within the rootDSE there are many numbers that look reasonably like this: 1.2.840.113556.1.4.800 – this is called an OID (or Object IDentifier). OIDs are widely used within many different protocols (not just LDAP), and there is a central authority for assigning OID-space. These OIDs are able to be searched on the internet to locate what they reference, for example a google search on 1.2.840.113556.1.4.800 returns http://www.oid-info.com/get/1.2.840.113556.1.4.800, which states: “If the RootDSE supportedCapabilities attribute contains this OID, it means the LDAP server is an Active Directory server (Win2k and later).”. Many OIDs are visible within the example rootDSE below, and each can be looked up to check for their meaning.

   username@computername:~/Samba/samba-master$ bin/ldbsearch -H ldap://localhost -s base -b ""
   
   # record 1
   
   dn:
   configurationNamingContext: CN=Configuration,DC=samba,DC=example,DC=com
   defaultNamingContext: DC=samba,DC=example,DC=com
   rootDomainNamingContext: DC=samba,DC=example,DC=com
   schemaNamingContext: CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com
   subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=samba,DC=example ,DC=com
   supportedCapabilities: 1.2.840.113556.1.4.800
   supportedCapabilities: 1.2.840.113556.1.4.1670
   supportedCapabilities: 1.2.840.113556.1.4.1791
   supportedCapabilities: 1.2.840.113556.1.4.1935
   supportedCapabilities: 1.2.840.113556.1.4.2080
   supportedLDAPVersion: 2
   supportedLDAPVersion: 3
   vendorName: Samba Team (http://samba.org)
   isSynchronized: TRUE
   dsServiceName: CN=NTDS Settings,CN=COMPUTERNAME,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=samba,DC=example,DC=com
   serverName: CN=COMPUTERNAME,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=samba,DC=example,DC=com
   dNSHostName: computername.samba.example.com
   ldapServiceName: samba.example.com:computername$@SAMBA.EXAMPLE.COM
   currentTime: 20111005012227.0Z
   supportedControl: 1.2.840.113556.1.4.841
   supportedControl: 1.2.840.113556.1.4.319
   supportedControl: 1.2.840.113556.1.4.473
   supportedControl: 1.2.840.113556.1.4.1504
   supportedControl: 1.2.840.113556.1.4.801
   supportedControl: 1.2.840.113556.1.4.801
   supportedControl: 1.2.840.113556.1.4.805
   supportedControl: 1.2.840.113556.1.4.529
   supportedControl: 1.2.840.113556.1.4.417
   supportedControl: 1.2.840.113556.1.4.2064
   supportedControl: 1.2.840.113556.1.4.1413
   supportedControl: 1.2.840.113556.1.4.1413
   supportedControl: 1.2.840.113556.1.4.1413
   supportedControl: 1.2.840.113556.1.4.1339
   supportedControl: 1.2.840.113556.1.4.1340
   supportedControl: 1.2.840.113556.1.4.1413
   supportedControl: 1.2.840.113556.1.4.1341
   namingContexts: DC=samba,DC=example,DC=com
   namingContexts: CN=Configuration,DC=samba,DC=example,DC=com
   namingContexts: CN=Schema,CN=Configuration,DC=samba,DC=example,DC=com
   supportedSASLMechanisms: GSS-SPNEGO
   supportedSASLMechanisms: GSSAPI
   supportedSASLMechanisms: NTLM
   highestCommittedUSN: 3731
   domainFunctionality: 2
   forestFunctionality: 2
   domainControllerFunctionality: 4
   isGlobalCatalogReady: TRUE
   
   # returned 1 records
   # 1 entries
   # 0 referrals

An excellent source of what the rootDSE contains is available at http://www.techgalaxy.net/Docs/Dev/LDAPv3%20RootDSE%20Overview.htm


Some parts of the rootDSE important to Samba are:

The naming contexts are extremely important within ActiveDirectory, these form sub-sections of the database that one would expect to reasonably contain a relevant subset of data. For example, configurationNamingContext points to where all configuration data may be found, defaultNamingContext would locate other subsections such as users, schemaNamingContext would point to the location of the schema information. On that last example, all of the contents of the schema lie within the subtree given by the schemaNamingContext, therefore the database is “introspective” – you need to look within the database for a description of itself. Users can query this subtree of the database to gain information on how the database as a whole should look and behave.


supportedCapabilities uses OIDs to describe what capabilities the server has.


supportedLDAPVersion displays which varieties of LDAP this server supports.


isSynchronized contains TRUE if replicated


dsServiceName is critical in ActiveDirectory. Each server in AD contains an NTDS (New Technology Directory Services) record containing all NTDS settings – information specific to that particular server, and the dsServiceName contains the DN to the object containing these settings. These settings are not contained within the rootDSE due to replication. The rootDSE is not replicated, but the configuration partition is replicated all over the forest, and by keeping these settings within a replicates partition we allow all domain controllers fast access to everyone else’s settings – ie to see capabilities, etc.


serverName points to an object that contains information such as server, DNS settings, netbios settings, etc.


dNSHostName is included within the rootDSE because Kerberos relies upon knowing the hostname to correctly authenticate, so we need access to this information BEFORE we can authenticate, therefore it needs to be located within a record that needs no authentication, thus the rootDSE.


supportedControl uses OIDs to describe what controls are supported by the server. Controls are a way that an LDAP client can ask for different behaviour for a particular operation from a server. There are only a few controls that an AD administrator might want to use, but controls can be very useful for developers. More information on these controls will be included in a later post.


namingContexts is a sub-section or partition of the database. The significance is that a search will, by default, not cross a naming context boundary. A naming context can be a child of another, in a hierarchy. If we do a search that starts at a lower level it will not, by default, cross boundaries to other naming contexts. –cross-ncs option (phantom root option, thus called because it effectively declares the root of the subtree to be at a higher level even though we are searching from lower) allows you to cross these boundaries.


highestCommittedUSN declares how many changes have been made to this database.


domainFunctionality and forestFunctionality when MS changes the way AD works they add a new functionality level. This tells what functionality level the machine has been upgraded to


LDB versioning

To produce a new LDB version:

  • Bump the VERSION in lib/ldb/wscript
  • ./configure.developer --extra-python=/usr/bin/python3 && make -j
  • 'git add' the lib/ldb/ABI/*$VERSION.sigs produced by the make
  • Commit your changes. In the commit message, state what changes/bug fixes went into the new version (i.e. check 'gitk lib/ldb/').