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