{"id":781,"date":"2012-02-15T01:42:00","date_gmt":"2012-02-15T01:42:00","guid":{"rendered":"http:\/\/web03.partners.extranet.chrisse.com\/wordpress\/?p=781"},"modified":"2023-06-06T17:09:38","modified_gmt":"2023-06-06T15:09:38","slug":"how-the-active-directory-data-store-really-works-inside-ntds-dit-part-2","status":"publish","type":"post","link":"https:\/\/blog.chrisse.se\/?p=781","title":{"rendered":"How the Active Directory \u2013 Data Store Really Works (Inside NTDS.dit) \u2013 Part 2"},"content":{"rendered":"\n<p>This is the second post in a series of articles that will describe what&#8217;s really inside NTDS.dit and how Active Directory works on the database layer, In an earlier post I explained the tables within NTDS.dit in detail as far as what they are used for, in which release of Active Directory (Windows Server) they were introduced in, as well any major changes being added in later versions: <a href=\"http:\/\/blogs.chrisse.se\/blogs\/chrisse\/archive\/2012\/02\/11\/how-the-active-directory-data-store-really-works-inside-ntds-dit-part-1.aspx\">How the Active Directory \u2013 Data Store Really Works (Inside NTDS.dit) \u2013 Part 1<\/a><\/p>\n\n\n\n<p>This post will go into the details of the contents of the &#8220;datatable&#8221; also known as the object store \u2013 that contains all objects and phantoms [1.1] represented as rows (1 object\/phantom = 1 row in the table) from any instanced naming context (NC) held as either writable or read-only (until they are physically removed by the garbage-collector) by the Directory System Agent (DSA) hosting the database and where columns represent every [1:3] attribute present in the schema except linked attributes [1:2]<\/p>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[1.1]: phantoms are references to object&#8217;s hosted outside the given database (NTDS.DIT) and the given Directory System Agent (DSA) \u2013 (Except structural phantoms)<br><\/em><\/span><\/p>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[1:2] Post-Windows Server 2003 the attribute &#8220;ntSecurityDescriptor&#8221; is stored in the &#8220;sd_table&#8221; rather than in the &#8220;datatable&#8221;<br><\/em><\/span><\/p>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[1:3] Some columns doesn&#8217;t reflect attributes and are columns pre-defined in the NTDS.dit template database generated by Microsoft (those are needed for internal states to the DSA)<br><\/em><\/span><\/p>\n\n\n\n<p><strong>Maintain the hierarchy of an object tree within a flat object store<br><\/strong><\/p>\n\n\n\n<p>The hierarchy in Active Directory is quite obvious to most of us at a simplified layer e.g. daily administrative task such as creating an Organizational Unit and creates several descendent\/child objects under neat it, some people may refer to some objects as leaf objects (object that usually don&#8217;t contain descendent\/child objects) such as object of the class &#8220;user&#8221; \u2013 However the fact is that any object within Active Directory has the possibility (technically) to contain one or more descendent\/child objects \u2013 this is controlled by schema constrains and more specifically the sum of the following attributes of a given object class and any inherited class (except for auxiliary classes) :<\/p>\n\n\n\n<p><span style=\"font-family: Franklin Gothic Demi; font-size: 10pt;\">Table&nbsp;1: Possible Superiors<br><\/span><\/p>\n\n\n\n<div style=\"margin-left: 77pt;\">\n<table style=\"border-collapse: collapse;\" border=\"0\"><colgroup> <col style=\"width: 231px;\"> <col style=\"width: 407px;\"><\/colgroup>\n<tbody valign=\"top\">\n<tr style=\"background: #d9d9d9;\">\n<td style=\"border-width: 1.5pt 0.5pt 0.5pt 1.5pt; border-style: solid; border-color: gray; padding-right: 7px; padding-left: 7px;\" valign=\"middle\">\n<p style=\"text-align: center;\"><span style=\"font-family: Franklin Gothic Demi Cond; font-size: 9pt;\">Attribute<\/span><\/p>\n<\/td>\n<td style=\"border-width: 1.5pt 1.5pt 0.5pt medium; border-style: solid solid solid none; border-color: gray gray gray currentColor; padding-right: 7px; padding-left: 7px;\">\n<p style=\"text-align: center;\"><span style=\"font-family: Franklin Gothic Demi Cond; font-size: 9pt;\">Description<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border-width: medium 0.5pt 0.5pt 1.5pt; border-style: none solid solid; border-color: currentColor gray gray; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">possSuperiors<\/span><\/td>\n<td style=\"border-width: medium 1.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">Contains references to object classes that can host the given as a descendent\/child object.<\/span>\n<p>&nbsp;<\/p>\n<p>possSuperios can be modified on both cat1 and cat2 schema class object&#8217;s after that they have been instantiated in the schema.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border-width: medium 0.5pt 1.5pt 1.5pt; border-style: none solid solid; border-color: currentColor gray gray; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">systemPossSuperiors<\/span><\/td>\n<td style=\"border-width: medium 1.5pt 1.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">Contains references to object classes that can host the given as a descendent\/child object.<br><\/span>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: Arial; font-size: 9pt;\">systemPossSuperiors can&#8217;t be modified from the outside, once being instanced after the initial creation of the class within the schema.<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n\n\n\n<p>Why it&#8217;s easy for all objects to host descendants\/child objects becomes more obvious when the hierarchy is explained at the DBLayer.<\/p>\n\n\n\n<p>The question remains with the details given above, if one row within the &#8220;datatable&#8221; represents an object\/phantom, how can the hierarchy be maintained? The below table &#8220;Table 2&#8221; represent columns in the &#8220;datatable&#8221; that are vital for representing\/building the hierarchy in the directory at the DBLayer.<\/p>\n\n\n\n<p><span style=\"font-family: Franklin Gothic Demi; font-size: 10pt;\">Table&nbsp;2: datatable \u2013 Simplified for hierarchy representation 1<br><\/span><\/p>\n\n\n\n<div style=\"margin-left: 77pt;\">\n<table style=\"border-collapse: collapse;\" border=\"0\"><colgroup> <col style=\"width: 208px;\"> <col style=\"width: 130px;\"> <col style=\"width: 231px;\"> <col style=\"width: 376px;\"><\/colgroup>\n<tbody valign=\"top\">\n<tr style=\"background: #d9d9d9;\">\n<td style=\"border-width: 1.5pt 0.5pt 0.5pt 1.5pt; border-style: solid; border-color: gray; padding-right: 7px; padding-left: 7px;\" valign=\"middle\">\n<p style=\"text-align: center;\"><span style=\"font-family: Franklin Gothic Demi Cond; font-size: 9pt;\">Name<\/span><\/p>\n<\/td>\n<td style=\"border-width: 1.5pt 0.5pt 0.5pt medium; border-style: solid solid solid none; border-color: gray gray gray currentColor; padding-right: 7px; padding-left: 7px;\">\n<p style=\"text-align: center;\"><span style=\"font-family: Franklin Gothic Demi Cond; font-size: 9pt;\">ESE Data Type<\/span><\/p>\n<\/td>\n<td style=\"border-width: 1.5pt 0.5pt 0.5pt medium; border-style: solid solid solid none; border-color: gray gray gray currentColor; padding-right: 7px; padding-left: 7px;\">\n<p style=\"text-align: center;\"><span style=\"font-family: Franklin Gothic Demi Cond; font-size: 9pt;\">ESE Column Options (grbit)<\/span><\/p>\n<\/td>\n<td style=\"border-width: 1.5pt 1.5pt 0.5pt medium; border-style: solid solid solid none; border-color: gray gray gray currentColor; padding-right: 7px; padding-left: 7px;\">\n<p style=\"text-align: center;\"><span style=\"font-family: Franklin Gothic Demi Cond; font-size: 9pt;\">Description<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border-width: medium 0.5pt 0.5pt 1.5pt; border-style: none solid solid; border-color: currentColor gray gray; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">DNT_col<\/span><\/td>\n<td style=\"border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269213(v=exchg.10).aspx\"><span style=\"font-family: Arial; font-size: 9pt;\">JET_coltypLong<\/span><\/a><\/td>\n<td style=\"border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269194(v=exchg.10).aspx\"><span style=\"font-family: Arial; font-size: 9pt;\">JET_bitColumnFixed,<br>JET_bitColumnAutoincrement<\/span><\/a><\/td>\n<td style=\"border-width: medium 1.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">Every object\/phantom within the &#8220;datatable&#8221; contains a unique DNT value. <\/span>\n<p>&nbsp;<\/p>\n<p>DNT is a short for distinguished name tag.<\/p>\n<p>ESE enforces uniqueness by declaring DNT to be an ESE auto-incrementing column (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269194(v=exchg.10).aspx\">JET_bitColumnAutoincrement<\/a>.)<\/p>\n<p><span style=\"font-family: Arial; font-size: 9pt;\">DNT is the primary key of the &#8220;datatable&#8221;, so [2.1] objects are clustered in storage by DNT, and access to an object by DNT is more efficient than access via any other column\/attribute. Since new objects are created in ascending DNT order, the primary key organization does not slow down the creation of new objects.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border-width: medium 0.5pt 0.5pt 1.5pt; border-style: none solid solid; border-color: currentColor gray gray; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">PDNT_col<\/span><\/td>\n<td style=\"border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269213(v=exchg.10).aspx\"><span style=\"font-family: Arial; font-size: 9pt;\">JET_coltypLong<\/span><\/a><\/td>\n<td style=\"border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269194(v=exchg.10).aspx\"><span style=\"font-family: Arial; font-size: 9pt;\">JET_bitColumnFixed<\/span><\/a><\/td>\n<td style=\"border-width: medium 1.5pt 0.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">The PDNT column holds the DNT of the parent of an object [2.2].<\/span>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: Arial; font-size: 9pt;\">PDNT is a short for parent distinguished name tag.<\/span><\/p>\n<p>The tree structure of objects is not represented by pointers from parent to child, as you might expect given how the tree is normally browsed, but by a pointer in each child object\/row to its parent<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border-width: medium 0.5pt 1.5pt 1.5pt; border-style: none solid solid; border-color: currentColor gray gray; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">RDNTyp_col<\/span><\/td>\n<td style=\"border-width: medium 0.5pt 1.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269213(v=exchg.10).aspx\"><span style=\"font-family: Arial; font-size: 9pt;\">JET_coltypLong<\/span><\/a><\/td>\n<td style=\"border-width: medium 0.5pt 1.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269194(v=exchg.10).aspx\"><span style=\"font-family: Arial; font-size: 9pt;\">JET_bitColumnFixed<\/span><\/a><\/td>\n<td style=\"border-width: medium 1.5pt 1.5pt medium; border-style: none solid solid none; border-color: currentColor gray gray currentColor; padding-right: 7px; padding-left: 7px;\"><span style=\"font-family: Arial; font-size: 9pt;\">The RDNTyp_col holds the attributeID to the attribute being used as RDN, typically: cn (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms675449(v=vs.85).aspx\">Common-Name<\/a>), ou (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms679096(v=vs.85).aspx\">Organizational-Unit<\/a>), dc (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms675481(v=vs.85).aspx\">Domain-Component<\/a>), o (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms679009(v=vs.85).aspx\">Organization<\/a>) [2:3]<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[2.1]: The maximum numbers of objects\/phantoms that ever can be created on a given DSA (Domain Controller) for its entire life time is 2 billion objects (147,483,393 (231 minus 255)). Note that this count against objects\/phantoms ever introduced to the local DSA as part of any naming context (NC) writable or partial ever hosted by the DSA. * If the DSA is promoted by using IFM (Install from Media it inheritance the count of already allocated DNTs from the former DSA) \u2013 When the maximum numbers of auto-increment values has been used (the limit mention above have been hit) the following error are returned at the DBLayer: <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/gg269297(v=exchg.10).aspx\">JET_errOutOfAutoincrementValues -1076<\/a> from the outside we will notice: &#8220;Error: Add: Operations Error. &lt;1&gt; Server error: 000020EF: SvcErr: DSID-0208044C, problem 5012 (DIR_ERROR), data -1076.&#8221; Read more about Active Directory Limits: <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/active-directory-maximum-limits-scalability(v=ws.10).aspx#BKMK_Objects\">http:\/\/technet.microsoft.com\/en-us\/library\/active-directory-maximum-limits-scalability(v=ws.10).aspx#BKMK_Objects<\/a><br><\/em><\/span><\/p>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[2.2]: The first row introduced in the &#8220;datatable&#8221; isn&#8217;t a real object nor is it a phantom and is named &#8220;$NOT_AN_OBJECT1$&#8221; and have its PDNT_col set to NULL.<br>The &#8220;PDNT_col&#8221; is indexed so becomes very easy to drive an object&#8217;s direct-descendants\/child objects (not all descendants) by simply query who that has the object&#8217;s DNT in their PDNT_col.<br><\/em><\/span><\/p>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[2:3] The DSA has an in-memory cache for the most common RDNs (the ones mentioned above)<br>Active Directory allows us to use a custom attribute as RDN as well by specify the attributeID of that custom attribute as the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms679439(v=vs.85).aspx\">rDNAttID<\/a> for the particular class. * A RDN attribute must have the syntax string **customization may not be supported by all LDAPv3 clients. *** rDNAttID should preferably be set before any objects of the given class is instanced in the directory (changes won&#8217;t apply to already instanced\/existing objects)<br><\/em><\/span><\/p>\n\n\n\n<p>Let&#8217;s apply &#8220;Table 2&#8221; to a theoretical sample:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"943\" height=\"689\" src=\"https:\/\/blog.chrisse.se\/wp-content\/uploads\/2023\/06\/image-45.png\" alt=\"\" class=\"wp-image-1076\" srcset=\"https:\/\/blog.chrisse.se\/wp-content\/uploads\/2023\/06\/image-45.png 943w, https:\/\/blog.chrisse.se\/wp-content\/uploads\/2023\/06\/image-45-300x219.png 300w, https:\/\/blog.chrisse.se\/wp-content\/uploads\/2023\/06\/image-45-768x561.png 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[3.1]: &#8220;Name&#8221; represent the RDN attribute, it&#8217;s not stored\/named as described in the illustration above, it&#8217;s rather stored as &#8220;ATTm589825&#8221; I choose to represent it as &#8220;Name&#8221; for simplifying the understanding of the hierarchy in this case.<br><\/em><\/span><\/p>\n\n\n\n<p><span style=\"font-size: 8pt;\"><em>[3.2] Structural Phantom \u2013 (Different from a phantom used for reference integrity to real object&#8217;s hosted outside the given DIT) is used to represent the full distinguished name of the domain e.g &#8220;DC=ntdev,DC=corp,DC=chrisse,DC=com&#8221;<br><\/em><\/span><\/p>\n\n\n\n<p>In the next article \u2013 we will continue the deep-dive into the content and the structure of the &#8220;datatable&#8221; \u2013 going thru things like ancestors, the difference between phantoms and real objects, tombstones and the garbage collector on the DBLayer and much more.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the second post in a series of articles that will describe what&#8217;s really inside NTDS.dit and how Active Directory works on the database layer, In an earlier post I explained the tables within NTDS.dit in detail as far as what they are used for, in which release of Active Directory (Windows Server) they &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.chrisse.se\/?p=781\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How the Active Directory \u2013 Data Store Really Works (Inside NTDS.dit) \u2013 Part 2&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[6,14,16],"class_list":["post-781","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-active-directory","tag-extensible-storage-engine-ese","tag-ntds-dit"],"_links":{"self":[{"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=\/wp\/v2\/posts\/781","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=781"}],"version-history":[{"count":2,"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=\/wp\/v2\/posts\/781\/revisions"}],"predecessor-version":[{"id":1077,"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=\/wp\/v2\/posts\/781\/revisions\/1077"}],"wp:attachment":[{"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.chrisse.se\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}