• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

liblog/H03-May-2022-27,14523,491

libs/H08-Mar-2022-288,723247,228

userdb/H03-May-2022-29,47925,360

AUTHORSH A D25-Aug-2013450 1812

COPYINGH A D25-Aug-2013183 43

COPYING.GPLH A D25-Aug-201334.3 KiB675553

ChangeLogH A D22-May-202123.3 KiB887497

INSTALLH A D28-May-202015.1 KiB318251

Makefile.amH A D22-May-202124.4 KiB680497

Makefile.inH A D03-May-2022102.8 KiB2,5392,241

NEWSH A D25-Aug-2013645 1913

READMEH A D11-Nov-20132.4 KiB5743

README.authdebug.html.inH A D25-Aug-201314.6 KiB371298

README.authmysql.myownqueryH A D25-Aug-201314.1 KiB551338

README.ldapH A D25-Aug-20132.7 KiB8865

README_authlib.html.inH A D22-May-202158 KiB770760

aclocal.m4H A D08-Mar-2022397.2 KiB11,24810,146

auth.hH A D07-May-20161.2 KiB5628

auth_enumerate.3H A D29-Oct-20204.2 KiB196169

auth_generic.3H A D29-Oct-2020143 41

auth_generic_meta.3H A D29-Oct-202011.2 KiB415385

auth_getoption.3H A D29-Oct-20203.5 KiB12598

auth_getuserinfo.3H A D29-Oct-2020142 41

auth_getuserinfo_meta.3H A D29-Oct-20209.7 KiB373343

auth_login.3H A D29-Oct-2020141 41

auth_login_meta.3H A D29-Oct-20209.9 KiB380350

auth_meta.3H A D29-Oct-20204 KiB182155

auth_mkhomedir.3H A D29-Oct-20203.3 KiB8457

auth_passwd.3H A D29-Oct-20203 KiB9164

auth_sasl.3H A D29-Oct-20205.3 KiB231204

auth_sasl_ex.3H A D29-Oct-2020135 41

authconfigfile.cppH A D07-May-20164.5 KiB264195

authconfigfile.hH A D24-Apr-20161.7 KiB10277

authcustom.cH A D28-Jan-20172.5 KiB11474

authcustom.hH A D25-Aug-2013413 2410

authdaemon.cH A D23-May-20206.2 KiB312257

authdaemond.cH A D07-Dec-202018 KiB1,063907

authdaemond.inH A D03-May-2022403 187

authdaemondcpp.cppH A D08-Jan-2016468 3220

authdaemonlib.cH A D23-May-202011.5 KiB708575

authdaemonrc.inH A D03-May-20224.2 KiB140122

authdaemontest.cH A D25-Aug-20131.7 KiB119100

authenumerate.cH A D25-Aug-20131.4 KiB8771

authinfo.cH A D25-Aug-20132.3 KiB144120

authldap.cH A D28-Jan-20171.9 KiB8766

authldap.hH A D08-Jan-2016733 3820

authldap.ldifH A D25-Aug-20133.7 KiB9291

authldap.schemaH A D25-Aug-20134 KiB10385

authldapescape.cH A D25-Aug-20131,006 6952

authldaplib.cppH A D22-May-202132.2 KiB1,7001,304

authldaprcH A D07-Nov-20218.6 KiB292244

authlib.3.inH A D29-Oct-20203.4 KiB11487

authlib.html.inH A D22-May-20213.3 KiB3422

authmksock.cH A D25-Aug-2013742 3929

authmoduser2.cH A D25-Aug-20131.1 KiB6852

authmoduser3.cH A D23-May-20202 KiB10072

authmysql.cppH A D28-Jan-20173.9 KiB190157

authmysql.hH A D18-Apr-20161,022 5038

authmysqllib.cppH A D01-May-201616.7 KiB811646

authmysqlrcH A D15-May-20219.3 KiB305264

authoption.cH A D25-Aug-20131.3 KiB8161

authpam.cH A D23-May-20206.5 KiB321249

authpasswd.1H A D29-Oct-20202.7 KiB10174

authpasswd.cH A D25-Aug-20131.9 KiB11888

authpgsql.cH A D28-Jan-20171.8 KiB7862

authpgsql.hH A D25-Apr-2016646 2918

authpgsqllib.cppH A D07-May-201618.4 KiB939754

authpgsqlrcH A D15-May-20217.9 KiB259225

authpipe.cH A D25-Aug-20133.9 KiB189148

authpipelib.cH A D25-Aug-20134.5 KiB193132

authpipelib.hH A D25-Aug-2013237 155

authpwd.cH A D25-Aug-20131.5 KiB8063

authpwdenumerate.cH A D25-Aug-2013864 5138

authsasl.cH A D07-Mar-20223.3 KiB207160

authsaslclient.cH A D25-Aug-20131.2 KiB5941

authsaslclient.hH A D24-Jul-20171.3 KiB4831

authsaslclientcram.cH A D25-Aug-20131.8 KiB8368

authsaslclientcrammd5.cH A D25-Aug-2013679 2818

authsaslclientcramsha1.cH A D25-Aug-2013938 3725

authsaslclientexternal.cH A D25-Aug-2013455 2514

authsaslclientlogin.cH A D25-Aug-2013907 4734

authsaslclientplain.cH A D25-Aug-2013957 5338

authsaslcram.cH A D25-Aug-20132.7 KiB130107

authsaslfrombase64.cH A D25-Aug-20132.2 KiB7664

authsasllogin.cH A D25-Aug-20132 KiB124104

authsaslplain.cH A D25-Aug-20131.8 KiB11899

authsasltobase64.cH A D05-Feb-2021830 5038

authshadow.cH A D25-Aug-20131.6 KiB8664

authsqlite.cppH A D28-Jan-20175 KiB219181

authsqlite.hH A D07-May-2016621 3525

authsqlitelib.cppH A D07-May-201612.5 KiB628485

authsqlitercH A D15-May-20218.1 KiB253222

authsyschangepwd.cH A D25-Aug-20132.6 KiB166133

authsyscommon.cH A D25-Aug-20131.4 KiB7256

authsystem.passwd.inH A D03-May-20221.7 KiB7139

authtest.1H A D29-Oct-20202.4 KiB6437

authtest.cH A D23-May-20202.4 KiB125103

authuserdb.cH A D28-Jan-20174.4 KiB213171

authuserdbpwd.cH A D24-Apr-20167.3 KiB436351

authvchkpw.cH A D03-May-20226.3 KiB243143

authvchkpwlib.cH A D03-May-2022663 3425

authwait.hH A D25-Aug-2013444 2616

checkpassword.cH A D20-Mar-20162.1 KiB9072

checkpasswordmd5.cH A D25-Aug-2013774 3626

checkpasswordsha1.cH A D25-Aug-20131.2 KiB6549

compileH A D01-Jan-20207.2 KiB349259

config.guessH A D14-Mar-202142.9 KiB1,4631,270

config.subH A D14-Mar-202135.5 KiB1,8241,686

configureH A D03-May-2022674.7 KiB23,13119,341

configure.acH A D08-Mar-202223.2 KiB1,023823

courier-authlib.service.inH A D07-Oct-2013233 129

courier-authlib.specH A D08-Mar-202211.1 KiB384290

courier-authlib.spec.inH A D22-May-202111.1 KiB384309

courier-authlib.sysvinit.inH A D25-Aug-2013892 5234

courier_auth_config.h.inH A D03-May-20227.5 KiB292195

courierauth.hH A D05-Feb-20216.2 KiB249105

courierauthdebug.hH A D05-Feb-2021907 3622

courierauthsasl.hH A D05-Feb-20213.4 KiB12539

courierauthsaslclient.hH A D05-Feb-20211.9 KiB8124

courierauthstaticlist.hH A D05-Feb-20211.2 KiB5538

cramlib.cH A D28-Jan-20174.4 KiB220169

cryptpassword.cH A D07-May-20162.3 KiB131101

dbobj.config.inH A D25-Aug-2013118 64

dbobj.h.inH A D25-Aug-20131.1 KiB5443

debug.cH A D25-Aug-20134.4 KiB18486

depcompH A D01-Jan-202023 KiB792502

install-shH A D14-Mar-202114.3 KiB502327

ltmain.shH A D14-Mar-2021316.6 KiB11,1507,980

missingH A D01-Jan-20206.7 KiB216143

preauthcustom.cH A D25-Aug-20134 KiB14655

preauthdaemon.cH A D23-May-20201.1 KiB5036

preauthldap.cH A D25-Aug-2013553 2819

preauthmysql.cppH A D18-Apr-20161.1 KiB5438

preauthpam.cH A D25-Aug-20131.1 KiB5743

preauthpwd.cH A D25-Aug-2013909 4734

preauthshadow.cH A D25-Aug-20131.5 KiB7557

preauthuserdb.cH A D25-Aug-2013499 2010

preauthuserdbcommon.cH A D25-Aug-20132.8 KiB147120

preauthvchkpw.cH A D03-May-20224.8 KiB16076

samplepipe.plH A D25-Aug-20132.3 KiB9258

sysconftoolH A D23-Jul-20216.5 KiB376261

userdb-test-cram-md5.pl.inH A D25-Aug-20132 KiB6524

README

1                         Courier Authentication Library
2
3   Download: [1]http://www.courier-mta.org/download.html#authlib
4
5Overview
6
7   The Courier authentication library provides authentication services for
8   other Courier applications. In this context, the term "authentication"
9   refers to the following functions:
10
11    1. Take a userid or a loginid, and a password. Determine whether the
12       loginid and the password are valid.
13    2. Given a userid, obtain the following information about the userid:
14
15         A. The account's home directory.
16         B. The numeric system userid and groupid that owns all files
17            associated with this account.
18         C. The location of the account's maildir.
19         D. Any maildir quota defined for this account. See the Courier
20            documentation for more information on maildir quotas.
21         E. Other miscellaneous account-specific options.
22
23    3. Change the password associated with a loginid.
24    4. Obtain a complete list of all login ids.
25
26   The Courier authentication library provides alternative implementations of
27   these authentication services:
28
29    1. Use the traditional system password files: /etc/passwd and
30       /etc/shadow, possibly in conjunction with the PAM library.
31    2. Maintain all this information in a GDBM or a DB database. The GDBM or
32       the DB database is compiled from plain text files. Perl scripts
33       provide a simple interface for creating and editing the authentication
34       information, then a script compiles the plain text files into a
35       database.
36    3. Use an LDAP server for authentication.
37    4. Use a table in a MySQL database for authentication.
38    5. Use a table in a PostgreSQL database for authentication.
39    6. Use a table in an SQLite file for authentication.
40
41   All Courier components that use this authentication library, therefore,
42   will be able to authenticate E-mail accounts using any of the above
43   methods.
44
45   Additional information can be found in the [2]INSTALL file.
46
47   The authentication API is [3]documented.
48
49Further resources
50
51   Subscribe to the [4]courier-users mailing list. Go to
52   http://lists.sourceforge.net/mailman/listinfo/courier-users to subscribe
53   to courier-users, or send a message to
54   <courier-users-request@lists.sourceforge.net> and put "subscribe" in the
55   subject line. Search the list archives at
56   [5]http://markmail.org/browse/net.sourceforge.lists.courier-users.
57

README.authdebug.html.in

1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head>
6  <meta http-equiv="Content-Type" content="" />
7
8  <title>Debugging authentication problems</title>
9</head>
10
11<body bgcolor="#FFFFFF">
12  <h1 align="center">Debugging authentication problems</h1>
13
14  <p>A common problem after installing the Courier authentication
15  library is that authentication, using authtest, doesn't work.
16  This document shows how to use courier's debugging features to
17  pinpoint the problem.</p>
18
19  <h2>1. Turn on debugging</h2>
20
21  <p>For courier-imap, you need to set one of the following values
22  in @sysconfdir@/authdaemonrc:</p>
23  <pre>
24DEBUG_LOGIN=1    # turn on authentication debugging
25DEBUG_LOGIN=2    # turn on authentication debugging AND show passwords
26</pre>
27
28  <p>This setting is located at the very end of the configuration
29  file.</p>
30
31  <p>After changing this setting, restart the authentication daemon
32  by running the "authdaemond stop" and "authdaemond start"
33  commands.</p>
34
35  <p>At this point, all debugging output goes to syslog at level
36  'debug', which is normally not shown. You will probably need to
37  change your <code>/etc/syslog.conf</code> file to be able to see
38  these messages. If you have an existing entry which says
39  "mail.info" (which means facility 'mail', level 'info' or higher)
40  then you can just change this to "mail.debug". Alternatively you
41  can add a new entry like this:</p>
42  <pre>
43*.debug                        /var/log/debug
44</pre>
45
46  <p>Don't forget to create this file, and to send a HUP signal to
47  syslogd to make it re-read its configuration:</p>
48  <pre>
49# touch /var/log/debug
50# killall -1 syslogd
51</pre>
52
53  <p>If you don't want to mess around with your syslog
54  configuration, you can also start <code>authdaemond</code>
55  manually, and log its output to a file:</p>
56
57  <p><code>@libexecdir@/courier-authlib/authdaemond &gt;filename
58  2&gt;&amp;1</code></p>
59
60  <h2>2. Issue a manual login</h2>
61
62  <p>You can use the authtest command to verify authentication, or
63  go ahead and install Courier-IMAP.</p>
64
65  <p>For courier-imap, you will get much better information by not
66  using a mail client and manually logging in using 'telnet'. The
67  transcript of this telnet session may give useful information as
68  to what is going on. If you are going to report a problem to the
69  mailing list, you should certainly include this transcript as
70  well as the corresponding debugging output.</p>
71  <pre>
72-- to debug POP3 --
73# telnet x.x.x.x 110
74user USERNAME
75pass PASSWORD
76stat
77quit
78
79-- to debug IMAP --
80# telnet x.x.x.x 143
81a login USERNAME PASSWORD
82a examine inbox
83a logout
84
85-- to debug POP3 over SSL --
86# openssl s_client -connect x.x.x.x:995
87(then use same commands as POP3 example)
88
89-- to debug IMAP over SSL --
90# openssl s_client -connect x.x.x.x:993
91(then use same commands as IMAP example)
92</pre>
93
94  <p>This isn't an option for sqwebmail of course - just login
95  through the web interface and check the authentication debug log
96  which is generated.</p>
97
98  <h2>3. Interpret the debug output</h2>
99
100  <p>First, a brief explanation of courier's authentication system.
101  There are a number of standalone <b>authentication modules</b>.
102  An authentication module exists for every authentication method.
103  Each authentication module is installed as a shared library. When
104  <strong>authdaemond</strong> starts, it attempts to load and
105  initialize the authentication modules, logging the following
106  messages to syslog:</p>
107  <pre>
108Oct 17 11:25:37 commodore authdaemond: modules="authuserdb authpam authpgsql authldap authmysql authcustom", daemons=5
109Oct 17 11:25:37 commodore authdaemond: Installing libauthuserdb
110Oct 17 11:25:37 commodore authdaemond: Installation complete: authuserdb
111Oct 17 11:25:37 commodore authdaemond: Installing libauthpam
112Oct 17 11:25:37 commodore authdaemond: Installation complete: authpam
113Oct 17 11:25:37 commodore authdaemond: Installing libauthpgsql
114Oct 17 11:25:37 commodore authdaemond: libauthpgsql.so: cannot open shared object file: No such file or directory
115Oct 17 11:25:37 commodore authdaemond: Installing libauthldap
116Oct 17 11:25:37 commodore authdaemond: libauthldap.so: cannot open shared object file: No such file or directory
117Oct 17 11:25:37 commodore authdaemond: Installing libauthmysql
118Oct 17 11:25:37 commodore authdaemond: libauthmysql.so: cannot open shared object file: No such file or directory
119Oct 17 11:25:37 commodore authdaemond: Installing libauthcustom
120Oct 17 11:25:37 commodore authdaemond: Installation complete: authcustom
121</pre>
122
123  <p>The first message lists all authentication modules that were
124  compiled, and indicates that <strong>authdaemond</strong> will
125  spawn five processes to handle all authentication requests. This
126  is followed by messages indicating that indicate which
127  authentication modules were installed.</p>
128
129  <p>In this example, authdaemond did not load the authpgsql,
130  authldap, and authmysql modules. That's because in this case the
131  Courier authentication library is installed by the system's
132  package manager. The LDAP, MySQL, and PostgreSQL support was
133  placed into optional sub-packages which are not installed. Even
134  though all of these modules were initially compiled, the optional
135  authentication modules were not installed.</p>
136
137  <p>This is normal. authdaemond will simply ignore any
138  authentication module it cannot find, and will activate only
139  those modules that are available. When an authentication request
140  comes in, all of the modules will be executed, one after the
141  other, resulting in one of three conditions:</p>
142
143  <dl>
144    <dt>ACCEPT</dt>
145
146    <dd>The user was authenticated successfully</dd>
147
148    <dt>REJECT</dt>
149
150    <dd>The module did not know this username, or the user gave
151    invalid credentials. The request is passed to the next
152    module.</dd>
153
154    <dt>TEMPFAIL</dt>
155
156    <dd>The module suffered an internal failure, such as inability
157    to contact an external database. The login is rejected, and no
158    further modules are tried.</dd>
159  </dl>
160
161  <p>In a typical Courier installation the authentication request
162  is sent, via a filesystem socket, to a pool of <b>authdaemond</b>
163  processes (note the extra "d" on the end) which perform the
164  actual work. authdaemond, in turn, contains other authentication
165  modules such as authpam, authmysql, and so on.</p>
166
167  <p>If <code>authdaemond</code> is running successfully, then it
168  will in turn run each of the modules it is linked against. If any
169  one returns REJECT then the next is tried; if any returns
170  TEMPFAIL or ACCEPT then no further modules are tried.</p>
171
172  <p>So a typical example might look like this:</p>
173  <pre>
174Apr 14 14:07:15 billdog authdaemond: received auth request, service=pop3, authtype=login
175Apr 14 14:07:15 billdog authdaemond: authcustom: trying this module
176Apr 14 14:07:15 billdog authdaemond: authcustom: nothing implemented in do_auth_custom()
177Apr 14 14:07:15 billdog authdaemond: authcustom: REJECT - try next module
178Apr 14 14:07:15 billdog authdaemond: authcram: trying this module
179Apr 14 14:07:15 billdog authdaemond: cram: only supports authtype=cram-*
180Apr 14 14:07:15 billdog authdaemond: authcram: REJECT - try next module
181Apr 14 14:07:15 billdog authdaemond: authuserdb: trying this module
182Apr 14 14:07:15 billdog authdaemond: userdb: opened /etc/userdb.dat
183Apr 14 14:07:15 billdog authdaemond: userdb: looking up 'brian'
184Apr 14 14:07:15 billdog authdaemond: userdb: entry not found
185Apr 14 14:07:15 billdog authdaemond: authuserdb: REJECT - try next module
186Apr 14 14:07:15 billdog authdaemond: authpam: trying this module
187Apr 14 14:07:15 billdog authdaemond: authpam: sysusername=brian, sysuserid=&lt;null&gt;, sysgroupid=1001, homedir=/home/brian, address=brian, fullname=Brian Candler, maildir=&lt;null&gt;, quota=&lt;null&gt;, options=&lt;null&gt;
188Apr 14 14:07:15 billdog authdaemond: pam_service=pop3, pam_username=brian
189Apr 14 14:07:15 billdog authdaemond: dopam successful
190Apr 14 14:07:15 billdog authdaemond: authpam: ACCEPT, username brian
191</pre>
192
193  <p>What's happening here?</p>
194
195  <ul>
196    <li>The request was received by 'authdaemond'</li>
197
198    <li>It tries 'authcustom' - this module does nothing unless you
199    have customised it yourself, so it REJECTs the request</li>
200
201    <li>It tried 'authcram', but since this was a request with
202    authtype=login (rather than authtype=cram-md5, say), this
203    module cannot handle it so it REJECTs</li>
204
205    <li>'authuserdb' has a go. In this case there is an
206    /etc/userdb.dat file for it to look in, but the requested
207    username 'brian' does not exist in there, so it REJECTs</li>
208
209    <li>'authpam' has a go. It finds the username and home
210    directory in /etc/passwd, and then calls the PAM subsystem to
211    authenticate. The authentication is successful.</li>
212  </ul>
213
214  <p>So, in principle, debugging is straightforward. Watch the
215  modules operate, search for the one which you <i>think</i> should
216  be authenticating the user, and if it is not, check for REJECT
217  (user not known or password mismatch) or TEMPFAIL (internal
218  error) status. Additional messages should indicate why this
219  status was returned.</p>
220
221  <h2>4. Read the documentation</h2>
222
223  <p>Most of the configuration files like authldaprc, authmysql are
224  well documented with comments.</p>
225
226  <p>For the nitty-gritty details of authentication modules, see
227  <a href="http://www.courier-mta.org/authlib.html">man
228  authlib</a>. There is probably a copy of this manpage installed
229  on your system; if that command doesn't work, try one of
230  these:</p>
231  <pre>
232# man -M @prefix@/man authlib
233or
234# cd /path/to/sources
235# cd authlib
236# nroff -mandoc authlib.7.in | less
237</pre>
238
239  <p>If you are using userdb authentication, you definitely need to
240  read <a href="makeuserdb.html">man makeuserdb</a>, <a href=
241  "userdb.html">man userdb</a>, and <a href="userdbpw.html">man
242  userdbpw</a>.</p>
243
244  <h2>5. Use the mailing list</h2>
245
246  <p>Please read through the common problems and solutions at the
247  bottom of this document. The next thing to do, of course, is
248  search the web to see if your particular problem has been seen
249  before and solved. <a href="http://www.google.com">Google</a> is
250  very good for this.</p>
251
252  <p>If you still cannot work out what the problem is, then you can
253  ask on the appropriate <a href=
254  "http://www.courier-mta.org/links.html">mailing list</a>. But
255  before you post, please gather together all the following
256  information:</p>
257
258  <ul>
259    <li>The operating system and version you are running</li>
260
261    <li>The versions of packages you have installed</li>
262
263    <li>The <code>./configure</code> command line you gave to build
264    it</li>
265
266    <li>If you didn't build it yourself, where you got the package
267    from (and if possible, find out from the packager what options
268    they used to build it)</li>
269
270    <li>The versions of any other relevant software which you are
271    linking against, e.g. openldap, mysql, pgsql</li>
272
273    <li>The transcript of the 'telnet' session you used to manually
274    test server connections</li>
275
276    <li>The corresponding debug output which was generated for that
277    session</li>
278
279    <li>The contents of relevant configuration files, e.g.
280    authldaprc, authmysqlrc, imapd, pop3d</li>
281
282    <li>A copy of the database entry you are trying to authenticate
283    against: e.g. the line from your userdb file, an LDAP entry, a
284    row from your mysql table, the line in /etc/password, etc.</li>
285  </ul>
286
287  <p>If you include all this, you are <i>much</i> more likely to
288  get a helpful response.</p>
289  <hr />
290
291  <h2>Frequently seen authentication problems and solutions</h2>
292
293  <p>See also the <a href=
294  "http://www.courier-mta.org/FAQ.html">Courier MTA FAQ</a></p>
295
296  <h3>When I try to login with POP3 using telnet, the server
297  disconnects immediately after the "PASS" command, without giving
298  a -ERR response</h3>
299
300  <p>The reason for this error will probably be found in your mail
301  logs. Usually it indicates either that the home directory does
302  not exist (chdir failed), or the Maildir has not been created.
303  See 'man maildirmake'.</p>
304
305  <h3>PAM authentication says "pam_start failed, result 4 [Hint:
306  bad PAM configuration?]"</h3>
307
308  <p>Probably your PAM configuration is bad. If you have
309  /etc/pam.d/other, then try simply removing /etc/pam.d/pop3 and
310  /etc/pam.d/imap and see if it works (this is sufficient for
311  FreeBSD). Otherwise, try copying one of your existing
312  /etc/pam.d/xxx files to /etc/pam.d/pop3, imap or webmail
313  respectively.<br />
314  The result value is a PAM_XXXX constant from
315  <code>/usr/include/security/pam_constants.h</code> (this file may
316  be in a different location on your system). Under FreeBSD, 4 is
317  PAM_SYSTEM_ERR.</p>
318
319  <h3>When I connect on the SSL ports (995 or 993), the server
320  accepts the connection but then immediately disconnects</h3>
321
322  <p>You probably didn't install any SSL certificates. Courier-imap
323  comes with scripts you can run to do this for you:</p>
324  <pre>
325# @prefix@/sbin/mkimapdcert
326# @prefix@/sbin/mkpop3dcert
327</pre>
328
329  <h3>I expected the authentication library to compile authmysql
330  (or some other module), but it's not there</h3>
331
332  <p>If the mysql authentication module did not compile, then
333  perhaps ./configure was unable to find your mysql libraries (you
334  can read through the file 'config.log' in the source directory to
335  see what it found). You may need to force it to look in the right
336  place, as follows:</p>
337  <pre>
338# ./configure --with-authmsql --with-mysql-libs=/usr/local/mysql/lib  \
339              --with-mysql-includes=/usr/local/mysql/include
340</pre>
341
342  <p>On some systems (e.g. FreeBSD), the mysqlclient library
343  depends on the math and compression libraries. For these systems,
344  try:</p>
345  <pre>
346# LDFLAGS="-lm -lz" ./configure --with-authmysql ... same as before
347</pre>
348
349  <h3>The POP3/IMAP server says "Temporary problem, please try
350  again later" when a bad password is entered</h3>
351
352  <p><code>authdaemond</code> tries each of the configured
353  authentication modules in turn, until either one accepts the
354  login, or they have all rejected it (in which case the usual
355  "Login failed" error is returned, and the user can try
356  again).</p>
357
358  <p>However, if one of these modules is unable to run because some
359  resource is not available, then it gives a "temporary failure"
360  response and no further modules are tried. You should find the
361  exact cause in your mail logs, but typically it means that you
362  have a module like 'authmysql' in your module list, but the mysql
363  database is not running.</p>
364
365  <p>So unless you actually do have account data in mysql (in which
366  case you need to fix your mysql setup), you should remove
367  'authmysql' and any other modules you do not use from
368  <code>authmodulelist</code> in <code>authdaemonrc</code>.</p>
369</body>
370</html>
371

README.authmysql.myownquery

1
2
3
4
5	    Developer Notes for courier-imap-myownquery.patch
6
7
8
9
10							document version: 1.03
11							author:	Pawel Wilk
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
280 What's that?
29
301 Modifications overview
31
322 Definitions
33
343 New data types
35  3.1 struct var_data
36  3.2 typedef size_t (*parsefunc)
37
384 New functions
39  4.1 get_variable
40  4.2 parse_core
41  4.3 ParsePlugin_counter
42  4.4 ParsePlugin_builder
43  4.5 parse_string
44  4.6 validate_password
45  4.7 get_localpart
46  4.8 get_domain
47  4.9 parse_select_clause
48  4.10 parse_chpass_clause
49
505 Ideas and TODO
51
526 Thanks
53
54
55
56
57		    *-----------------------
58		     0 What's that?
59		    *-----------------------
60
61Courier-imap-myownquery.patch allows administrator to set own SQL queries
62used by authdaemon to authenticate user (including fetchig credentials) and to
63change user's password. It allows to construct SELECT or UPDATE clause in the
64configuration file (authmysqlrc or authpgsqlrc) by adding two new configuration
65variables: MYSQL_SELECT_CLAUSE or PGSQL_SELECT_CLAUSE and MYSQL_CHPASS_CLAUSE
66or PGSQL_CHPASS_CLAUSE. It may be useful in the mail environments where there
67is such a need to have different database structure and/or tables scheme than
68expected by authmysql or authpgsql module.
69
70It also implements a small parsing engine for substitution variables which
71may appear in the clauses and are used to put informations like username
72or domain into the right place of a query.
73
74This patch was created using `diff -Nur` on courier-imap-1.3.12 source.
75
76
77
78
79
80		    *-----------------------
81		     1 Modifications overview
82		    *-----------------------
83
84Modified files:	authmysqllib.c authmysqlrc authpgsqllib.c authpgsqlrc
85
86Each modified set of instructions is marked by my e-mail address:
87siefca@pld.org.pl (for MySQL files) or tom@minnesota.com (for PostgreSQL files)
88
89Changes in the current source code are related to:
90
91- sections where the queries are constructed
92  (including memory allocation for the buffers)
93
94	when MYSQL_SELECT_CLAUSE or MYSQL_CHPASS_CLAUSE or
95        PGSQL_SELECT_CLAUSE or PGSQL_CHPASS_CLAUSE  is
96	used then the query goes through the parsing functions
97	passing over current memory allocation and query construction
98	subroutines
99
100- section where the configuration file is read
101
102	i've had to modify read_env() function to allow line breaks
103	- now each sequence of the backslash as a first character and
104	newline as the second is replaced by two whitespaces while
105	putting into the buffer
106
107- sections where the query is constructed
108
109	selection is made, depending on configuration variables which
110	are set or not - if own query is used
111
112
113
114
115
116		    *-----------------------
117		     2 Definitions
118		    *-----------------------
119
120#define		MAX_SUBSTITUTION_LEN	32
121#define		SV_BEGIN_MARK		"$("
122#define		SV_END_MARK		")"
123#define		SV_BEGIN_LEN		((sizeof(SV_BEGIN_MARK))-1)
124#define		SV_END_LEN		((sizeof(SV_END_MARK))-1)
125
126These definitions allows to change substitution marks in an easy way.
127SV_BEGIN_MARK refers to sequence of characters treated as a prefix of
128each substitution variable and SV_END_MARK refers to string which is
129a closing suffix. If the expected substitution variable is called
130'local_part' (without apostrophes) then '$(local_part)' is a valid
131string representation for SV_BEGIN_MARK set to "$(" and SV_END_MARK to ")".
132MAX_SUBSTITUTION_LEN defines maximal length of a substitution variable's
133identifier (name).
134
135The last two definitions are just for code simplification.
136
137
138
139
140
141
142		    *-----------------------
143		     3 New data types
144		    *-----------------------
145
146This section describes new data type definitions and variables.
147
1483.1 struct var_data
149
150struct var_data {
151	const char *name;
152	const char *value;
153	const size_t size;
154	size_t value_length;
155	} ;
156
157This structure holds information needed by parsing routines.
158Using var_data array you may specify a set of string substitutions
159which should be done while parsing a query. Last element in array
160should have all fields set to zero (null).
161
162name field	- should contain substituted variable name
163value 		- should contain string which replaces it
164size		- should contain string size including the last zero byte ('\0')
165value_length	- should be set to zero - it is used as a value size cache
166
167
168explanation: size is used to increase speed of calculation proccess
169	     value_length is used to cache length of a value during the
170	     parsing subroutines - it helps when substitution variable
171	     occures more than once within the query
172
173Example:
174
175struct var_data vdt[] =	{
176    {"some",	"replacement",	sizeof("some"),		0},
177    {"anotha",	NULL,		sizeof("anotha"),	0},
178    {NULL,	NULL,		0,			0}
179};
180
181In this example we've declared that $(some) in the query should be
182replaced by 'replacement' text, and replacement for $(anotha) will
183be defined in the code before passing on the array pointer to
184the paring function.
185
186
1873.2 typedef size_t (*parsefunc)
188
189typedef int (*parsefunc)(const char *, size_t, void *);
190
191This type definition refers to the function pointer, which is used
192to pass plugin functions into the core parsing subroutine. This definition
193is included to simplify the declaration of the parse_core() function.
194
195
196
197
198
199		    *-----------------------
200		     4 New functions
201		    *-----------------------
202
203This section describes added functions.
204
2054.1 get_variable
206
207NAME
208
209	get_variable
210
211SYNOPSIS
212
213	static const struct var_data *get_variable (const char *begin,
214						    size_t len,
215  		  	        	  	    struct var_data *vdt);
216
217DESCRIPTION
218
219	This function searches an array pointed by vdt and tries to find
220	the substitution variable, which name is identified with begin
221	pointer and length of len bytes long.
222
223	This function is also responsible for updating length cache field
224	of vdt elements and validating requested variables.
225
226	This function repports errors by sending human readable
227	messages to the standard error stream.
228
229RETURN VALUE
230
231	This function returns a pointer to the array element which is
232	structure of var_data type, which contains variable definition
233	of a given name. It returns NULL on error or failure.
234
235
2364.2 parse_core
237
238NAME
239
240	parse_core
241
242SYNOPSIS
243	static int    parse_core (const char *source, struct var_data *vdt,
244				  parsefunc outfn, void *result);
245
246DESCRIPTION
247
248	This is the parsing routine for query strings containing the
249	substitution variables. It reads the string pointed with source
250	and tries to catch a valid substitution variables or parts which
251	are plain text blocks. The main purpose of using this function
252	it to split source string into parts and for each part call
253	outfn() function. Those parts are substrings identified by
254	pointer to some element of the source string and size.
255	Those elements are the result of splitting source string into
256	logical parts: plain text substrings and substitution variables'
257	values. To get the values of any found substitution variables
258	parse_core() uses get_variable() function. To find places
259	where substitution variables occurs it uses strstr() function
260	in conjunction with SV_BEGIN_MARK and SV_END_MARK definitions.
261	It passes vdt structure pointer to get_variable() function is
262	it calls it.
263
264	outfn() function should be passed by its pointer which
265	refers to declaration:
266
267 	int (*outfn)    (const char *begin,
268			 size_t string_length,
269			 void *void_pointer);
270
271	Each time outfn() is called the result argument of parse_core()
272	is passed to the outfn() as a last argument (void_pointer).
273
274	Example:
275
276	    Example string "$(local_part) AND $(domain)" will cause the
277	    outfn() to be called 3 times. First time for a value of
278	    $(local_part) substitution variable, second time
279	    for " AND " string, and the last time for $(domain) variable's
280	    value. Variables are passed to outfn() by their (found) values,
281	    plain text blocks are passed as they appear.
282
283	This function repports errors by sending human readable
284	messages to the standard error stream.
285
286RETURN VALUE
287
288	This function returns -1 if an error has occured and 0 if
289	everything went good.
290
2914.3 ParsePlugin_counter
292
293NAME
294
295	ParsePlugin_counter
296
297SYNOPSIS
298
299	int    ParsePlugin_counter (const char *begin, size_t len,
300			            void *vp);
301
302DESCRIPTION
303
304	This is parsing plugin function. It simply increments the value
305	found in the memory area pointed by vp. It assumes that
306	the memory area is allocated for the variable of size_t
307	type and that area was passed by (size_t *) pointer.
308	The value is incremented by len argument. Begin argument
309	is not used.
310
311	This function repports errors by sending human readable
312	messages to the standard error stream.
313
314RETURN VALUE
315
316	This function returns the variable size or -1 if an error
317	has occured, 0 if everything went good.
318
3194.4 ParsePlugin_builder
320
321NAME
322
323	ParsePlugin_builder
324
325SYNOPSIS
326
327	int    ParsePlugin_builder (const char *begin, size_t len,
328			            void *vp);
329
330DESCRIPTION
331
332	This is parsing plugin function. It simply copies len bytes
333	of a string pointed by begin to the end of memory area pointed by
334	vp. It assumes that the area pointed by vp is passed by (char **)
335	type pointer and refers to the (char *) pointer variable.
336	After each call it shifts the value of pointer variable (char *)
337	incrementing it by len bytes. Be careful when using this function
338	- its changes the given pointer value. Always operate on an
339	additional pointer type variable when passing it as the third
340	argument.
341
342RETURN VALUE
343
344	This function returns the variable size or -1 if an error
345	has occured, 0 if everything went good.
346
3474.5 parse_string
348
349NAME
350	parse_string
351
352SYNOPSIS
353
354	static char *parse_string (const char *source, struct var_data *vdt);
355
356DESCRIPTION
357
358	This function parses the string pointed with source according to the
359	replacement instructions set in var_data array, which is passed with
360	its pointer vdt. It produces changed string located in newly allocated
361	memory area.
362
363	This function calls parse_core() function with various parsing
364	subroutines passed as function pointers.
365
366	1. It uses parse_core() with ParsePlugin_counter to obtain the
367	   total amount	of memory needed for the output string.
368
369	2. It allocates the memory.
370
371	3. It uses parse_core() with ParsePlugin_builder to build the
372	   output string.
373
374	This function repports errors by sending human readable
375	messages to the standard error stream.
376
377RETURN VALUE
378
379	Function returns pointer to the result buffer or NULL
380	if an error has occured.
381
382WARNINGS
383
384	This function allocates some amount of memory using standard
385	ANSI C routines. Memory allocated by this function should be
386	freed with free().
387
388
3894.6 validate_password
390
391NAME
392	validate_password
393
394SYNOPSIS
395
396	static const char *validate_password (const char *password);
397
398DESCRIPTION
399
400	This function checks whether password string does contain
401	any dangerous characters, which may be used to pass command
402	strings to the database connection stream. If it founds one
403	it replaces it by the backslash character.
404
405RETURN VALUE
406
407	It returns a pointer to the static buffer which contains
408	validated password string or NULL if an error has occured.
409
410
4114.7 get_localpart
412
413NAME
414
415	get_localpart
416
417SYNOPSIS
418
419	static const char *get_localpart (const char *username);
420
421DESCRIPTION
422
423	This function detaches local part of an e-mail address
424	from string pointed with username and puts it to the
425	buffer of the fixed length. All necessary cleaning is
426	made on the result string.
427
428RETURN VALUE
429
430	Pointer to the static buffer containing local part or
431	NULL if there was some error.
432
433
4344.8 get_domain
435
436NAME
437
438	get_domain
439
440SYNOPSIS
441
442	static const char *get_domain (const char *username,
443				       const char *defdomain);
444
445DESCRIPTION
446
447        This function detaches domain part of an e-mail address
448	from string pointed with username and puts it to the
449	buffer of the fixed length. All necessary cleaning is
450	made on the result string. If function cannot find domain
451	part in the string the string pointed by defdomain is
452	used instead.
453
454RETURN VALUE
455
456        Pointer to the static buffer containing domain name or
457	NULL if there was some error.
458
459
4604.9 parse_select_clause
461
462NAME
463
464	parse_select_clause
465
466SYNOPSIS
467
468	static char *parse_select_clause (const char *clause,
469					  const char *username,
470                                  	  const char *defdomain);
471
472DESCRIPTION
473
474	This function is a simple wrapper to the parse_string()
475	function. It parses a query pointed by caluse. username
476	and defdomain strings are used to replace corresponding
477	substitution strings if present in the query: $(local_part)
478	and $(domain).
479
480
481RETURN VALUE
482
483	Same as parse_string().
484
485
4864.10 parse_chpass_clause
487
488NAME
489
490        parse_chpass_clause
491
492SYNOPSIS
493
494        static char *parse_chpass_clause (const char *clause,
495                                          const char *username,
496                                          const char *defdomain,
497					  const char *newpass,
498					  const char *newpass_crypt);
499
500DESCRIPTION
501
502	This function is a simple wrapper to the parse_string()
503	function. It parses a query pointed by caluse. username,
504	defdomain, newpass and newpass_crypt strings are used to
505	replace corresponding substitution strings if present in
506	the query: $(local_part), $(domain), $(newpass),
507	$(newpass_crypt).
508
509RETURN VALUE
510
511	Same as parse_string().
512
513
514
515
516
517		    *------------------------
518		     5 Ideas and TODO
519		    *------------------------
520
521- solve problem with fixed buffer length of local part and the domain part
522  strings after split						(problem?)
523- allow admin to set a group name instead of numerical group id
524- allow admin to set a username instead of numerical user id
525
526- add clauses:
527
528  - MYSQL_PRESELECT_CLAUSE (query which comes before MYSQL_SELECT_CLAUSE)
529  - MYSQL_POSTSELECT_CLAUSE (query which comes after MYSQL_SELECT_CLAUSE)
530  - PGSQL_PRESELECT_CLAUSE (query which comes before PGSQL_SELECT_CLAUSE)
531  - PGSQL_POSTSELECT_CLAUSE (query which comes after PGSQL_SELECT_CLAUSE)
532
533
534
535
536
537		    *------------------------
538		     6 Thanks
539		    *------------------------
540
541At the beginning this patch was messy indeed. :> I would like to thank
542Sam Varshavchik for pointing me a lot how to make it more fast and solid.
543I would also thank Philip Hazel, Chris Lightfoot and Mike Bremford which
544by their software capabilities inspired me to write it.
545
546Thomas T. Thai <tom@minnesota.com> ported author's original MySQL code
547to the PostgreSQL module.
548
549---------------------------------------------------------------------------
550
551

README.ldap

1LDAP support based on a patch by:
2Luc Saillard <luc.saillard@alcove.fr>  Thu, 30 Dec 1999 20:33:08 +0100
3
4Adapted as a generic authlib authentication module - SV 12/31/99.
5
6Configuration File
7------------------
8
9     LDAP configuration is placed in the file authldaprc, which is installed,
10     by default, as /usr/lib/courier-imap/etc/authldaprc.
11     Use --with-authldaprc=pathname to override the location.
12
13     This file must be owned by root and have the permissions set to 0400
14     because the LDAP administrator password is stored in this file.
15
16     See the default authldaprc for more information.
17
18     CC both me and Luc Saillard for questions on authldap.
19
20Schema
21------
22
23OpenLDAP 2.0 defaults to schema checking on all directories.  The file
24authldap.schema contains a definition of a LDAP objects
25CourierMailAccount, CourierMailAlias, and CourierDomainAlias.
26
27Only CourierMailAccount is used for mailbox authentication (i.e. IMAP,
28webmail).  The other two objects are used by LDAP-based mail routing
29in the Courier Mail Server.
30
31The file authldap.ldif contains an ldif format definition of the same objects.
32This is the same schema definition as in authldap.schema, except in the ldif
33format.
34
35Here are some sample LDAP objects that use this schema:
36
37dn: o=example, c=com
38ObjectClass: organization
39o: example
40c: com
41
42dn: mail=xyz123@example.com, o=example, c=com
43ObjectClass: CourierMailAccount
44ObjectClass: person
45cn: Xavier Y Zimmerman
46sn: Zimmerman
47mail: xyz123@example.com
48clearPassword: tux
49userPassword: {MD5}WrbkuYvH+3FvwH7Zj+34Ag==
50homeDirectory: /home/xyz123
51uidNumber: 1001
52gidNumber: 1001
53
54dn: mail=mailalias@example.com, o=example, c=com
55ObjectClass: CourierMailAlias
56ObjectClass: nisMailAlias
57cn: mailalias
58mail: mailalias
59maildrop: xyz123
60
61dn: virtualdomain=domain.com, o=example, c=com
62ObjectClass: nisMailAlias
63ObjectClass: CourierDomainAlias
64cn: domain.com
65virtualdomain: domain.com
66virtualdomainuser: wxyz456
67
68
69Notice on Luc's original patch:
70-------------------------------
71
72  Copyright (C) 1999 Luc Saillard
73
74  This program is free software; you can redistribute it and/or modify
75  it under the terms of the GNU General Public License as published by
76  the Free Software Foundation; either version 2 of the License, or
77  (at your option) any later version.
78
79  This program is distributed in the hope that it will be useful,
80  but WITHOUT ANY WARRANTY; without even the implied warranty of
81  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
82  GNU General Public License for more details.
83
84  You should have received a copy of the GNU General Public License
85  along with this program; if not, write to the Free Software
86  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
87
88

README_authlib.html.in

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