Merge from debian.
[hcoop/debian/courier-authlib.git] / README_authlib.html.in
CommitLineData
d9898ee8 1<?xml version="1.0"?>
0fde1ce3 2<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><title>Courier Authentication Library</title><link rel="stylesheet" href="style.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.73.2"/><link rel="start" href="#authlib" title="Courier Authentication Library"/><link rel="next" href="#authpwd" title="The authpwd authentication module"/><link xmlns="" rel="stylesheet" type="text/css" href="manpage.css"/><meta xmlns="" name="MSSmartTagsPreventParsing" content="TRUE"/><link xmlns="" rel="icon" href="icon.gif" type="image/gif"/><!--
d9898ee8 3
4Copyright 1998 - 2007 Double Precision, Inc. See COPYING for distribution
5information.
6
0fde1ce3 7--></head><body><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="authlib" shape="rect"> </a>Courier Authentication Library</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#authpwd" shape="rect">The <code class="literal">authpwd</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authshadow" shape="rect">The <code class="literal">authshadow</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authpam" shape="rect">The <code class="literal">authpam</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authpipe" shape="rect">The <code class="literal">authpipe</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authpipeproto" shape="rect">The <code class="literal">authpipe</code> protocol</a></span></dt><dt><span class="sect1"><a href="#authuserdb" shape="rect">The <code class="literal">authuserdb</code> authentication module</a></span></dt><dd><dl><dt><span class="sect2"><a href="#userdbprimer" shape="rect">A brief <code class="literal">userdb</code> primer</a></span></dt><dt><span class="sect2"><a href="#userdbsimple" shape="rect">A simple userdb setup</a></span></dt><dt><span class="sect2"><a href="#userdbcomplex" shape="rect">Large virtual domain farm</a></span></dt><dt><span class="sect2"><a href="#moreuserdb" shape="rect">Beyond <code class="literal">userdb</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="#authmysql" shape="rect">The <code class="literal">authmysql</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authpgsql" shape="rect">The <code class="literal">authpgsql</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authldap" shape="rect">The <code class="literal">authldap</code> authentication module</a></span></dt><dt><span class="sect1"><a href="#authcustom" shape="rect"><code class="literal">authcustom</code></a></span></dt><dt><span class="sect1"><a href="#options" shape="rect">Account options</a></span></dt><dt><span class="sect1"><a href="#authtest" shape="rect">Running <span class="command"><strong>authtest</strong></span></a></span></dt><dd><dl><dt><span class="sect2"><a href="#pwchange" shape="rect">Changing account passwords</a></span></dt></dl></dd><dt><span class="sect1"><a href="#internals" shape="rect">Authentication internals</a></span></dt><dt><span class="sect1"><a href="#files" shape="rect">FILES</a></span></dt><dt><span class="sect1"><a href="#seealso" shape="rect">SEE ALSO</a></span></dt></dl></div><p>
d9898ee8 8This library is used for two purposes:</p><p>
91. Read the name of a mail account.
10Determine the local account's home directory, and system userid and
11groupid.</p><p>
122. Read an account name, and a password.
13If valid, determine the account's home directory, system userid, and
14groupid.</p><p>
15The term "authentication" is used in the following documentation to refer
16to either one of these two functions.
17The library contains several alternative authentication modules to choose
18from, described below.</p><p>
19The configuration file <code class="filename">@authdaemonrc@</code> contains several
20settings. The most important of them are:</p><div class="itemizedlist"><ul type="disc"><li><p>
21A list of authentication modules to activate.
22By default, this list includes all available authentication modules,
23even if some are not actually installed at the moment.
24When the authentication library is set up, only those authentication
25modules that can be supported by the operating system will be installed.
26Some of the listed modules may not actually be there,
27however that's not a problem.
28Any unavailable authentication modules will be ignored.
29Also, on some platforms certain authentication modules are installed by
30optional sub-packages.
31Installing the sub-package is the only action needed to make use of it.</p><p>
32The only time the list of authentication modules need to be adjusted is
33when an available authentication module must be disabled for some reason.
34This should only be needed in the most unusual circumstances.</p></li><li><p>
35Number of authentication processes.
36The default setting is to start five authentication processes, which should be
37sufficient for normal usage.
38Try increasing this setting if its taking too long to log into an account,
39and you have determined that this is not due to a bottleneck in the whatever
40authentication database you're using (LDAP, MySQL, or PostgreSQL).</p><p>
41An authentication request must be completed within thirty seconds, otherwise
42it gets rejected.
43When authentication requests come in faster than all five authentication
44processes can get to them, delays build up, and the timer is ticking.
45If all the activity maxes out the CPU or I/O bandwidth,
46nothing can be done about it, short
47of getting another server. However if there's plenty of available CPU and
48I/O, increasing the number of processes will do the trick.</p></li></ul></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authpwd" shape="rect"> </a>The <code class="literal">authpwd</code> authentication module</h2></div></div></div><p>
49This modules obtains account information and passwords from the
50<code class="filename">/etc/passwd</code> file.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
51This module doesn't actually read the <code class="filename">/etc/passwd</code>
52file, it uses the C library's getpw() functions.
53The C library implementation could use any mechanism to obtain the equivalent
54information.</p></div></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authshadow" shape="rect"> </a>The <code class="literal">authshadow</code> authentication module</h2></div></div></div><p>
55This module is a version of the <code class="literal">authpwd</code> module that
56reads passwords
57from <code class="filename">/etc/shadow</code> (the C library's getsp()
58functions).</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authpam" shape="rect"> </a>The <code class="literal">authpam</code> authentication module</h2></div></div></div><p>
59This modules uses the system's PAM library
60(pluggable authentication modules) for authentication.
61This is, essentially, a way to use existing PAM modules for authentication.
62Note, however, that the authenticated account's home directory, userid and
63groupid are still read from the <code class="filename">/etc/passwd</code> file,
64since PAM functionality is limited to validating account passwords.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
65Not all PAM modules are compatible with Courier's authentication library.
66PAM modules that make use of PAM's session functions, or authentication token
67functions, like <code class="literal">pam_krb5</code> will not work with Courier.</p></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
68Additional configuration steps will be required to set up
69the PAM library to authenticate Courier's services.
70Courier's IMAP and POP3 servers, for example, require that the
71“<span class="quote">imap</span>” and “<span class="quote">pop3</span>” PAM service to be
72configured.</p><p>
73The specific configuration steps differ from system to system.
74Consult the system documentation for more information.
75It might be tempting to throw in a towel and use
76<code class="literal">authshadow</code> or <code class="literal">authpwd</code>
77if you cannot figure out how to install PAM support,
78however that is not advisable.
79It is highly recommended to use
80<code class="filename">authpam</code> wherever the PAM library is available.</p><p>
81The exact configuration procedure depends on the PAM implementation.
82Most PAM libraries use configuration files in the
83<code class="filename">/etc/pam.d</code> directory.
84Therefore, it will be necessary to install the configuration files
85<code class="filename">/etc/pam.d/imap</code> and
86<code class="filename">/etc/pam.d/pop3</code>. Similarly, Courier's webmail
87server, SqWebMail, uses <code class="filename">/etc/pam.d/webmail</code>, and
88its optional calendar component uses <code class="filename">/etc/pam.d/webmail</code>.
89Courier-MTA's authenticated SMTP component uses the
90<code class="filename">/etc/pam.d/smtp</code> service.</p><p>
91In nearly all cases all these configuration files will specify an
92identical PAM library configuration for all services.
93The exact configuration details are site-specific.
94Here's an example of a PAM configuration file for a recent version of the
95most common PAM library:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
96auth required pam_nologin.so
97auth required pam_stack.so service=system-auth
98account required pam_stack.so service=system-auth
99session required pam_stack.so service=system-auth
100</pre></div><p>
101Again, the actual configuration is site specific.
102Examine the contents of existing configuration files in
103<code class="filename">/etc/pam.d</code> for similar services (if there's
104<code class="filename">/etc/pam.d/ppp</code>
105it's often a good example to follow) in order
106to derive the correct setup for Courier.</p><p>
107Older PAM libraries use a single configuration file, usually
108<code class="filename">/etc/pam.conf</code>.
109Append Courier-specific PAM settings to this configuration file, again
110using settings for existing services as a guide.
111For example:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
112imap auth required pam_unix.so try_first_pass
113imap account required pam_unix.so
114imap session required pam_permit.so
115pop3 auth required pam_unix.so try_first_pass
116pop3 account required pam_unix.so
117</pre></div><p>
118Some PAM libraries use
119<code class="filename">pam_pwdb.so</code> instead of
120<code class="filename">pam_unix.so</code>; consult the PAM library's
121documentation for more information.</p></div></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authpipe" shape="rect"> </a>The <code class="literal">authpipe</code> authentication module</h2></div></div></div><p>This is a generic plug-in module that runs an external script,
122or a program, in response to authentication requests.</p><p>The external program reads from stdin and writes to stdout. It
123can be persistent and handle many authentication requests. Only one request
124will be sent to it at a time; each authdaemon process starts its own copy of
125the external script.</p><p>The location of the external program is set by the
126<code class="literal">--with-pipeprog</code> configure option,
127which defaults to
128<code class="filename">@sysconfdir@/authlib/authProg</code>. A sample program
129is included in the courier-authlib source.</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authpipeproto" shape="rect"> </a>The <code class="literal">authpipe</code> protocol</h2></div></div></div><p>
130authpipe uses the same protocol as authdaemon clients use to communicate
131with authdaemond.</p><p>There are four possible requests: <code class="literal">PRE</code>,
132<code class="literal">AUTH</code>, <code class="literal">PASSWD</code> and
133<code class="literal">ENUMERATE</code>. Apart from <code class="literal">AUTH</code>, each
134request is a single line terminated by newline.
135</p><div class="variablelist"><dl><dt><span class="term">PRE . <em class="replaceable"><code>authservice</code></em> <em class="replaceable"><code>username</code></em> <span class="emphasis"><em>&lt;newline&gt;</em></span></span></dt><dd><p>Look up data for an account.
136 <em class="replaceable"><code>authservice</code></em> identifies the service the
137 user is trying to use - e.g. pop3, imap, webmail etc.</p><p>If the account exists, return the account
138 data as a series of ATTR=value newline-terminated lines, followed by a
139 period on a line of its own. Valid attributes are:
140 </p><pre class="screen" xml:space="preserve">
141 USERNAME=username -- system account which owns mailbox (name)
142 UID=uid -- system account which owns mailbox (numeric uid)
143 GID=gid -- numeric groupid
144 HOME=homedir -- home directory
145 ADDRESS=addr -- e-mail address
146 NAME=name -- full name
147 MAILDIR=maildir -- Maildir relative to home directory
148 QUOTA=quota -- quota string: maxbytesS,maxfilesC
149 PASSWD=cryptpasswd -- encrypted password
150 PASSWD2=plainpasswd -- plain text password
151 OPTIONS=acctoptions -- option1=val1,option2=val2,...
152 .
153 </pre><p>
154 Of these, it is mandatory to return ADDRESS, HOME, GID, and either UID
155 or USERNAME; the others are optional.
156 </p><p>If the account is not known, return <code class="literal">FAIL</code><span class="emphasis"><em><code class="literal">&lt;newline&gt;</code></em></span>.
157 If there is a temporary failure, such as a database being down, authProg
158 should terminate (thereby closing stdin/stdout) without sending any
159 response. authdaemon will restart the pipe module for the next
160 request, thus ensuring it is properly reinitialized.
161 </p></dd><dt><span class="term">AUTH <em class="replaceable"><code>len</code></em><span class="emphasis"><em>&lt;newline&gt;</em></span><em class="replaceable"><code>len-bytes</code></em></span></dt><dd><p>
162 Validate a login attempt. The AUTH line is followed by
163 <span class="emphasis"><em>len-bytes</em></span> of authentication data, which does not
164 necessarily end with a newline. The currently defined authentication
165 requests are:
166 </p><pre class="screen" xml:space="preserve">
167 login \n username \n password [\n] -- plaintext login
168 cram-md5 \n challenge \n response [\n] -- base-64 encoded challenge and response
169 cram-sha1 \n challenge \n response [\n] -- ditto
170 cram-sha256 \n challenge \n response [\n] -- ditto
171 </pre><p>
172 In the case of success, return the complete set of
173 account parameters in the same format as PRE, ending with a period on
174 a line of its own. In the case of failure (e.g. username does not exist,
175 password wrong, unsupported authentication type), return
176 <code class="literal">FAIL</code><span class="emphasis"><em><code class="literal">&lt;newline&gt;</code></em></span>.
177 If there is a temporary failure, such as a database being down, authProg
178 should terminate without sending any response.
179 </p><p>
180 Note: if the user provides a plaintext password and authenticates
181 successfully, then you can return it as PASSWD2 (plain text password)
182 even if the database contains an encrypted password. This is useful
183 when using the POP3/IMAP proxy functions of courier-imap.
184 </p></dd><dt><span class="term">PASSWD <em class="replaceable"><code>service</code></em><span class="emphasis"><em>&lt;tab&gt;</em></span>
185 <em class="replaceable"><code>username</code></em><span class="emphasis"><em>&lt;tab&gt;</em></span>
186 <em class="replaceable"><code>oldpasswd</code></em><span class="emphasis"><em>&lt;tab&gt;</em></span>
187 <em class="replaceable"><code>newpasswd</code></em><span class="emphasis"><em>&lt;tab&gt;</em></span>
188 <span class="emphasis"><em>&lt;newline&gt;</em></span>
189 </span></dt><dd><p>Request a password change for the given account: validate that
190 the oldpassword is correct, and if so, change it to the newpassword.
191 </p><p>Reply: the string
192 for success, or <code class="literal">FAIL</code><span class="emphasis"><em><code class="literal">&lt;newline&gt;</code></em></span> for
193 a data error (e.g. no such account, old password wrong, new password not
194 acceptable). In the case of a temporary failure, such as a database
195 being down, authProg should terminate without sending any response.
196 </p></dd><dt><span class="term">ENUMERATE <span class="emphasis"><em>&lt;newline&gt;</em></span></span></dt><dd><p>
197 Return a list of all accounts, one per line in the following format,
198 ending with a period on a line of its own:
199 </p><pre class="screen" xml:space="preserve">
200 username \t uid \t gid \t homedir \t maildir \t options \n
201 .
202 </pre><p>
203 If your module does not support the ENUMERATE command then return just
204 a period on a line of its own (which will still allow enumeration data
205 from other modules to be returned). In the case of a temporary failure,
206 such as a database being down or an error occuring mid-way through
207 returning account data, authProg should terminate before sending
208 the terminating period.
209 </p></dd></dl></div></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authuserdb" shape="rect"> </a>The <code class="literal">authuserdb</code> authentication module</h2></div></div></div><p>
210This module
211uses a GDBM or a DB-based
0fde1ce3 212<a class="ulink" href="userdb.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">userdb</span>(8)</span></a> database.
d9898ee8 213This module also incorporates userdb-based challenge-response authentication
214implementation that was done by a separate <code class="literal">authcram</code> module
215in previous versions of the Courier authentication library.</p><p>
216<code class="filename">@sysconfdir@/authlib/userdb</code> is a plain file that
217can be edited with any text editor.
218The file contains a list of account names, and their pertinent information.
219<code class="filename">@sysconfdir@/authlib/userdb</code> may alternatively be a
220directory containing plain text files, which are effectively concatenated
221together to form the actual list of accounts.
0fde1ce3 222The <span class="command"><strong>makeuserdb</strong></span> script compiles the account information
d9898ee8 223into a GDBM or DB database file, which can be quickly looked up.</p><p>
224<code class="filename">@sysconfdir@/authlib/userdb</code> is loosely equivalent in
225function to <code class="filename">/etc/passwd</code> and
226<code class="filename">/etc/shadow</code>, and contain analous information: account
227name, its numeric userid and groupid, home directory, and passwords.
228<code class="filename">@sysconfdir@/authlib/userdb</code> also contains additional
229Courier-specific metadata, such as account quotas and other account-specific
230settings.
231<code class="filename">@sysconfdir@/authlib/userdb</code> files can also be
232maintained by custom-written Perl scripts, instead of being edited
233by hand.</p><p>
234<code class="filename">@sysconfdir@/authlib/userdb</code>
235allows creation of virtual mail accounts that do not have a corresponding
236login account -- virtual mail accounts that can share the same, reserved,
237system userid.
238<code class="filename">@sysconfdir@/authlib/userdb</code>
239can also be used to completely supersede
240<code class="filename">/etc/passwd</code>.
241With many accounts it can be quite a drain to have to continuously linearly
242scan <code class="filename">/etc/passwd</code> in order to look up an account.
243Instead, a fast database lookup can retrieve the same information from the
244database file.
245Review the included manual pages, starting with
0fde1ce3 246<a class="ulink" href="userdb.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">userdb</span>(8)</span></a>, for more information.</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="userdbprimer" shape="rect"> </a>A brief <code class="literal">userdb</code> primer</h3></div></div></div><p>
d9898ee8 247<code class="literal">userdb</code> is a way to implement many virtual mailboxes - many
248mailboxes that do not have to have a separate system userid allocated for
249each one, and there is no system login associated with each mailbox.
250<code class="literal">userdb</code> uses a database for mapping virtual addresses to physical
251maildirs. It should be scalable to thousands of mailboxes. It can also be
252used to replace linear searches of <code class="filename">/etc/passwd</code> with a database
253lookup, see
0fde1ce3 254<a class="ulink" href="pw2userdb.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">pw2userdb</span>(8)</span></a>.</p><p>
d9898ee8 255Note - you still MUST use some valid system userid and groupid that is
256shared by all virtual mailboxes. Instead of allocating a single userid and
257groupid per each mailbox, the same userid and groupid is used for all of
258them.</p><p>
259This is a rough overview of using userdb. For additional information, read
0fde1ce3 260<a class="ulink" href="userdb.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">userdb</span>(8)</span></a>
d9898ee8 261and
0fde1ce3 262<a class="ulink" href="makeuserdb.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">makeuserdb</span>(8)</span></a>. All the scripts will
d9898ee8 263be installed in <code class="filename">@sbindir@</code>, so look for them there.</p><p>
264The best way to describe how <code class="literal">userdb</code> works is to try to create
265one virtual mail account. As mentioned before, virtual mailboxes still need
266one system account to be used for uid/gid purposes. Let's call this system
267account "vmail".</p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="userdbsimple" shape="rect"> </a>A simple userdb setup</h3></div></div></div><p>
268This approach should be used if you do not have many virtual mailboxes.
269It's very simple, but quickly becomes cumbersome if you administer many
270virtual mailboxes.</p><p>Create an empty <code class="filename">@userdb@</code> file:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
271# cp /dev/null @userdb@
272# chmod 700 @userdb@</pre></div><p>
273<code class="filename">@userdb@</code> must have 700 permissions,
274since it will contain passwords.</p><p>
0fde1ce3 275Now, run the script <span class="command"><strong>pw2userdb</strong></span>, as root.
d9898ee8 276This script converts the
277contents of <code class="filename">/etc/passwd</code>
278to the <code class="filename">@userdb@</code> format
279(including the contents of <code class="filename">/etc/shadow</code>,
280this is why permissions
281on <code class="filename">@userdb@</code> must be 700). This script is usually used
282where you
283want to convert a very large <code class="filename">/etc/passwd</code> to
284<code class="filename">@userdb@</code>. <code class="literal">userdb</code> applications can now
285use a fast
286<code class="literal">userdb</code> database instead of a linear scan
287of <code class="filename">/etc/passwd</code>
288in order to look up system accounts. However, you probably don't want to
289use this feature right now, so what you want to do is take the output
0fde1ce3 290of <span class="command"><strong>pw2userdb</strong></span>, and find the entry for the vmail account
d9898ee8 291that you
292created earlier. Look for a line that starts with 'vmail' followed by tab,
293followed by familiar fields from <code class="filename">/etc/passwd</code>. Save the
294output of
0fde1ce3 295<span class="command"><strong>pw2userdb</strong></span> in a temporary file, edit it, and remove
d9898ee8 296everything
297except the line containing vmail, and the very next line, which is a special
298entry that maps vmail's userid back to the vmail record.</p><p>
299Here's what you might find in the output of
0fde1ce3 300<span class="command"><strong>pw2userdb</strong></span>:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
d9898ee8 301vmail uid=1012|gid=1012|home=/home/vmail|systempw=*
3021012= vmail</pre></div><p>
303The actual numerical values and the home directory location may vary.
304Save
305these two lines as <code class="filename">@userdb@</code>, and set the permissions on
306<code class="filename">@userdb@</code> to 700:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
307$ chmod 700 <code class="filename">@userdb@</code>
308</pre></div><p>
309Now, with that out of the way, let's really create a virtual account. In
310this example we'll create a virtual mailbox for 'john@example.com'.</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
311# su vmail
312$ cd ~vmail
313$ mkdir john-example
314$ maildirmake john-example/Maildir
315$ exit
316#
317</pre></div><p>
0fde1ce3 318You may need to specify a full path to your <span class="command"><strong>maildirmake</strong></span>
d9898ee8 319program. The end result is that you created
320<code class="filename">$HOME/john-example</code> in vmail's account, which
321can be thought of as a “<span class="quote">virtual home directory</span>” for
322“<span class="quote">john@example.com</span>”, that contains the account's maildir
323mailbox.</p><p>
324Now, let's connect the dots here, and create an entry in
325<code class="filename">@userdb@</code> for <code class="filename">john@example.com</code>:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
326# userdb "john@example.com" set home=/home/vmail/john-example \
327 uid=UUU gid=GGG
328</pre></div><p>
329This command runs the script named <code class="filename">userdb</code> , which is
330installed, by default in <code class="filename">@sbindir@</code>. Replace UUU and
331GGG with the userid and groupid of the vmail account. If you now look in
332<code class="filename">@userdb@</code>, you will see that a new record for
333“<span class="quote">john@example.com</span>”
334has been appended to the end of the file.</p><p>
335One more detail: we need to set the IMAP password for this
336mailbox:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
337# userdbpw | userdb "john@example.com" set imappw</pre></div><p>
338On most modern Linux and BSD distributions, you can specify the -md5
0fde1ce3 339option to <span class="command"><strong>userdbpw</strong></span>, in order to use MD5 password hashes,
d9898ee8 340instead of crypt. The traditional password function allows passwords only
341up to 8 characters long; everything in excess is ignored.
342The newer MD5 passwords, now supported by most modern systems, allow
343longer passwords.</p><p>
344Use "<code class="literal">systempw</code>" instead of
345"<code class="literal">imappw</code>" if you would like to use the same password for the POP3
346server, and for all other services.
347The "<code class="literal">imappw</code>" field is only checked by the IMAP server.
348If not
349defined, "<code class="literal">systempw</code>" is used instead. The field
350<code class="literal">pop3pw</code>
351is checked only by Courier's POP3 server. If it is
352not defined the POP3 server will check <code class="literal">systempw</code> too.</p><p>Finally, compile the database:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
353# makeuserdb
354</pre></div><p>
355This command creates the actual database, <code class="filename">@userdb@.dat</code> and
356<code class="filename">@userdb@shadow.dat</code> from the plain text file
357<code class="filename">@userdb@</code>. Courier will now start accepting logins to this
358mailbox. Adding and removing mailboxes can be done while Courier is
359running.</p><p>
360Courier reads <code class="filename">@userdb@.dat</code> and
361<code class="filename">@userdb@shadow.dat</code> only. The plain text source,
362<code class="filename">@userdb@</code> is not read by Courier itself. Changes take
363effect
0fde1ce3 364only when <span class="command"><strong>makeuserdb</strong></span> runs.</p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="userdbcomplex" shape="rect"> </a>Large virtual domain farm</h3></div></div></div><p>
d9898ee8 365The previous approach used a single flat file, <code class="filename">@userdb@</code>.
366This
367will work for up to a couple of hundred accounts.
368An slightly different approach can scale to thousands of
369domains and mailboxes.</p><p>
370Instead of creating a <code class="filename">@userdb@</code> file, create a
371subdirectory:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
372# mkdir @userdb@
373# chmod 700 @userdb@
374</pre></div><p>
375Now, create <code class="filename">@userdb@/default</code>, containing pw2userdb's
376output
377for the vmail account, as previously described.</p><p>
378This time, you probably want to create all mailboxes for the same domain
379in a separate subdirectory:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
380# su - vmail
381$ cd ~vmail
382$ mkdir -p domains/example-com
383$ mkdir domains/example-com/john
384$ maildirmake domains/example-com/john
385$ exit
386</pre></div><p>
387The idea is that all the maildirs for <code class="literal">@example.com</code> will
388now be found
389in <code class="filename">~vmail/domains/example-com</code>. All maildirs for
390<code class="literal">domain.org</code> will be in
391<code class="filename">~vmail/domains/domain.org</code>. The actual layout and naming
392conventions are entirely up to you to define.</p><p>Here's how configure <code class="filename">@userdb@</code>:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
393$ userdb "example-com/john@example.com" set \
394 home=/home/vmail/domains/example-com/john \
395 uid=UUU gid=GGG</pre></div><p>
396This creates the file <code class="filename">@userdb@/example-com</code> (the first
0fde1ce3 397parameter to the <span class="command"><strong>userdb</strong></span> command), and appends a record named
d9898ee8 398"john@example.com". You will store all <code class="literal">userdb</code> entries for
399<code class="literal">@example.com</code> in the file
400<code class="filename">@userdb@/example-com</code>. All
401entries for <code class="literal">@domain.org</code> will be maintained in
402<code class="filename">@userdb@/domain-org</code>, and so on.</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
403$ userdbpw | userdb "example-com/john@example.com" set imappw
404</pre></div><p>
405This sets the IMAP access password for this account. Finally:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
406$ makeuserdb
407</pre></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="moreuserdb" shape="rect"> </a>Beyond <code class="literal">userdb</code></h3></div></div></div><p>
408<code class="literal">userdb</code> is a simple, straightforward solution that scales
409to a couple of thousand of mail accounts, depending on the hardware.
410Beyond that, one of database-based modules will need to be used,
411such as
412<code class="literal">authldap</code>,
413<code class="literal">authmysql</code>,
414<code class="literal">authpgsql</code>.
415Since <code class="literal">userdb</code> is maintained as plain text files that
416are easily parsed by a script, migrating data from userdb will not be
0fde1ce3 417difficult.</p></div></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authmysql" shape="rect"> </a>The <code class="literal">authmysql</code> authentication module</h2></div></div></div><p>
d9898ee8 418This module reads
419the list of mail accounts and passwords from a table in a
420MySQL database.
421The <code class="filename">@authmysqlrc@</code> configuration file defines the
422particular details regarding the MySQL database and the schema of the
423mail account table.</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authpgsql" shape="rect"> </a>The <code class="literal">authpgsql</code> authentication module</h2></div></div></div><p>
424This module reads
425the list of mail accounts and passwords from a table in a
426PostgreSQL database.
427The <code class="filename">@authpgsqlrc@</code> configuration file defines the
428particular details regarding the PostgreSQL database and the schema of the
429mail account table.</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authldap" shape="rect"> </a>The <code class="literal">authldap</code> authentication module</h2></div></div></div><p>
430This module reads
431the list of mail accounts and passwords from an LDAP directory.
432The <code class="filename">@authldaprc@</code> configuration file defines the
433particular details regarding the LDAP directory layout.</p><p>
434A suggested LDAP schema can be found in the file
435<code class="filename">authldap.schema</code>,
436which is included in Courier authentication library's source code, and
437may be installed on your system.</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authcustom" shape="rect"> </a><code class="literal">authcustom</code></h2></div></div></div><p>
438This is a do-nothing module where custom authentication code
439can be added.
440This authentication module is just a stub that doesn't really do anything.
441It's purpose is to serve as a placeholder where custom authentication code
442can be easily implement.</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="options" shape="rect"> </a>Account options</h2></div></div></div><p>
443The authentication library has a facility for keep arbitrary
444“<span class="quote">name=value</span>”-type settings,
445called “<span class="quote">options</span>”, for individual accounts. This feature is
446only available with
447<code class="literal">userdb</code>,
448<code class="literal">LDAP</code>, <code class="literal">MySQL</code>, and
449<code class="literal">PostgresSQL</code>
450modules. Individual account options are not supported with
451system-based authentication modules (password/shadow files, or PAM).</p><p>
452See the
0fde1ce3 453<a class="ulink" href="auth_generic.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">auth_generic</span>(3)</span></a>
d9898ee8 454for a description of option names used by various Courier packages.
455Other applications can make up names for their own settings, and
456use them in the same way.</p><p>
457Account options are specified via the authentication modules in the
458following manner:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">userdb</code></span></dt><dd><p>
0fde1ce3 459Use the <span class="command"><strong>userdb</strong></span> command to set a field called
d9898ee8 460"<code class="literal">options</code>". Example:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
461userdb user1@example.com set options=disableimap=1,sharedgroup=44
462makeuserdb
463</pre></div><p>
464The option text string here is
465"<code class="literal">disableimap=1,sharedgroup=44</code>".
466It specifies two options.</p></dd><dt><span class="term"><code class="literal">LDAP</code></span></dt><dd><p>
467Account options are defined by the <code class="literal">LDAP_AUXOPTIONS</code>
468setting in the <code class="filename">authldaprc</code> configuration file.
469<code class="literal">LDAP_AUXOPTIONS</code> consists of a comma-separated list of
470"<code class="literal">attribute=setting</code>". "attribute" is the name of an LDAP
471attribute, and "setting" is the corresponding account setting name. The
472value of the attribute becomes the value of the setting. Unless you
473value your sanity, the names of LDAP attributes should be the same as
474the actual setting names (in which case "=setting" may be dropped and
475<code class="literal">LDAP_AUXOPTIONS</code> becomes a simple comma-separated list of
476supported settings), but they don't have to be.</p><p>
477<code class="literal">LDAP_AUXOPTIONS</code> is nothing more than a simple mapping
478of LDAP attributes to account settings. A <code class="literal">LDAP_AUXOPTIONS</code>
479of "shared=sharedgroup,disableimap" means that the LDAP attribute
480called "shared" contains the "sharedgroup" setting, as described
481previously; and an LDAP attribute of disableimap contains the setting
482of the same name.</p></dd><dt><span class="term"><span class="application">MySQL</span>, and <span class="application">PostgreSQL</span></span></dt><dd><p>
483Account options are defined by <code class="literal">MYSQL_AUXOPTIONS_FIELD</code>
484or <code class="literal">POSTGRESQL_AUXOPTIONS_FIELD</code>, in its corresponding
485configuration file. In the most simplest case, add a character field to
486the database, and put the field name into the
487<code class="literal">MYSQL_AUXOPTIONS_FIELD</code> or
488<code class="literal">POSTGRESQL_AUXOPTIONS_FIELD</code> configuration file setting.
489For each account, the character field should contain the literal option
490string. Yes, you'll just put "shared=sharedgroup,disableimap"
491literally, in that field.</p><p>
492Fortunately, there is a cleaner way to do this, which avoid driving
493a database designer batty. Keep in mind that the contents of
494<code class="literal">MYSQL_AUXOPTIONS_FIELD</code>/<code class="literal">POSTGRESQL_AUXOPTIONS_FIELD</code>
495are simply inserted directly into the SQL query that fetches the
496account information. Both MySQL and PostgreSQL have a rich SQL that can
497be used to manufacture a suitable option string from plain,
498garden-variety, database fields. That is, you may define individual
499table fields like "disableimap", and "disablepop3", then provide a
500suitable (albeit ugly) SQL fragment that combines them together into
501the expected option string. An example of such an SQL string is
502provided in the comments portion of the configuration file.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
503When using the alternative custom query option, the option string
0fde1ce3 504 is the last field that the custom SQL query should return.</p></div></dd></dl></div></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="authtest" shape="rect"> </a>Running <span class="command"><strong>authtest</strong></span></h2></div></div></div><p>
505The <span class="command"><strong>authtest</strong></span> command may be used to verify that the
d9898ee8 506authentication library is working:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
507authtest userid
508authtest userid password
509authtest userid password newpassword
510authenumerate</pre></div><p>
511Running
0fde1ce3 512<span class="command"><strong>authtest</strong></span>
d9898ee8 513with one argument should display the selected account's
514home directory, userid, groupid,
515and other related data.
516The second argument to
0fde1ce3 517<span class="command"><strong>authtest</strong></span>,
d9898ee8 518if supplied, specifies the account's password.
519The two argument form of
0fde1ce3 520<span class="command"><strong>authtest</strong></span>
d9898ee8 521validates the password, and displays an indication whether the given
522password is valid, or not.
523The three argument form of the
0fde1ce3 524<span class="command"><strong>authtest</strong></span>
d9898ee8 525command attemps to change the account's password.
526The second argument is the old password, the third argument is the
527new password.</p><p>
0fde1ce3 528See <a class="ulink" href="README.authdebug.html" target="_top" shape="rect"><code class="filename">README.authdebug.html</code></a> for more information.</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="pwchange" shape="rect"> </a>Changing account passwords</h3></div></div></div><p>For the virtual domain modules (<code class="literal">authldap</code>,
d9898ee8 529<code class="literal">authmysql</code>, <code class="literal">authpgsql</code> and friends) changing the
530login is a no-brainer. The tricky situation is when SqWebMail uses system
531passwords to log in (the <code class="literal">authpwd</code>, <code class="literal">authshadow</code>, or
532<code class="literal">authpam</code> authentication module). Different systems use different
533ways to keep login passwords. Many systems use the traditional
534<code class="filename">/etc/passwd</code> and <code class="filename">/etc/shadow</code> files. Other systems
535use a binary database; other systems use NIS. And on some systems the
536password file lookup library is a wrapper that goes against an external LDAP
537directory, or a database. For maximum compatibility, SqWebMail changes login
0fde1ce3 538passwords by running the <span class="command"><strong>passwd</strong></span> command. This is the traditinal
539*nix command that changes login passwords. <span class="command"><strong>passwd</strong></span> is an
d9898ee8 540interactive command. It's normally run from a terminal.
541 SqWebMail uses an
0fde1ce3 542<span class="command"><strong>expect</strong></span> script - as mentioned in
d9898ee8 543the introduction - to answer interactive
0fde1ce3 544prompts from <span class="command"><strong>passwd</strong></span>. The <span class="command"><strong>expect</strong></span> script expects to
545get a plain, garden-variety, <span class="command"><strong>passwd</strong></span> command, which acts
d9898ee8 546something like this:</p><div class="informalexample"><pre class="programlisting" xml:space="preserve">
547 # passwd
548 Changing password for luser
549 (current) UNIX password: (old password typed here)
550 New UNIX password: (new password typed here)
551 Retype new UNIX password: (new password retyped here)
552 passwd: all authentication tokens updated successfully
553 #
554</pre></div><p>
0fde1ce3 555Systems that use a <span class="command"><strong>passwd</strong></span> command with very different prompts
556may find that the default <span class="command"><strong>expect</strong></span> script will fail. In which case
557it will be necessary to tweak the <span class="command"><strong>expect</strong></span> script to match the
558prompts from the system's <span class="command"><strong>passwd</strong></span> command.</p><p>
559Modern systems use a <span class="command"><strong>passwd</strong></span> command that rejects "bad"
d9898ee8 560passwords - passwords that are based on dictionary words, are too short, or
561are obvious for other reasons. When testing the ability to change
562system passwords be sure to use randomly-generated gibberish for the test
0fde1ce3 563passwords. Otherwise, the default <span class="command"><strong>expect</strong></span> script will
d9898ee8 564actually be
565working, but you won't be the wiser. For security reasons, the actual
0fde1ce3 566messages from <span class="command"><strong>passwd</strong></span> will not be shown by.</p><p>
567The <span class="command"><strong>expect</strong></span> script is installed as
d9898ee8 568<code class="filename">/usr/local/libexec/courier-authlib/authsystem.passwd</code>
0fde1ce3 569(assuming default options to the <span class="command"><strong>configure</strong></span> script).</p></div></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="internals" shape="rect"> </a>Authentication internals</h2></div></div></div><p>
d9898ee8 570The following structure describes an authentication module:</p><div class="blockquote"><blockquote class="blockquote"><div class="example"><a id="authstaticinfo" shape="rect"> </a><p class="title"><b>Example 1. struct authstaticinfo</b></p><div class="example-contents"><pre class="programlisting" xml:space="preserve">
571struct authstaticinfo {
572 const char *auth_name;
573 int (*auth_func)(const char *, const char *, char *, int,
574 int (*)(struct authinfo *, void *),
575 void *);
576 int (*auth_prefunc)(const char *, const char *,
577 int (*)(struct authinfo *, void *),
578 void *);
579 void (*auth_cleanupfunc)();
580 int (*auth_changepwd)(const char *, /* service */
581 const char *, /* userid */
582 const char *, /* oldpassword */
583 const char *); /* new password */
584
585 void (*auth_idle)();
586 /* Not null - gets called every 5 mins when we're idle */
587
588 void (*auth_enumerate)( void(*cb_func)(const char *name,
589 uid_t uid,
590 gid_t gid,
591 const char *homedir,
592 const char *maildir,
593 void *void_arg),
594 void *void_arg);
595 } ;
596</pre></div></div><br class="example-break" clear="none"/></blockquote></div><p>
597An authentication module is a shared library that defines a single function
598called
599“<span class="quote">courier_auth_<em class="replaceable"><code>NAME</code></em>_init</span>”, where
600“<span class="quote">NAME</span>” is the name of the authentication module.
601The shared library does not need to export any other symbols, this is the
602only function that needs to be exported.
603The function returns a pointer to the <span class="structname">authstaticinfo</span>
604structure.
605For example, the relevant code from the <code class="literal">authmysql</code> module is:
606</p><div class="blockquote"><blockquote class="blockquote"><div class="example"><a id="authmysqlex" shape="rect"> </a><p class="title"><b>Example 2. authmysql</b></p><div class="example-contents"><pre class="programlisting" xml:space="preserve">
607static struct authstaticinfo authmysql_info={
608 "authmysql",
609 auth_mysql,
610 auth_mysql_pre,
611 auth_mysql_cleanup,
612 auth_mysql_changepw,
613 auth_mysql_cleanup,
614 auth_mysql_enumerate};
615
616
617struct authstaticinfo *courier_authmysql_init()
618{
619 return &amp;authmysql_info;
620}
621</pre></div></div><br class="example-break" clear="none"/></blockquote></div><p>
622<code class="function">auth_func</code> points to a function that handles an
623authentication request. The function is invoked as follows:</p><div class="blockquote"><blockquote class="blockquote"><div class="example"><a id="auth_func" shape="rect"> </a><p class="title"><b>Example 3. auth_func</b></p><div class="example-contents"><pre class="programlisting" xml:space="preserve">
624int result=auth_func(const char *service, const char *authtype,
625 const char *authdata,
626 int (*callback_func)(struct authinfo *, void *),
627 void *callback_arg);
628</pre></div></div><br class="example-break" clear="none"/></blockquote></div><p>
629“<span class="quote">service</span>” is the name of the service being authenticated,
630such as “<span class="quote"><code class="literal">imap</code></span>” or
631“<span class="quote"><code class="literal">pop3</code></span>”.
632“<span class="quote">authtype</span>” defines the authentication format,
633and “<span class="quote">authdata</span>” is the actual authentication request.</p><p>
634Two authentication formats are defined at this time.
635The “<span class="quote">authtype</span>” string is set to one of the following
636strings:</p><div class="variablelist"><dl><dt><span class="term">“<span class="quote">login</span>”</span></dt><dd><p>
637Tradition userid/password authentication.
638<code class="literal">authdata</code> points to a string that consists of:
639the userid; a newline character; the password; a final newline
640character.</p></dd><dt><span class="term">“<span class="quote">cram-md5</span>”, or “<span class="quote">cram-sha1</span>”</span></dt><dd><p>
641Challenge/response authentication.
642<code class="literal">authdata</code> points to a string that consists of:
643the base64-encoded challenge; a newline character;
644the base64-encoded response string; and a final newline
645character. Furthermore, the base64-encoded response string consists of:
646the login ID, a space character, and the response as a hexadecimal
647string (yes, base64-encoding of the response string is not strictly
648necessary).</p></dd></dl></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
649Not all authentication modules may implement all authentication formats.
650An authentication module that does not implement a particular authentication
651format should handle it the same way as an invalid login ID.</p></div><p>
652The authentication function should return a negative value if the login ID
653is invalid. The authentication library will try the next authentication
654module.</p><p>
655The authentication function should return a positive value if the login ID
656is valid, but the password is invalid. The authentication library will not
657try any more authentication modules.</p><p>
658Otherwise, the authentication module should call the
659<code class="function">callback_func</code> function, and return the same value that's
660returned by this function.</p><p>
661The authentication module should pass through <code class="literal">callback_arg</code>
662to the callback function as a second argument.
663The first argument is a pointer to the
664<span class="structname">authinfo</span> structure, which is described in detail
665in the
0fde1ce3 666<a class="ulink" href="auth_generic.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">auth_generic</span>(3)</span></a>
d9898ee8 667manual page.
668The authentication module is responsible for allocating this structure.
669After the callback function returns this structure can be deallocated.
670The authentication module initializes the following fields:</p><p>
671<code class="function">auth_pre_func</code> points to a function that obtains
672account information. The function is invoked as follows:</p><div class="blockquote"><blockquote class="blockquote"><div class="example"><a id="auth_pre_func" shape="rect"> </a><p class="title"><b>Example 4. auth_pre_func</b></p><div class="example-contents"><pre class="programlisting" xml:space="preserve">
673int auth_pre_func(const char *user, const char *service,
674 int (*callback)(struct authinfo *, void *), void *arg);
675</pre></div></div><br class="example-break" clear="none"/></blockquote></div><p>
676This function does the same thing as “<span class="quote">auth_func</span>” except that
677the password is not actually verified.
678If the account exists, the callback function is invoked with the
679same callback arguments.</p><p>
680<code class="function">auth_cleanup_func</code> points to a function that will be
681invoked just before the authentication module is uninstalled, giving it
682the opportunity for some last-minute cleanup.</p><p>
683<code class="function">auth_idle</code> points to a function that will be
684invoked when no authentication requests are received for a couple of minutes,
685giving the authentication module an opportunity to close any database
686connections, so that they do not get shut down by the server, for inactivity,
687resulting in an error the next time an authentication request is
688received.</p><p>
689<code class="function">auth_changepwd</code> points to a function that will be
690invoked to change a password on an account, as follows.</p><div class="blockquote"><blockquote class="blockquote"><div class="example"><a id="auth_changepwd" shape="rect"> </a><p class="title"><b>Example 5. auth_changepwd</b></p><div class="example-contents"><pre class="programlisting" xml:space="preserve">
691int auth_changepwd(const char *service, const char *user,
692 const char *oldpw, const char *newpw);
693</pre></div></div><br class="example-break" clear="none"/></blockquote></div><p>
694<code class="literal">service</code> is the name of the service whose password is to
695be changed (such as “<span class="quote">imap</span>” or “<span class="quote">pop3</span>”).
696<code class="function">auth_changepwd</code> should return 0 if the password was
697changed succesfully, a negative value if <code class="literal">user</code> is invalid
698(the next authentication module will be tried), or a positive value if
699the password change request failed (no more modules will be tried).</p><p>
700<code class="function">auth_enumerate</code> points to a function that enumerates
701the list of all login IDs known to the authentication module.
702The first argument <code class="function">auth_enumerate</code> is a callback
703function. <code class="function">auth_enumerate</code> invokes the callback
704function once for each login ID, supplying the login ID, the userid,
705groupid, home directory and maildir as arguments.
706The last argument to the callback function is passed through from the
707second argument to <code class="function">auth_enumerate</code>.</p><p>
708After enumerating all login IDs <code class="function">auth_enumerate</code> calls
709the callback function one last time, with a NULL pointer for the login ID,
710then returns. If an error is encountered while enumerating the login IDs,
711<code class="function">auth_enumerate</code> terminates without invoking
712the callback function with a NULL login ID.</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="files" shape="rect"> </a>FILES</h2></div></div></div><p>
0fde1ce3 713<code class="filename"> @authdaemonrc@</code> - <span class="command"><strong>authdaemond</strong></span> configuration file</p><p>
714<code class="filename"> @authldaprc@</code> - <span class="command"><strong>authldap</strong></span> configuration file</p><p>
715<code class="filename"> @authmysqlrc@</code> - <span class="command"><strong>authmysql</strong></span> configuration file</p><p>
716<code class="filename"> @authpgsqlrc@</code> - <span class="command"><strong>authpgsql</strong></span> configuration file</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="seealso" shape="rect"> </a>SEE ALSO</h2></div></div></div><p>
717<a class="ulink" href="courier.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">courier</span>(8)</span></a>,
d9898ee8 718
0fde1ce3 719<a class="ulink" href="userdb.html" target="_top" shape="rect"><span class="citerefentry"><span class="refentrytitle">userdb</span>(8)</span></a></p></div></div></body></html>