authlib.html.in
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:41k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
  2.                       "http://www.w3.org/TR/REC-html40/loose.dtd">
  3. <html>
  4. <head>
  5.   <title>authlib - Courier Authentication Library</title>
  6.   <!-- $Id: authlib.html.in,v 1.11 2000/04/27 23:41:27 mrsam Exp $ -->
  7.   <!-- Copyright 1998 - 1999 Double Precision, Inc.  See COPYING for -->
  8.   <!-- distribution information. -->
  9.   <!-- SECTION 8 -->
  10.   <meta http-equiv="Content-Type" content="text/html">
  11. </head>
  12. <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B"
  13. alink="#FF0000">
  14. <h1>authlib - Courier Authentication Library</h1>
  15. <h2>SYNOPSIS</h2>
  16. <pre>   authpam <i>program arg1 arg2...</i>
  17.    authpwd <i>program arg1 arg2...</i>
  18.    authshadow <i>program arg1 arg2...</i>
  19.    authuserdb <i>program arg1 arg2...</i>
  20.    authvchkpw <i>program arg1 arg2...</i>
  21.    authcram <i>program arg1 arg2...</i>
  22.    authmysql <i>program arg1 arg2...</i>
  23.    authldap <i>program arg1 arg2...</i>
  24.    authdaemon <i>program arg1 arg2...</i>
  25.    authdaemond (start|stop|restart)</pre>
  26. <h2>DESCRIPTION</h2>
  27. <p>These modules read an account name and password from an external
  28. application, then return an indication to the external application whether or
  29. not the account name and password is valid. These modules cannot be normally
  30. executed from the command line because they expect to be executed by a
  31. separate application, which provides authentication information via
  32. environment variables and specially prepared pipes.</p>
  33. <p>These authentication modules are usually installed automatically by an
  34. application that uses them. Not every one of these modules will be installed.
  35. Different modules implement different ways of authenticating the account name
  36. and password. Only the modules that are compatible with your system will be
  37. installed by default.</p>
  38. <p><code>authpwd</code> validates the account name and password against your
  39. <code>/etc/passwd</code> file.</p>
  40. <p><code>authshadow</code> validates the account name and password against
  41. your <code>/etc/shadow</code> file.</p>
  42. <p><code>authuserdb</code> validates the account name and password against
  43. your <a href="userdb.html"><code>userdb(8)</code></a> database.</p>
  44. <p><code>authcram</code> also uses <a
  45. href="userdb.html"><code>userdb(8)</code></a>, but implements a
  46. challenge/response authentication mechanism (CRAM), instead of the traditional
  47. userid/password.</p>
  48. <p><code>authpam</code> validates the account name and password using your
  49. Pluggable Authentication Module (PAM) library.  <code>authpam</code> allows
  50. PAM modules to be used to authenticate passwords by any application that uses
  51. this authentication library.</p>
  52. <p><code>authvchkpw</code> supports existing vchkpw-based virtual domain
  53. setups. New installations should use the <a
  54. href="userdb.html"><code>userdb(8)</code></a> database.</p>
  55. <p><code>authldap</code> is an experimental module that uses LDAP for
  56. authentication. <code>authldap</code> will authenticate clear-text or crypt-ed
  57. passwords in an LDAP database. If clear-text passwords are used,
  58. <code>authldap</code> will also be able to handle CRAM authentication, if the
  59. application that uses this authentication library supports CRAM
  60. authentication. See below for more information.</p>
  61. <p><code>authmysql</code> is another experimental module that authenticates
  62. against a MySQL table.  See below for more information.</p>
  63. <p><code>authdaemon</code> is a background daemon proxy. See "<a
  64. href="#authdaemon"><code>AUTHDAEMON</code> authentication module</a>" for more
  65. information.</p>
  66. <p>As previously mentioned, only those modules that are appropriate to your
  67. particular system will be installed. The <code>authpam</code> module will be
  68. installed only if your system supports PAM authentication.
  69. <code>authldap</code> will be installed only if LDAP client libraries are
  70. available. <code>authpwd</code> and <code>authshadow</code> will not be
  71. installed if you have PAM authentication or LDAP authentication.
  72. <code>authvchkpw</code> is usually installed only if your system has the
  73. vpopmail/vchkpw account. <code>authuserdb</code> is usually installed in any
  74. case. <code>authcram</code> is installed only if the application that uses
  75. this authentication library supports CRAM authentication.
  76. <code>authmysql</code> is usually installed if MySQL client libraries are
  77. found, and <code>authvchkpw</code> is not installed.</p>
  78. <h2><code>AUTHLDAP</code> authentication module</h2>
  79. <p>This section applies if you have the <code>authldap</code> authentication
  80. module installed. This is an experimental authentication module, and may not
  81. be stable.</p>
  82. <p>The <code>authldap</code> authentication module reads a configuration file.
  83. The configuration file tells <code>authldap</code> where to obtain the
  84. information that it needs. A default configuration file will be installed in
  85. <code>@authldaprc@</code>.</p>
  86. <p>It will be necessary to edit this file in order to properly configure
  87. <code>authldap</code>. This configuration file contains a list of settings,
  88. one per line. Each line starts with the name of the setting, followed by one
  89. or more whitespace characters, followed by the setting value. Leading or
  90. trailing whitespace is not allowed.</p>
  91. <p>Comments in the default configuration file describe what each setting does.
  92. <code>LDAP_SERVER</code>, <code>LDAP_PORT</code>, <code>LDAP_BASEDN</code>,
  93. <code>LDAP_BINDDN</code>, and <code>LDAP_BINDPW</code> specify your LDAP
  94. server's coordinates. <code>LDAP_TIMEOUT</code> sets the timeout for the LDAP
  95. query.</p>
  96. <p>The LDAP query is keyed by the E-mail address. The <code>LDAP_MAIL</code>
  97. settings sets the LDAP attribute that is searched for, which should be "mail".
  98. The E-mail address should be of the form <code>user@domain</code>. If the
  99. domain is missing, authldap appends <code>LDAP_DOMAIN</code> to the query.</p>
  100. <p><code>authldap</code> will need to obtain the following attributes: the
  101. account's home directory, user and group ids, and the account password. These
  102. attributes are required. The password can be a clear-text password, or a
  103. crypt-ed password.</p>
  104. <p>There are also several optional attributes which, if present, will be used:
  105. the full name of the user, and the location of the user's main mailbox. If the
  106. mailbox location is not specified, the default location, as defined by the
  107. system administrator, will be used.</p>
  108. <p>The configuration file lists which LDAP attributes contain which
  109. properties. If all your accounts share the same global user and group IDs,
  110. which may be the case if you are authenticating access to a large number of
  111. virtual accounts, you can set the global user and group ID with the
  112. <code>LDAP_GLOB_UID</code> and <code>LDAP_GLOB_GID</code> setting. Otherwise,
  113. you must define <code>LDAP_UID</code> and <code>LDAP_GID</code> to be the LDAP
  114. attributes that contain the numerical user and group IDs.</p>
  115. <p><code>LDAP_HOMEDIR</code> specifies the name of the required LDAP attribute
  116. which contains the account's home directory, <code>LDAP_MAILDIR</code>
  117. specifies the name of the optional attribute that specifies the location of
  118. the default mailbox. If your virtual accounts have no home directory, set both
  119. <code>LDAP_HOMEDIR</code> and <code>LDAP_MAILDIR</code> to the same LDAP
  120. attribute that specifies the location of the virtual account's mailbox.</p>
  121. <p><code>LDAP_FULLNAME</code> is an optional LDAP attribute. Not every
  122. application that uses this authentication library will need it.</p>
  123. <p>You must define either LDAP_CLEARPW and LDAP_CRYPTPW. It is possible to
  124. define both of them, but, in practice, only one of them needs to be defined.
  125. If you store clear-text passwords, set <code>LDAP_CLEARPW</code> to the name
  126. of the LDAP attribute that holds the clear-text password. If you store
  127. crypt-ed passwords in LDAP, set <code>LDAP_CRYPTPW</code> to the name of the
  128. LDAP attribute that holds the crypt-ed password.</p>
  129. <p>If you store clear-text passwords, <code>authldap</code> will be able to
  130. carry out CRAM authentication. Only userid/password authentication is possible
  131. if crypt-ed password are used.</p>
  132. <h2><code>AUTHMYSQL</code> authentication module</h2>
  133. <p>This section applies if you have the <code>authmysql</code> authentication
  134. module installed. This is an experimental authentication module, and may not
  135. be stable.</p>
  136. <p><code>authmysql</code> functions like <code>authldap</code>, but uses a
  137. MySQL The <code>authmysql</code> authentication module reads a configuration
  138. file. The configuration file tells <code>authmysql</code> where to obtain the
  139. information that it needs. A default configuration file will be installed in
  140. <code>@authmysqlrc@</code>.</p>
  141. <p>It will be necessary to edit this file in order to properly configure
  142. <code>authmysql</code>. This configuration file contains a list of settings,
  143. one per line. Each line starts with the name of the setting, followed by one
  144. or more whitespace characters, followed by the setting value. Leading or
  145. trailing whitespace is not allowed.</p>
  146. <p>Comments in the default configuration file describe what each setting does.
  147. Consult the configuration file for more information.</p>
  148. <a name="authdaemon"></a>
  149. <h2><code>AUTHDAEMON</code> authentication module</h2>
  150. <p>This authentication library is used by applications in one of two ways: 1)
  151. individual authentication methods are compiled as standalone modules, or 2)
  152. individual authentication methods are statically linked with the
  153. application.</p>
  154. <p>Standalone modules have greater flexibility, but may not be very efficient
  155. in environments that use a database back-end, where the database connection
  156. and teardown is comparatively expensive. Each authentication request requires
  157. a new database connection to be established, and torn down.  An example of
  158. when this happens is with the <code>authldap</code> and <code>authmysql</code>
  159. authentication modules.</p>
  160. <p>Even applications that statically linked with this authentication library
  161. may not fare much better.  Typically, an instance of the application is
  162. invoked for every user, so essentially it works out to be the same thing.</p>
  163. <p>The <code>authdaemon</code> module is not a new authentication method.
  164. Enabling <code>authdaemon</code> in addition to any other modules will result
  165. in <code>authdaemon</code> being built as the only "official" authentication
  166. module. However, the remaining modules are compiled into a separate process,
  167. "<code>authdaemond</code>".</p>
  168. <p>It will be necessary to add the following command to your system startup
  169. script, to start <code>authdaemond</code> at system boot:</p>
  170. <pre>    @libexecdir@/authlib/authdaemond start</pre>
  171. <p>This command starts an authentication daemon. The <code>authdaemon</code>
  172. authentication module takes an authentication request, and forwards it to the
  173. permanently running <code>authdaemond</code> daemon process, then returns the
  174. result to the application. The application "sees" only the
  175. <code>authdaemon</code> authentication module, which swallows every
  176. authentication requests, and passes it along to the <code>authdaemond</code>
  177. for processing, where all the real authentication modules do their stuff.</p>
  178. <p>It is necessary to start the <code>authdaemond</code> process as early as
  179. possible, when the system boots, because until that happens no authentication
  180. can take place. Additionally, the <code>@authdaemonvar@</code> subdirectory
  181. must be created in advance, that contains the filesystem socket used for
  182. interprocess communication, and other miscellania. It goes without saying that
  183. the underlying filesystem for <code>@authdaemonvar@</code> must support
  184. filesystem domain sockets. This pretty much excludes all network filesystems,
  185. so this directory must reside on a local disk.</p>
  186. <p><code>@authdaemonvar@</code> MUST NOT HAVE any world-readable, executable
  187. or writable permissions!  Under NO circumstances should this be allowed to
  188. happen.  The exact permissions and ownership of <code>@authdaemonvar@</code>
  189. may vary.  For the standalone versions of Courier-IMAP and SqWebMail,
  190. <code>@authdaemonvar@</code> should be owned by root, and have no group or
  191. world permissions.  For the Courier mail server, <code>@authdaemonvar@</code>
  192. should be owned by the userid that Courier is installed under, and it must be
  193. readable and writable by the Courier user and group (but no world
  194. permissions).</p>
  195. <h2>Configuring the <code>authdaemond</code> daemon</h2>
  196. <p>The <code>@authdaemonrc@</code> configuration file sets several operational
  197. parameters for the <code>authdaemond</code> process. See the comments in the
  198. default file installed for more information. Currently,
  199. <code>@authdaemonrc@</code> sets two parameters: number of daemon processes,
  200. and authentication modules that will be used.</p>
  201. <p>Although <code>authdaemond</code> might be built with several
  202. authentication modules, not all of them may be used.  This allows for a single
  203. <code>authdaemond</code> build to be made that gets installed on multiple
  204. systems with different authentication needs. The default module list specified
  205. by <code>@authdaemonrc@</code> would be a list of all the available
  206. authentication modules.</p>
  207. <p>The number of <code>authdaemond</code> processes is also set in this
  208. configuration file.  The more processes that are started, the more
  209. authentication requests can be handled.  If <code>authdaemon</code> does not
  210. receive an answer within a moderate amount of time, it will declare an
  211. authentication failure, and abort. Try increasing the number of processes if
  212. you start seeing random authentication failures.  However, that should only be
  213. used as a stop-gap measure.  If the default number of <code>authdaemond</code>
  214. processes proves to be insufficient, it is far more likely that more resources
  215. are needed for the server: more RAM, a faster disk, or a faster CPU, at least
  216. in the humble opinion of the author. Increasing the number of processes should
  217. only be used as a stop-gap measure, until a more thorough analysis on the
  218. bottleneck can be made. secon</p>
  219. <p>After making any changes to @authdaemonrc@, run the following command for
  220. these changes to take effect:</p>
  221. <pre>    @libexecdir@/authlib/authdaemond restart</pre>
  222. <p>The <code>stop</code> command is also available, to shut down the daemon
  223. completely.</p>
  224. <h2>CONFIGURING THE COURIER AUTHENTICATION LIBRARY</h2>
  225. <p>This authentication library is used by applications that typically consist
  226. of two separate parts.  The first part waits for the user to enter the account
  227. name and password. Then, it runs one or more authentication modules, which
  228. check if the account name and password is valid. The second part of the
  229. application is then executed. If the password is valid, the second part of the
  230. application runs normally. Otherwise, the first part is executed again, to try
  231. to read another account name and password.</p>
  232. <p>This manual page provides generic instructions for using this
  233. authentication library. You will need to use the documentation that comes with
  234. each application to determine the filenames corresponding to the first, login,
  235. part and the second, application, part. The following example assumes that the
  236. application consists of the following programs: <code>/usr/bin/getlogin</code>
  237. and <code>/usr/bin/app</code>.  <code>getlogin</code> reads the account name
  238. and password, and <code>app</code> is the actual application.</p>
  239. <p>The following command starts this application with the
  240. <code>authuserdb</code> and <code>authshadow</code> modules:</p>
  241. <pre>/usr/bin/getlogin @prefix@/lib/authuserdb 
  242.                   @prefix@/lib/authshadow 
  243.                   /usr/bin/app</pre>
  244. <p>After obtaining the account name and password, <code>getlogin</code> simply
  245. runs the program specified by its first argument, which is
  246. <code>authuserdb</code>. The remaining command line arguments to
  247. <code>getlogin</code> are received as arguments to <code>authuserdb</code>.
  248. Note that this is not a pipe, there is no | here.  <code>authuserdb</code>
  249. receives the remaining arguments as its own arguments, checks the account name
  250. and password, then runs the program specified by the first argument, which is
  251. authshadow. <code>authshadow</code> receives the remaining argument, checks
  252. the account name and password, if necessary, then runs the program specified
  253. by its first argument.</p>
  254. <p>The protocol implemented by this authentication library permits
  255. multiple modules to try to authenticate the account name and password.
  256. Essentially, to start an application that uses this authentication library,
  257. you run its login part, then pass the pathnames to the authentication modules
  258. to be used as the arguments to the login part of the application. The pathname
  259. to the application part is usually the last argument. Where any module
  260. requires an option or an argument, the option or the argument is provided at
  261. the appropriate point on the command line.</p>
  262. <p>Any application that uses this authentication library can use any
  263. combination of authentication modules that are installed, unless there are
  264. specific restrictions mention in the documentation for each application. All
  265. pathnames must be absolute. Pathnames relative to the current directory are
  266. prohibited.</p>
  267. <p>Each authentication module runs the program specified by its first
  268. argument, after checking the account name and password. So, in the example
  269. given previous <code>/usr/bin/app</code> will be eventually executed by the
  270. last authentication module. Each authentication module checks if the account
  271. name and password has already been validated by a previous authentication
  272. module. If not, it tries to validate the account name and password by itself.
  273. The final module, the application part itself, checks if any authentication
  274. modules successfully validated the account name and password. If not, it will
  275. immediately execute the login part of the application using the same arguments
  276. that were originally used, and the process will begin again. Otherwise, if the
  277. account password was successfully accepted by any authentication module, the
  278. application part runs normally.</p>
  279. <p>The login portion of the application, <code>getlogin</code> in this
  280. example, must be executed by the superuser. After the account password is
  281. successfully validated, the authentication module sets its user and group IDs
  282. of the process to the user group IDs for that account, and sets its home
  283. directory to the account's home directory. However, if all authentication
  284. modules rejected the account name and password, the application module,
  285. <code>app</code> in this example, will still be a superuser process when it
  286. starts. That's fine, because the first thing it does is check if the
  287. authentication succeeded, and, if not, it will run the login process again.
  288. Obviously, you can't use just any application with this authentication
  289. library. An application must be specially written to understand and use this
  290. protocol.</p>
  291. <h2>NETWORK SERVICES</h2>
  292. <p>Applications that use this authentication library are usually network
  293. services, and must be started in response to a network connection. There are
  294. several ways to do that.  One way is to use the <code>inetd(8)</code> daemon.
  295. Here is a sample entry in <code>/etc/inetd.conf</code> for a hypothetical IMAP
  296. server that uses this authentication library:</p>
  297. <pre>imap stream tcp nowait root /usr/bin/imaplogin /usr/bin/imaplogin
  298. @prefix@/lib/authpam /usr/bin/imapserver</pre>
  299. <p>This should all be entered on one line in <code>/etc/inetd.conf</code>.</p>
  300. <p>Note that some <code>inetd</code> implementations automatically infer the
  301. <code>argv[0]</code> argument from the filename.  You can use those
  302. <code>inetd</code> servers by removing the second
  303. <code>/usr/bin/imaplogin</code> entry (in this particular case) ONLY if the
  304. inetd server does NOT strip the pathname from the<code></code>implied
  305. <code>argv[0]</code> argument. The application login process
  306. (<code>imaplogin</code> in this case), MUST know its complete pathname so that
  307. it can be executed again if the first password is rejected.</p>
  308. <h3><code>tcpserver</code></h3>
  309. <p>If you use Dan Bernstein's <code>tcpserver</code>, here's an equivalent
  310. <code>tcpserver</code> startup command for this hypothetical IMAP
  311. application:</p>
  312. <pre>/usr/local/bin/tcpserver -H -R 0 imap 
  313.     /usr/bin/imaplogin @prefix@/lib/authpam /usr/bin/imapserver &amp; </pre>
  314. <h3><code>couriertcpd</code></h3>
  315. <p>If you use the <code>couriertcpd</code> server, here's an equivalent
  316. <code>couriertcpd</code> startup command for this hypothetical IMAP
  317. application:</p>
  318. <pre>/usr/local/bin/couriertcpd -nodnslookup -noidentlookup imap 
  319.    /usr/bin/imaplogin @prefix@/lib/authpam /usr/bin/imapserver &amp; </pre>
  320. <p>You may specify appropriate options for <code>tcpserver</code> and
  321. <code>couriertcpd</code> that are right for you.</p>
  322. <h2>AUTHENTICATION PROTOCOL</h2>
  323. <p>The remainder of this document defines the protocol used by these
  324. authentication modules.</p>
  325. <p>The overall application that uses this authentication library is made up of
  326. at least three processes:</p>
  327. <p>The first process, called a "login process", is started as a superuser
  328. process in response to a network connection, or an equivalent event. It reads
  329. the userid and password, then starts an authentication module and securely
  330. transmits this information to the authentication module.</p>
  331. <p>The second process is an "authentication module" that attempts to validate
  332. the userid and password in some arbitrary fashion. Whether or not the password
  333. is authenticated, the authenticated module runs the next process. That's
  334. because the next process can be another authentication module, or the
  335. authenticated client process (see below). If one authentication module fails,
  336. another authentication module can be given a chance to authenticate the userid
  337. and password. An authentication module can also decide that other
  338. authentication modules can not be used to attempt to authenticate this userid
  339. and password, because it should be unequivocally rejected.</p>
  340. <p>If the authentication module successfully validates the userid and
  341. password, it sets the process's user and group ID to the authenticated user's,
  342. then sets the current directory to the authenticated user's home directory.
  343. The authentication module may also set some additional environment
  344. variables.</p>
  345. <p>The final process is called the "authenticated client" process in this
  346. documentation. Contrary to its name, it is possible that it will be called
  347. even if all modules rejected the userid and password, so the first thing it
  348. does is check whether that's the case.</p>
  349. <p>If any authentication module permanently rejects a userid and password, or
  350. if the authenticated client detects that all authenticated modules rejected
  351. the userid and password, the original login process is executed again, in
  352. order to try to read another password and start the process again.</p>
  353. <p>It is expected that the login process is initially started by a daemon
  354. process, and it begins with a relatively clean environment. Modules use
  355. environment variables and pipes in order to implement this authentication
  356. protocol. When the login process starts it can check these environment
  357. variables to determine if this is the first time it is run, or if it is
  358. executed again in order to read another userid and password, after the first
  359. pair was rejected.</p>
  360. <h2>AUTHENTICATION MODULES</h2>
  361. <p>The login process is usually invoked by some system daemon process in
  362. response to a network connection.  argv[0] to the login process must be a
  363. complete pathname.  Otherwise, the AUTHUSER environment variable must be set
  364. prior to running the login process, and it must contain a complete pathname.
  365. It is possible that certain systems might strip the full path from argv[0],
  366. leaving just the filename, so use AUTHUSER in that case</p>
  367. <p>Any options for the login process can be specified on the command line.</p>
  368. <p>The first argument after any options must be a full pathname to the first
  369. authentication module to run.</p>
  370. <p>It is possible to run two authentication modules, as previously described.
  371. The complete pathname of the second module should be the next argument.
  372. Additional authentication modules may also be specified in this fashion.</p>
  373. <p>The arguments to the login process end with a complete pathname to the
  374. authenticated client process, followed by any options it requires. Here is a
  375. hypothetical example of a complete invocation of the login process:<br>
  376. <br>
  377. </p>
  378. <pre>  /usr/local/bin/readuserpass -d 
  379.      @prefix@/lib/authuserdb 
  380.      @prefix@/lib/authpam 
  381.      /usr/local/bin/dostuff -x
  382. <br>
  383. </pre>
  384. <p>This example runs <code>/usr/local/bin/readuserpass</code> to read the
  385. userid and password. This process  uses the <code>-d</code> option. This is
  386. followed by two modules - <code>authuserdb</code> and <code>authpam</code> -
  387. they are specified as the modules which will be used to authenticate the
  388. userid and password. <code>/usr/local/bin/dostuff -x</code> is specified as
  389. the command to execute upon successful userid/password validation.</p>
  390. <h2>AUTHENTICATION LIBRARY</h2>
  391. <p>This and the following sections provide documentation that's of interest
  392. only if you want to write your own authentication modules. The low-level
  393. authentication protocol is defined later. The <code>libauth.a</code> and
  394. <code>libauthmod.a</code> libraries contain functions that handle all the low
  395. level details, and provide convenient high level authentication services that
  396. you can use to write your own authentication modules in C or C++.</p>
  397. <p>Under normal conditions, the login process reads its command line
  398. arguments, and processes any options it knows about. Afterwards, the remaining
  399. command line arguments specify the next process to run.</p>
  400. <p>The typical logic used by the login process is as follows:<br>
  401. <br>
  402. </p>
  403. <pre>int main(int argc, char **argv)
  404. {
  405.    if (authmoduser(argc, argv, TIMEOUT, ERR_TIMEOUT))
  406.    {
  407.       /* Print initial greeting */
  408.    }
  409.    else
  410.    {
  411.       /* Error: invalid userid/password */
  412.    }
  413.    /* read userid and password */
  414.    authmod(argc-1, argv+1, SERVICE, AUTHTYPE, AUTHDATA);
  415. }</pre>
  416. <p>This example does not use any options for the login process itself. If the
  417. login process parses any options, they must be removed from the argc/argv
  418. arguments to the call to the <code>authmod</code> function. For example, if
  419. the authentication user process received two options, subtract two from argc,
  420. and add two to argv to skip over them.</p>
  421. <p>The TIMEOUT argument specifies the authentication timeout, in seconds. The
  422. <code>authmoduser</code> function calls alarm to set up an alarm signal to be
  423. delivered after the specified period of time (which will terminate this
  424. process by default).</p>
  425. <p>The <code>authmoduser</code> function copies the command line arguments
  426. into environment variables. This allows the login process to be invoked with
  427. the same exact command line arguments in the event that the subsequent account
  428. password is rejected, in order to start the process again.</p>
  429. <p><code>authmoduser</code> checks if the environment variables are not
  430. already set, meaning that this is the first time the login process is
  431. executed. If so, it copies the command line arguments to environment
  432. variables, and returns non-zero.</p>
  433. <p>If the environment variables were already set, the function returns 0 in
  434. this case after sleeping for the amount of time specified by the
  435. <code>ERR_TIMEOUT</code> argument (in seconds). Note that the
  436. <code>TIMEOUT</code> time interval will generally be a cumulative value.
  437. <code>authmoduser</code> checks the system clock, and subsequent invocation of
  438. the login process will automatically cause <code>authmoduser</code> to
  439. subtract the time already used up during the initial invocation of the
  440. process.</p>
  441. <p>The return value from <code>authmoduser</code> can be used to determine
  442. whether a "password rejected" type of a message should be printed, or if a
  443. greeting message should be used instead.</p>
  444. <p>Afterwards, the userid and password are obtained, in some fashion, and the
  445. <code>authmod</code> function is called.  The first two arguments to
  446. <code>authmod</code> must be exactly as shown. If <code>authmoduser</code>
  447. received <code>argc</code> and <code>argv</code>, <code>authmod</code> must
  448. receive <code>argc-1</code> and <code>argv+1</code>. If authmoduser received
  449. any options, argc/argv must be advanced appropriately. The next argument
  450. specifies the first authentication module to execute, which is precisely what
  451. the <code>authmod</code> function does.</p>
  452. <p><code>SERVICE</code> is a character string that specifies an
  453. "authentication service". This is not used by all authentication modules. The
  454. <code>authpam</code> module passes this directly to the PAM library, and the
  455. PAM library uses this value to look up a list of PAM modules to run.</p>
  456. <p><code>AUTHTYPE</code> and <code>AUTHDATA</code> are also both character
  457. strings. <code>AUTHTYPE</code> specifies the authentication type or format.
  458. The contents of <code>AUTHDATA</code> depend on <code>AUTHTYPE</code>.</p>
  459. <p>Currently, two <code>AUTHTYPE</code>s are defined: "login", which specifies
  460. the traditional userid/password authentication mechanism; and "cram-md5", that
  461. specifies the challenge/response authentication mechanism defined by <a
  462. href="ftp://ftp.isi.edu/in-notes/rfc2095.txt">RFC 2095</a>.</p>
  463. <p>When <code>AUTHTYPE</code> is set to "login", <code>AUTHDATA</code> must be
  464. set to the userid, followed by a newline character, and the password, also
  465. followed by the newline character.</p>
  466. <p>When AUTHTYPE is set to "cram-md5", AUTHDATA must be set to the
  467. base64-encoded challenge string followed by a newline character, then the
  468. base64-encoded response string, also followed by a newline character.</p>
  469. <p>Before running the first authentication module, <code>authmod</code> sets
  470. up a pipe on file descriptor 3 to the first authentication module, and writes
  471. the following to the pipe:
  472. <code>service&lt;NL>AUTHTYPE&lt;NL>AUTHDATA</code></p>
  473. <p>&lt;NL> represents the newline character.  The pipe is immediately closed
  474. after writing this information. The authlib library does not use file
  475. descriptors 0, 1, and 2. They are preserved throughout the process.</p>
  476. <p>The logic in an authentication module is usually like this:</p>
  477. <pre>int main(int argc, char **argv)
  478. {
  479. const char *service, *authtype;
  480. char *authdata;
  481.    authmod_init(argc, argv, &amp;service, &amp;authtype, &amp;authdata);
  482.    /* Attempt to accept this authentication request */
  483.    if success
  484.    {
  485.        authmod_success(argc, argv);
  486.    }
  487.    if failed
  488.    {
  489.        authmod_fail(argc, argv)
  490.    }
  491.    if permanently failed
  492.    {
  493.        authmod_fail_completely();
  494.    }
  495. }</pre>
  496. <p>The authentication module calls authmod_init as the first order of
  497. business. <code>authmod_init </code>receives the <code>argc</code> and
  498. <code>argv</code> arguments as main received them. <code>authmod_init</code>
  499. retrieves the service, authentication type, and data, and returns them.</p>
  500. <p>NOTE: There's a theoretical upper limit on the maximum number of characters
  501. read from the pipe on file descriptor 3. It is high enough that most people
  502. shouldn't worry about it (the total number of characters allowed cannot be
  503. more than 8189 characters on a typical Linux system).</p>
  504. <p>The authentication module then proceeds to authenticate this request in
  505. some arbitrary fashion. The end result must be a call to one of three
  506. functions: <code>authmod_success</code>, <code>authmod_fail</code>, or
  507. <code>authmod_fail_completely</code>.</p>
  508. <p><code>authmod_success</code> and <code>authmod_fail</code> must receive the
  509. <code>argc</code> and <code>argv</code> arguments that were received by main.
  510. They remove argv[0] from the array, and use the remaining arguments to specify
  511. the next process to execute.</p>
  512. <p>All three functions do not return, as they functions execute either the
  513. next process specified by command line arguments, or the login process
  514. again.</p>
  515. <p>Before calling <code>authmod_success</code>, an authentication module must
  516. reset its user and group id to the ones appropriate for the authenticated
  517. account, change to the account's home directory, and perform any additional
  518. initialization logic deemed necessary.</p>
  519. <p>If <code>authmod_success</code> is called, and the next process is another
  520. authentication module, the next module's <code>authmod_init</code> function
  521. will automatically call <code>authmod_success</code> itself, without returning
  522. to the main function.</p>
  523. <p><code>authmod_fail</code> should be called if the password has not been
  524. authenticated. If the next process is another authentication module, it will
  525. receive the service string, and authtype and authtype strings, via a pipe on
  526. file descriptor 3, and the next authentication module will get a crack at
  527. validating the password.</p>
  528. <p><code>authmod_fail_completely</code> should be called if the authentication
  529. module rejects the password, and the authentication module does not want to
  530. give any other authentication modules a chance to validate the userid and
  531. password. This is typically done if the authentication module believes that
  532. its the only authentication module that should be used to validate this
  533. authentication request, and that no other authentication modules should be
  534. able to do so. <code>authmod_fail_completely</code> reads the original
  535. arguments to the login process, then runs it.</p>
  536. <p>Eventually, the authenticated client process will be executed. That's the
  537. last process specified on the original command line to the login process.</p>
  538. <p>The only thing that the authentication client process needs to do is to
  539. make a call to the <code>authmodclient()</code> function as the very first
  540. order of business in <code>main()</code>. <code>authmodclient</code> takes no
  541. arguments. It checks whether or not any modules successfully authenticated the
  542. userid and password by calling <code>authmod_success</code>. In any other
  543. event, <code>authmodclient()</code> automatically executes the login process
  544. (without returning to main) to begin the authentication process again.</p>
  545. <h2>FUNCTIONS IN libauth.a</h2>
  546. <p>In addition to the authentication functions in libmodauth.a library, the
  547. libauth.a contains the following functions which may be useful when writing a
  548. new authentication module:</p>
  549. <pre>void authchangegroup(gid_t);
  550. void authchangeuidgid(uid_t, gid_t);
  551. void authchangeusername(const char *, const gid_t *);</pre>
  552. <p>An authentication module should call these function prior to calling
  553. <code>authmod_success</code>. These functions set the process's user and group
  554. IDs. Some systems feature supplementary group IDs in addition to standard
  555. group IDs, and you may not want the authenticated client process to inherit
  556. any auxiliary group IDs from the superuser login process. The configuration
  557. script for the libauth.a tries to detect if this is the case, and these
  558. functions will include code to remove all auxiliary group IDs.</p>
  559. <p><code>authchangegroup</code> changes the process's group ID to the one
  560. specified by its argument. <code>authchangeuidgid</code> changes both the
  561. group and the user ID. <code>authchangeusername</code> looks up the userid and
  562. the groupid in <code>/etc/passwd</code>. If the second argument to
  563. <code>authchangeusername</code> is not NULL, it points to a group ID which
  564. will override the group ID specified in the system's password database for
  565. this user. If it is NULL, the group ID and any auxiliary group IDs are
  566. retrieved from the system's password database (the auxiliary group IDs are
  567. reset in all other cases).</p>
  568. <h2>LOW LEVEL AUTHENTICATION PROTOCOL</h2>
  569. <p>The actual authentication protocol uses environment variables and pipes to
  570. communicate authentication information between modules. All of this
  571. functionality is implemented by high level functions in the
  572. <code>libauthmod.a</code> library. This documentation is provided in the event
  573. it is desired to put together a compatible authentication module without using
  574. the code from <code>libauthmod.a</code>.</p>
  575. <p>The login process performs the following procedure prior to running the
  576. first authentication module:</p>
  577. <p>1) The <code>AUTHENTICATED</code> environment variable is cleared (set to
  578. an empty string). <code>argv[0]</code> is checked to make sure it contains a
  579. full pathname, and its contents are used to set the <code>AUTHUSER</code>
  580. environment variable. If <code>AUTHUSER</code> is already set,
  581. <code>argv[0]</code> is ignored. If <code>argv[0]</code> does not contain a
  582. full pathname, <code>AUTHUSER</code> must already be set prior to running this
  583. process.</p>
  584. <p>2) <code>wait(2)</code> is repeatedly called to reap any zombie child
  585. processes that are a byproduct of this authentication protocol.
  586. <code>wait(2)</code> is called repeatedly until there are no more child
  587. processes left.</p>
  588. <p>3) The <code>AUTHARGC</code> environment variable is checked. If it is not
  589. defined it means that the process was invoked for the first time, by a system
  590. daemon process. If <code>AUTHARGC</code> is defined it means that this is not
  591. the first time this process was executed for this connection, and the previous
  592. authentication request failed.</p>
  593. <p>4) If necessary, <code>AUTHARGC</code> is set to contain the decimal value
  594. of argc, as received by main.</p>
  595. <p>5) The environment variables <code>ARGV0</code>, <code>ARGV1</code>, up to
  596. <code>ARGVn</code>, are initialized to the contents of the argv array, as
  597. received by main. <code>ARGV0</code> is set to the contents of
  598. <code>argv[0]</code>, <code>ARGV1</code> is set to the contents of
  599. <code>ARGV[2]</code>, and so on.</p>
  600. <p>6) If the login process wants to have an expiration time for the login
  601. attempt, then it should set the AUTHEXPIRE environment variable the first time
  602. the login process is called. <code>AUTHEXPIRE</code> should be set to the
  603. calculated expiration time, based on the system clock.  Subsequent invocations
  604. (after failed authentication attempts) compare the system clock against the
  605. contents of <code>AUTHEXPIRE</code> to check if the login has expired. If not,
  606. it's possible to calculate how much time is left, and set the alarm clock to
  607. kill the process. The alarm clock is cleared if the next authentication
  608. attempt is entered before the alarm clock goes off.</p>
  609. <p>7) The login process then tries read a potential userid and password, in
  610. some sort of fashion, taking into account.</p>
  611. <p>8) After obtaining the userid and password, the authentication user process
  612. kills the expiration timer (if it was set), and creates a pipe. It forks, and
  613. the parent process connects the output of the pipe to file descriptor 3, then
  614. executes the next process specified by the command line arguments. The child
  615. process writes the following text to the pipe:</p>
  616. <p><code><b>service</b>&lt;NL><b>authtype</b>&lt;NL><b>authdata</b></code></p>
  617. <p><i>service</i>, <i>authtype</i>, and <i>authdata</i>, comprise the
  618. authentication request, as defined previously. They are separated by a newline
  619. character, <code>&lt;NL></code>. A pipe is used to send the authentication
  620. request to the authentication module instead of command line arguments or
  621. environment variables. That's because you do not want the password readable by
  622. anyone who happens to run <code>ps(1)</code> at the same time. After writing
  623. the authentication request to the pipe, the child process quickly
  624. terminates.</p>
  625. <p>An authentication module performs the following steps:</p>
  626. <p>1) Checks the <code>AUTHENTICATED</code> environment variable. If it is not
  627. empty, it means that some previous authentication module successfully
  628. authenticated the userid and the password, so the authentication module
  629. immediately executes the next process specified by the command line.
  630. Otherwise, the module reads the userid, password, and service from file
  631. descriptor 3 which is immediately closed afterwards.</p>
  632. <p>2) The authentication module calls <code>wait(2)</code> repeatedly to reap
  633. any zombie child processes.</p>
  634. <p>3) Following that, the authentication module attempt to authenticate this
  635. request. There are three possible outcomes.</p>
  636. <p>4) If the request is successfully authenticated, the module sets the
  637. process's userid, groupid, then changes to the account's home directory. The
  638. following environment variables are set: <code>AUTHENTICATED</code> is set to
  639. the userid; <code>AUTHFULLNAME</code> is set to the user's "full name";
  640. <code>AUTHADDR</code> is set to the user's return address. After these
  641. environment variables are set, the next process specified on the command line
  642. is executed.</p>
  643. <p>5) If the authentication request is rejected, the module process creates a
  644. pipe, forks, the parent process connects the output side of the pipe to file
  645. descriptor 3, then executes the next process specified by command line
  646. arguments line arguments. The child process writes the authentication request
  647. to the pipe, then immediately terminates. This allows the next authentication
  648. module, if present, to have the opportunity to authenticate this request.</p>
  649. <p>6) In order to permanently reject the authentication request, without
  650. invoking any additional authentication modules, the authentication module must
  651. execute the process specified by the <code>AUTHUSER</code> environment
  652. variable. The command line arguments for the process must be taken from the
  653. <code>AUTHARGVn</code> series environment variables, the number of which is
  654. given by the <code>ARGC</code> environment variable.</p>
  655. <p>An authenticated client process of this authentication library must take
  656. the following steps as the first order of business when it starts:</p>
  657. <p>1) Repeatedly call <code>wait(2)</code> to reap any zombie child
  658. processes.</p>
  659. <p>2) Verify that the <code>AUTHENTICATED</code> environment variable is not
  660. empty. If not, it means that none of the authentication modules successfully
  661. authenticated this request, so the process specified by <code>AUTHUSER</code>
  662. must be immediately invoked, with command line arguments set by the contents
  663. of <code>AUTHARGVn</code> series of environment variables.</p>
  664. <p>3) Otherwise, the client process is considered to be authenticated, and
  665. ready for business.</p>
  666. <h2>BUGS</h2>
  667. <p>File descriptor 3 is used in order to avoid messing with <i>program</i>'s
  668. stdin, stdout, and stderr.</p>
  669. <h2>SEE ALSO</h2>
  670. <p><a href="courier.html">courier(8),</a> <a
  671. href="userdb.html">userdb(8)</a></p>
  672. <p></p>
  673. </body>
  674. </html>