This file is indexed.

/usr/share/tomcat7-docs/docs/funcspecs/fs-jndi-realm.html is in tomcat7-docs 7.0.52-1ubuntu0.16.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
<html><head><META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Catalina Functional Specifications (7.0.52) - JNDIRealm</title><meta name="author" content="Craig McClanahan"><style type="text/css" media="print">
            .noPrint {display: none;}
            td#mainBody {width: 100%;}
        </style><style type="text/css">
            code {background-color:rgb(224,255,255);padding:0 0.1em;}
            code.attributeName, code.propertyName {background-color:transparent;}
        </style><style type="text/css">
            .wrapped-source code { display: block; background-color: transparent; }
            .wrapped-source div { margin: 0 0 0 1.25em; }
            .wrapped-source p { margin: 0 0 0 1.25em; text-indent: -1.25em; }
        </style><style type="text/css">
            p.notice {
                border: 1px solid rgb(255, 0, 0);
                background-color: rgb(238, 238, 238);
                color: rgb(0, 51, 102);
                padding: 0.5em;
                margin: 1em 2em 1em 1em;
            }
        </style></head><body bgcolor="#ffffff" text="#000000" link="#525D76" alink="#525D76" vlink="#525D76"><table border="0" width="100%" cellspacing="0"><!--PAGE HEADER--><tr><td><!--PROJECT LOGO--><a href="http://tomcat.apache.org/"><img src="../images/tomcat.gif" align="right" alt="
      Catalina Functional Specifications
    " border="0"></a></td><td><h1><font face="arial,helvetica,sanserif">Apache Tomcat 7</font></h1><font face="arial,helvetica,sanserif">Version 7.0.52, Oct 10 2018</font></td><td><!--APACHE LOGO--><a href="http://www.apache.org/"><img src="../images/asf-logo.gif" align="right" alt="Apache Logo" border="0"></a></td></tr></table><table border="0" width="100%" cellspacing="4"><!--HEADER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><tr><!--LEFT SIDE NAVIGATION--><td width="20%" valign="top" nowrap class="noPrint"><p><strong>Links</strong></p><ul><li><a href="../index.html">Docs Home</a></li><li><a href="index.html">Functional Specs</a></li><li><a href="http://wiki.apache.org/tomcat/FAQ">FAQ</a></li><li><a href="#comments_section">User Comments</a></li></ul><p><strong>Administrative Apps</strong></p><ul><li><a href="fs-admin-apps.html">Overall Requirements</a></li><li><a href="mbean-names.html">Tomcat MBean Names</a></li><li><a href="fs-admin-objects.html">Administered Objects</a></li><li><a href="fs-admin-opers.html">Supported Operations</a></li></ul><p><strong>Internal Servlets</strong></p><ul><li><a href="fs-default.html">Default Servlet</a></li></ul><p><strong>Realm Implementations</strong></p><ul><li><a href="fs-jdbc-realm.html">JDBC Realm</a></li><li><a href="fs-jndi-realm.html">JNDI Realm</a></li><li><a href="fs-memory-realm.html">Memory Realm</a></li></ul></td><!--RIGHT SIDE MAIN BODY--><td width="80%" valign="top" align="left" id="mainBody"><h1>JNDIRealm</h1><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Table of Contents"><!--()--></a><a name="Table_of_Contents"><strong>Table of Contents</strong></a></font></td></tr><tr><td><blockquote>
<ul><li><a href="#Overview">Overview</a><ol><li><a href="#Introduction">Introduction</a></li><li><a href="#External_Specifications">External Specifications</a></li><li><a href="#Implementation_Requirements">Implementation Requirements</a></li></ol></li><li><a href="#Dependencies">Dependencies</a><ol><li><a href="#Environmental_Dependencies">Environmental Dependencies</a></li><li><a href="#Container_Dependencies">Container Dependencies</a></li></ol></li><li><a href="#Functionality">Functionality</a><ol><li><a href="#Operational_Modes">Operational Modes</a></li><li><a href="#Administrator_Login_Mode_Functionality">Administrator Login Mode Functionality</a></li><li><a href="#Username_Login_Mode_Functionality">Username Login Mode Functionality</a></li></ol></li><li><a href="#Testable_Assertions">Testable Assertions</a></li></ul>
</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Overview"><strong>Overview</strong></a></font></td></tr><tr><td><blockquote>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Introduction"><strong>Introduction</strong></a></font></td></tr><tr><td><blockquote>

    <p>The purpose of the <strong>JNDIRealm</strong> implementation is to
    provide a mechanism by which Tomcat can acquire information needed
    to authenticate web application users, and define their security roles,
    from a directory server or other service accessed via JNDI APIs.  For
    integration with Catalina, this class must implement the
    <code>org.apache.catalina.Realm</code> interface.</p>

    <p>This specification reflects a combination of functionality that is
    already present in the <code>org.apache.catalina.realm.JNDIRealm</code>
    class, as well as requirements for enhancements that have been
    discussed.  Where appropriate, requirements statements are marked
    <em>[Current]</em> and <em>[Requested]</em> to distinguish them.</p>

    <p>The current status of this functional specification is
    <strong>PROPOSED</strong>.  It has not yet been discussed and
    agreed to on the TOMCAT-DEV mailing list.</p>

    <p>The code in the current version of <code>JNDIRealm</code>, and the
    ideas expressed in this functional specification, are the results of
    contributions from many individuals, including (alphabetically):</p>
    <ul>
    <li>Holman, John &lt;j.g.holman@qmw.ac.uk&gt;</li>
    <li>Lockhart, Ellen &lt;elockhart@home.com&gt;</li>
    <li>McClanahan, Craig &lt;craigmcc@apache.org&gt;</li>
    </ul>

  </blockquote></td></tr></table>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="External Specifications"><!--()--></a><a name="External_Specifications"><strong>External Specifications</strong></a></font></td></tr><tr><td><blockquote>

    <p>The implementation of this functionality depends on the following
    external specifications:</p>
    <ul>
    <li><a href="http://java.sun.com/products/jndi/">Java Naming and
        Directory Interface</a> (version 1.2.1 or later)</li>
    </ul>

  </blockquote></td></tr></table>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Implementation Requirements"><!--()--></a><a name="Implementation_Requirements"><strong>Implementation Requirements</strong></a></font></td></tr><tr><td><blockquote>

    <p>The implementation of this functionality shall conform to the
    following requirements:</p>
    <ul>
    <li>Be realized in one or more implementation classes.</li>
    <li>Implement the <code>org.apache.catalina.Realm</code> interface.
        [Current]</li>
    <li>Implement the <code>org.apache.catalina.Lifecycle</code>
        interface.  [Current]</li>
    <li>Subclass the <code>org.apache.catalina.realm.RealmBase</code>
        base class.</li>
    <li>Live in the <code>org.apache.catalina.realm</code> package.
        [Current]</li>
    <li>Support a configurable debugging detail level. [Current]</li>
    <li>Log debugging and operational messages (suitably internationalized)
        via the <code>getContainer().log()</code> method. [Current]</li>
    </ul>

  </blockquote></td></tr></table>


</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Dependencies"><strong>Dependencies</strong></a></font></td></tr><tr><td><blockquote>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Environmental Dependencies"><!--()--></a><a name="Environmental_Dependencies"><strong>Environmental Dependencies</strong></a></font></td></tr><tr><td><blockquote>

    <p>The following environmental dependencies must be met in order for
    JNDIRealm to operate correctly:</p>
    <ul>
    <li>The desire to utilize JNDIRealm must be registered in
        <code>$CATALINA_BASE/conf/server.xml</code>, in a
        <code>&lt;Realm&gt;</code> element that is nested inside a
        corresponding <code>&lt;Engine&gt;</code>, <code>&lt;Host&gt;</code>,
        or <code>&lt;Context&gt;</code> element.</li>
    <li>If the <em>Administrator Login</em> operational mode is selected,
        the configured administrator username and password must be configured
        in the corresponding directory server.</li>
    <li>If the <em>Username Login</em> operational mode is selected,
        the corresponding directory server must be configured to accept
        logins with the username and password that will be passed to
        <code>JNDIRealm</code> by the appropriate <code>Authenticator</code>.
        </li>
    </ul>

  </blockquote></td></tr></table>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Container Dependencies"><!--()--></a><a name="Container_Dependencies"><strong>Container Dependencies</strong></a></font></td></tr><tr><td><blockquote>

    <p>Correct operation of JNDIRealm depends on the following
    specific features of the surrounding container:</p>
    <ul>
    <li>Interactions with <code>JNDIRealm</code> will be initiated by
        the appropriate <code>Authenticator</code> implementation, based
        on the login method that is selected.</li>
    </ul>

  </blockquote></td></tr></table>


</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Functionality"><strong>Functionality</strong></a></font></td></tr><tr><td><blockquote>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Operational Modes"><!--()--></a><a name="Operational_Modes"><strong>Operational Modes</strong></a></font></td></tr><tr><td><blockquote>

    <p>The completed <code>JNDIRealm</code> must support two major operational
    modes in order to support all of the required use cases.  For the purposes
    of this document, the modes are called <em>administrator login</em> and
    <em>Username Login</em>.  They are described further in the following
    paragraphs.</p>

    <p>For <em>Administrator Login</em> mode, <code>JNDIRealm</code> will be
    configured to establish one or more connections (using a connection pool)
    to an appropriate directory server, using JNDI APIs, under a "system
    administrator" username and password.  This is similar to the approach
    normally used to configure <code>JDBCRealm</code> to access authentication
    and access control information in a database.  It is assumed that the
    system administrator username and password that are configured provide
    sufficient privileges within the directory server to read (but not modify)
    the username, password, and assigned roles for each valid user of the
    web application associated with this <code>Realm</code>.  The password
    can be stored in cleartext, or in one of the digested modes supported by
    the <code>org.apache.catalina.realm.RealmBase</code> base class.</p>

    <p>For <em>Username Login</em> mode, <code>JNDIRealm</code> does not
    normally remain connected to the directory server.  Instead, whenever a
    user is to be authenticated, a connection to the directory server
    (using the username and password received from the authenticator) is
    attempted.  If this connection is successful, the user is assumed to be
    successfully authenticated.  This connection is then utilized to read
    the corresponding security roles associated with this user, and the
    connection is then broken.</p>

    <p><strong>NOTE</strong> - <em>Username Login</em> mode cannot be used
    if you have selected login method <code>DIGEST</code> in your web
    application deployment descriptor (<code>web.xml</code>) file.  This
    restriction exists because the cleartext password is never available
    to the container, so it is not possible to bind to the directory server
    using the user's username and password.</p>

    <p>Because these operational modes work so differently, the functionality
    for each mode will be described separately.  Whether or not both modes
    are actually supported by a single class (versus a class per mode) is
    an implementation detail left to the designer.</p>

    <p><strong>NOTE</strong> - The current implementation only implements
    part of the <em>Administrator Lookup</em> mode requirements.  It does
    not support the <em>Username Lookup</em> mode at all, at this point.</p>

  </blockquote></td></tr></table>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Administrator Login Mode Functionality"><!--()--></a><a name="Administrator_Login_Mode_Functionality"><strong>Administrator Login Mode Functionality</strong></a></font></td></tr><tr><td><blockquote>


    <h3>Configurable Properties</h3>

    <p>The implementation shall support the following properties
    that can be configured with JavaBeans property setters:</p>
    <ul>
    <li><code>connectionURL</code> - URL of the directory server we will
        be contacting.</li>
    <li><code>contextFactory</code> - Fully qualified class name of the JNDI
        context factory used to retrieve our InitialContext.
        [com.sun.jndi.ldap.LdapCtxFactory]</li>
    <li>Additional configuration properties required to establish the
        appropriate connection.  [Requested]</li>
    <li>Connection pool configuration properties.  [Requested]</li>
    <li>Configuration properties defining how a particular user is
        authenticated.  The following capabilities should be supported:
        <ul>
        <li>Substitute the specified username into a string.  [Requested]</li>
        <li>Retrieve the distinguished name (DN) of an authorized user via an
            LDAP search string with a replacement placeholder for the
            username, and comparison of the password to a configurable
            attribute retrieved from the search result.  [Current]</li>
        </ul></li>
    <li>Configuration properties defining how the roles associated with a
        particular authenticated user can be retrieved.  The following
        approaches should be supported:
        <ul>
        <li>Retrieve a specified attribute (possibly multi-valued)
            from an LDAP search expression,
            with a replacement placeholder for the DN of the user.
            [Current]</li>
        <li>Retrieve a set of role names that are defined implicitly (by
            selecting principals that match a search pattern) rather than
            explicitly (by finding a particular attribute value).
            [Requested]</li>
        </ul></li>
    </ul>

    <h3>Lifecycle Functionality</h3>

    <p>The following processing must be performed when the <code>start()</code>
    method is called:</p>
    <ul>
    <li>Establish a connection to the configured directory server, using the
        configured system administrator username and password.  [Current]</li>
    <li>Configure and establish a connection pool of connections to the
        directory server.  [Requested]</li>
    </ul>

    <p>The following processing must be performed when the <code>stop()</code>
    method is called:</p>
    <ul>
    <li>Close any opened connections to the directory server.</li>
    </ul>


    <h3>Method authenticate() Functionality</h3>

    <p>When <code>authenticate()</code> is called, the following processing
    is required:</p>
    <ul>
    <li>Acquire the one and only connection [Current] or acquire a connection
        from the connection pool [Requested].</li>
    <li>Authenticate the user by retrieving the user's Distinguished Name,
        based on the specified username and password.</li>
    <li>If the user was not authenticated, release the allocated connection
        and return <code>null</code>.</li>
    <li>Acquire a <code>List</code> of the security roles assigned to the
        authenticated user.</li>
    <li>Construct a new instance of class
        <code>org.apache.catalina.realm.GenericPrincipal</code>, passing as
        constructor arguments:  this realm instance, the authenticated
        username, and a <code>List</code> of the security roles associated
        with this user.</li>
    <li><strong>WARNING</strong> - Do not attempt to cache and reuse previous
        <code>GenericPrincipal</code> objects for a particular user, because
        the information in the directory server might have changed since the
        last time this user was authenticated.</li>
    <li>Return the newly constructed <code>GenericPrincipal</code>.</li>
    </ul>


    <h3>Method hasRole() Functionality</h3>

    <p>When <code>hasRole()</code> is called, the following processing
    is required:</p>
    <ul>
    <li>The <code>principal</code> that is passed as an argument SHOULD
        be one that we returned (instanceof class
        <code>org.apache.catalina.realm.GenericPrincipal</code>, with a
        <code>realm</code> property that is equal to our instance.</li>
    <li>If the passed <code>principal</code> meets these criteria, check
        the specified role against the list returned by
        <code>getRoles()</code>, and return <code>true</code> if the
        specified role is included; otherwise, return <code>false</code>.</li>
    <li>If the passed <code>principal</code> does not meet these criteria,
        return <code>false</code>.</li>
    </ul>

  </blockquote></td></tr></table>


  <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Username Login Mode Functionality"><!--()--></a><a name="Username_Login_Mode_Functionality"><strong>Username Login Mode Functionality</strong></a></font></td></tr><tr><td><blockquote>

    <h3>Configurable Properties</h3>

    <p>The implementation shall support the following properties
    that can be configured with JavaBeans property setters:</p>
    <ul>
    <li><code>connectionURL</code> - URL of the directory server we will
        be contacting.</li>
    <li><code>contextFactory</code> - Fully qualified class name of the JNDI
        context factory used to retrieve our InitialContext.
        [com.sun.jndi.ldap.LdapCtxFactory]</li>
    <li>Additional configuration properties required to establish the
        appropriate connection.  [Requested]</li>
    <li>Connection pool configuration properties.  [Requested]</li>
    <li>Configuration properties defining if and how a user might be looked
        up before binding to the directory server.  The following approaches
        should be supported:
        <ul>
        <li>No previous lookup is required - username specified by the user
            is the same as that used to authenticate to the directory
            server.</li>
        <li>Substitute the specified username into a string.</li>
        <li>Search the directory server based on configured criteria to
            retrieve the distinguished name of the user, then attempt to
            bind with that distinguished name.</li>
        </ul></li>
    <li>Configuration properties defining how the roles associated with a
        particular authenticated user can be retrieved.  The following
        approaches should be supported:
        <ul>
        <li>Retrieve a specified attribute (possibly multi-valued)
            from an LDAP search expression,
            with a replacement placeholder for the DN of the user.
            [Current]</li>
        </ul></li>
    </ul>

    <h3>Lifecycle Functionality</h3>

    <p>The following processing must be performed when the <code>start()</code>
    method is called:</p>
    <ul>
    <li>None required.</li>
    </ul>

    <p>The following processing must be performed when the <code>stop()</code>
    method is called:</p>
    <ul>
    <li>None required.</li>
    </ul>


    <h3>Method authenticate() Functionality</h3>

    <p>When <code>authenticate()</code> is called, the following processing
    is required:</p>
    <ul>
    <li>Attempt to bind to the directory server, using the username and
        password provided by the user.</li>
    <li>If the user was not authenticated, release the allocated connection
        and return <code>null</code>.</li>
    <li>Acquire a <code>List</code> of the security roles assigned to the
        authenticated user.</li>
    <li>Construct a new instance of class
        <code>org.apache.catalina.realm.GenericPrincipal</code>, passing as
        constructor arguments:  this realm instance, the authenticated
        username, and a <code>List</code> of the security roles associated
        with this user.</li>
    <li><strong>WARNING</strong> - Do not attempt to cache and reuse previous
        <code>GenericPrincipal</code> objects for a particular user, because
        the information in the directory server might have changed since the
        last time this user was authenticated.</li>
    <li>Return the newly constructed <code>GenericPrincipal</code>.</li>
    </ul>


    <h3>Method hasRole() Functionality</h3>

    <p>When <code>hasRole()</code> is called, the following processing
    is required:</p>
    <ul>
    <li>The <code>principal</code> that is passed as an argument SHOULD
        be one that we returned (instanceof class
        <code>org.apache.catalina.realm.GenericPrincipal</code>, with a
        <code>realm</code> property that is equal to our instance.</li>
    <li>If the passed <code>principal</code> meets these criteria, check
        the specified role against the list returned by
        <code>getRoles()</code>, and return <code>true</code> if the
        specified role is included; otherwise, return <code>false</code>.</li>
    <li>If the passed <code>principal</code> does not meet these criteria,
        return <code>false</code>.</li>
    </ul>

  </blockquote></td></tr></table>

</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Testable Assertions"><!--()--></a><a name="Testable_Assertions"><strong>Testable Assertions</strong></a></font></td></tr><tr><td><blockquote>

  <p>In addition the the assertions implied by the functionality requirements
  listed above, the following additional assertions shall be tested to
  validate the behavior of <code>JNDIRealm</code>:</p>
  <ul>
  </ul>

</blockquote></td></tr></table></td></tr><tr class="noPrint"><td width="20%" valign="top" nowrap class="noPrint"></td><td width="80%" valign="top" align="left"><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="comments_section" id="comments_section"><strong>Comments</strong></a></font></td></tr><tr><td><blockquote><p class="notice"><strong>Notice: </strong>This comments section collects your suggestions
              on improving documentation for Apache Tomcat.<br><br>
              If you have trouble and need help, read
              <a href="http://tomcat.apache.org/findhelp.html">Find Help</a> page
              and ask your question on the tomcat-users
              <a href="http://tomcat.apache.org/lists.html">mailing list</a>.
              Do not ask such questions here. This is not a Q&amp;A section.<br><br>
              The Apache Comments System is explained <a href="../comments.html">here</a>.
              Comments may be removed by our moderators if they are either
              implemented or considered invalid/off-topic.</p><script type="text/javascript"><!--//--><![CDATA[//><!--
              var comments_shortname = 'tomcat';
              var comments_identifier = 'http://tomcat.apache.org/tomcat-7.0-doc/funcspecs/fs-jndi-realm.html';
              (function(w, d) {
                  if (w.location.hostname.toLowerCase() == "tomcat.apache.org") {
                      d.write('<div id="comments_thread"><\/div>');
                      var s = d.createElement('script');
                      s.type = 'text/javascript';
                      s.async = true;
                      s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
                      (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
                  }
                  else {
                      d.write('<div id="comments_thread"><strong>Comments are disabled for this page at the moment.<\/strong><\/div>');
                  }
              })(window, document);
              //--><!]]></script></blockquote></td></tr></table></td></tr><!--FOOTER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><!--PAGE FOOTER--><tr><td colspan="2"><div align="center"><font color="#525D76" size="-1"><em>
        Copyright &copy; 1999-2018, Apache Software Foundation
        </em></font></div></td></tr></table></body></html>