/usr/share/tomcat7-docs/docs/funcspecs/fs-jndi-realm.html is in tomcat7-docs 7.0.68-1.
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 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | <html><head><META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Catalina Functional Specifications (7.0.68) - 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;}
table {
border-collapse: collapse;
text-align: left;
}
table *:not(table) {
/* Prevent border-collapsing for table child elements like <div> */
border-collapse: separate;
}
th {
text-align: left;
}
div.codeBox pre code, code.attributeName, code.propertyName, code.noHighlight, .noHighlight code {
background-color: transparent;
}
div.codeBox {
overflow: auto;
margin: 1em 0;
}
div.codeBox pre {
margin: 0;
padding: 4px;
border: 1px solid #999;
border-radius: 5px;
background-color: #eff8ff;
display: table; /* To prevent <pre>s from taking the complete available width. */
/*
When it is officially supported, use the following CSS instead of display: table
to prevent big <pre>s from exceeding the browser window:
max-width: available;
width: min-content;
*/
}
div.codeBox pre.wrap {
white-space: pre-wrap;
}
table.defaultTable tr, table.detail-table tr {
border: 1px solid #CCC;
}
table.defaultTable tr:nth-child(even), table.detail-table tr:nth-child(even) {
background-color: #FAFBFF;
}
table.defaultTable tr:nth-child(odd), table.detail-table tr:nth-child(odd) {
background-color: #EEEFFF;
}
table.defaultTable th, table.detail-table th {
background-color: #88b;
color: #fff;
}
table.defaultTable th, table.defaultTable td, table.detail-table th, table.detail-table td {
padding: 5px 8px;
}
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.68, Feb 18 2016</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 <j.g.holman@qmw.ac.uk></li>
<li>Lockhart, Ellen <elockhart@home.com></li>
<li>McClanahan, Craig <craigmcc@apache.org></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://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html">
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><Realm></code> element that is nested inside a
corresponding <code><Engine></code>, <code><Host></code>,
or <code><Context></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 to 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&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 © 1999-2016, Apache Software Foundation
</em></font></div></td></tr></table></body></html>
|