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