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