Linux-PAM_ADG.xml 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. <?xml version='1.0' encoding='UTF-8'?>
  2. <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
  4. <book id="adg">
  5. <bookinfo>
  6. <title>The Linux-PAM Application Developers' Guide</title>
  7. <authorgroup>
  8. <author>
  9. <firstname>Andrew G.</firstname>
  10. <surname>Morgan</surname>
  11. <email>morgan@kernel.org</email>
  12. </author>
  13. <author>
  14. <firstname>Thorsten</firstname>
  15. <surname>Kukuk</surname>
  16. <email>kukuk@thkukuk.de</email>
  17. </author>
  18. </authorgroup>
  19. <releaseinfo>Version 1.1.2, 31. August 2010</releaseinfo>
  20. <abstract>
  21. <para>
  22. This manual documents what an application developer needs to know
  23. about the <emphasis remap='B'>Linux-PAM</emphasis> library. It
  24. describes how an application might use the
  25. <emphasis remap='B'>Linux-PAM</emphasis> library to authenticate
  26. users. In addition it contains a description of the functions
  27. to be found in <filename>libpam_misc</filename> library, that can
  28. be used in general applications. Finally, it contains some comments
  29. on PAM related security issues for the application developer.
  30. </para>
  31. </abstract>
  32. </bookinfo>
  33. <chapter id="adg-introduction">
  34. <title>Introduction</title>
  35. <section id="adg-introduction-description">
  36. <title>Description</title>
  37. <para>
  38. <emphasis remap='B'>Linux-PAM</emphasis>
  39. (Pluggable Authentication Modules for Linux) is a library that enables
  40. the local system administrator to choose how individual applications
  41. authenticate users. For an overview of the
  42. <emphasis remap='B'>Linux-PAM</emphasis> library see the
  43. <emphasis>Linux-PAM System Administrators' Guide</emphasis>.
  44. </para>
  45. <para>
  46. It is the purpose of the <emphasis remap='B'>Linux-PAM</emphasis>
  47. project to liberate the development of privilege granting software
  48. from the development of secure and appropriate authentication schemes.
  49. This is accomplished by providing a documented library of functions
  50. that an application may use for all forms of user authentication
  51. management. This library dynamically loads locally configured
  52. authentication modules that actually perform the authentication tasks.
  53. </para>
  54. <para>
  55. From the perspective of an application developer the information
  56. contained in the local configuration of the PAM library should not be
  57. important. Indeed it is intended that an application treat the
  58. functions documented here as a 'black box' that will deal with all
  59. aspects of user authentication. 'All aspects' includes user
  60. verification, account management, session initialization/termination
  61. and also the resetting of passwords
  62. (<emphasis>authentication tokens</emphasis>).
  63. </para>
  64. </section>
  65. <section id="adg-introduction-synopsis">
  66. <title>Synopsis</title>
  67. <para>
  68. For general applications that wish to use the services provided by
  69. <emphasis remap='B'>Linux-PAM</emphasis> the following is a summary
  70. of the relevant linking information:
  71. <programlisting>
  72. #include &lt;security/pam_appl.h&gt;
  73. cc -o application .... -lpam
  74. </programlisting>
  75. </para>
  76. <para>
  77. In addition to <command>libpam</command>, there is a library of
  78. miscellaneous functions that make the job of writing
  79. <emphasis>PAM-aware</emphasis> applications easier (this library is not
  80. covered in the DCE-RFC for PAM and is specific to the Linux-PAM
  81. distribution):
  82. <programlisting>
  83. #include &lt;security/pam_appl.h&gt;
  84. #include &lt;security/pam_misc.h&gt;
  85. cc -o application .... -lpam -lpam_misc
  86. </programlisting>
  87. </para>
  88. </section>
  89. </chapter>
  90. <chapter id="adg-overview">
  91. <title>Overview</title>
  92. <para>
  93. Most service-giving applications are restricted. In other words,
  94. their service is not available to all and every prospective client.
  95. Instead, the applying client must jump through a number of hoops to
  96. convince the serving application that they are authorized to obtain
  97. service.
  98. </para>
  99. <para>
  100. The process of <emphasis>authenticating</emphasis> a client is what
  101. PAM is designed to manage. In addition to authentication, PAM provides
  102. account management, credential management, session management and
  103. authentication-token (password changing) management services. It is
  104. important to realize when writing a PAM based application that these
  105. services are provided in a manner that is
  106. <emphasis remap='B'>transparent</emphasis> to the application. That is
  107. to say, when the application is written, no assumptions can be made
  108. about <emphasis>how</emphasis> the client will be authenticated.
  109. </para>
  110. <para>
  111. The process of authentication is performed by the PAM library via a
  112. call to <function>pam_authenticate()</function>. The return value
  113. of this function will indicate whether a named client (the
  114. <emphasis>user</emphasis>) has been authenticated. If the PAM library
  115. needs to prompt the user for any information, such as their
  116. <emphasis>name</emphasis> or a <emphasis>password</emphasis>
  117. then it will do so. If the PAM library is configured to authenticate
  118. the user using some silent protocol, it will do this too. (This
  119. latter case might be via some hardware interface for example.)
  120. </para>
  121. <para>
  122. It is important to note that the application must leave all decisions
  123. about when to prompt the user at the discretion of the PAM library.
  124. </para>
  125. <para>
  126. The PAM library, however, must work equally well for different styles
  127. of application. Some applications, like the familiar
  128. <command>login</command> and <command>passwd</command> are terminal
  129. based applications, exchanges of information with the client in
  130. these cases is as plain text messages. Graphically based applications,
  131. however, have a more sophisticated interface. They generally interact
  132. with the user via specially constructed dialogue boxes. Additionally,
  133. network based services require that text messages exchanged with the
  134. client are specially formatted for automated processing: one such
  135. example is <command>ftpd</command> which prefixes each exchanged
  136. message with a numeric identifier.
  137. </para>
  138. <para>
  139. The presentation of simple requests to a client is thus something very
  140. dependent on the protocol that the serving application will use. In
  141. spite of the fact that PAM demands that it drives the whole
  142. authentication process, it is not possible to leave such protocol
  143. subtleties up to the PAM library. To overcome this potential problem,
  144. the application provides the PAM library with a
  145. <emphasis>conversation</emphasis> function. This function is called
  146. from <emphasis>within</emphasis> the PAM library and enables the PAM
  147. to directly interact with the client. The sorts of things that this
  148. conversation function must be able to do are prompt the user with
  149. text and/or obtain textual input from the user for processing by the
  150. PAM library. The details of this function are provided in a later
  151. section.
  152. </para>
  153. <para>
  154. For example, the conversation function may be called by the PAM
  155. library with a request to prompt the user for a password. Its job is
  156. to reformat the prompt request into a form that the client will
  157. understand. In the case of <command>ftpd</command>, this might involve
  158. prefixing the string with the number <command>331</command> and sending
  159. the request over the network to a connected client. The conversation
  160. function will then obtain any reply and, after extracting the typed
  161. password, will return this string of text to the PAM library. Similar
  162. concerns need to be addressed in the case of an X-based graphical
  163. server.
  164. </para>
  165. <para>
  166. There are a number of issues that need to be addressed when one is
  167. porting an existing application to become PAM compliant. A section
  168. below has been devoted to this: Porting legacy applications.
  169. </para>
  170. <para>
  171. Besides authentication, PAM provides other forms of management.
  172. Session management is provided with calls to
  173. <function>pam_open_session()</function> and
  174. <function>pam_close_session()</function>. What these functions
  175. actually do is up to the local administrator. But typically, they
  176. could be used to log entry and exit from the system or for mounting
  177. and unmounting the user's home directory. If an application provides
  178. continuous service for a period of time, it should probably call
  179. these functions, first open after the user is authenticated and then
  180. close when the service is terminated.
  181. </para>
  182. <para>
  183. Account management is another area that an application developer
  184. should include with a call to <function>pam_acct_mgmt()</function>.
  185. This call will perform checks on the good health of the user's account
  186. (has it expired etc.). One of the things this function may check is
  187. whether the user's authentication token has expired - in such a case the
  188. application may choose to attempt to update it with a call to
  189. <function>pam_chauthtok()</function>, although some applications
  190. are not suited to this task (<command>ftp</command> for example)
  191. and in this case the application should deny access to the user.
  192. </para>
  193. <para>
  194. PAM is also capable of setting and deleting the user's credentials with
  195. the call <function>pam_setcred()</function>. This function should
  196. always be called after the user is authenticated and before service
  197. is offered to the user. By convention, this should be the last call
  198. to the PAM library before the PAM session is opened. What exactly a
  199. credential is, is not well defined. However, some examples are given
  200. in the glossary below.
  201. </para>
  202. </chapter>
  203. <chapter id="adg-interface">
  204. <title>
  205. The public interface to <emphasis remap='B'>Linux-PAM</emphasis>
  206. </title>
  207. <para>
  208. Firstly, the relevant include file for the
  209. <emphasis remap='B'>Linux-PAM</emphasis> library is
  210. <function>&lt;security/pam_appl.h&gt;</function>.
  211. It contains the definitions for a number of functions. After
  212. listing these functions, we collect some guiding remarks for
  213. programmers.
  214. </para>
  215. <section id="adg-interface-by-app-expected">
  216. <title>What can be expected by the application</title>
  217. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  218. href="pam_start.xml"/>
  219. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  220. href="pam_end.xml"/>
  221. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  222. href="pam_set_item.xml"/>
  223. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  224. href="pam_get_item.xml"/>
  225. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  226. href="pam_strerror.xml"/>
  227. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  228. href="pam_fail_delay.xml"/>
  229. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  230. href="pam_authenticate.xml"/>
  231. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  232. href="pam_setcred.xml"/>
  233. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  234. href="pam_acct_mgmt.xml"/>
  235. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  236. href="pam_chauthtok.xml"/>
  237. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  238. href="pam_open_session.xml"/>
  239. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  240. href="pam_close_session.xml"/>
  241. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  242. href="pam_putenv.xml"/>
  243. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  244. href="pam_getenv.xml"/>
  245. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  246. href="pam_getenvlist.xml"/>
  247. </section>
  248. <section id="adg-interface-of-app-expected">
  249. <title>What is expected of an application</title>
  250. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  251. href="pam_conv.xml"/>
  252. </section>
  253. <section id="adg-interface-programming-notes">
  254. <title>Programming notes</title>
  255. <para>
  256. Note, all of the authentication service function calls accept the
  257. token <emphasis remap='B'>PAM_SILENT</emphasis>, which instructs
  258. the modules to not send messages to the application. This token
  259. can be logically OR'd with any one of the permitted tokens specific
  260. to the individual function calls.
  261. <emphasis remap='B'>PAM_SILENT</emphasis> does not override the
  262. prompting of the user for passwords etc., it only stops informative
  263. messages from being generated.
  264. </para>
  265. </section>
  266. </chapter>
  267. <chapter id="adg-security">
  268. <title>
  269. Security issues of <emphasis remap='B'>Linux-PAM</emphasis>
  270. </title>
  271. <para>
  272. PAM, from the perspective of an application, is a convenient API for
  273. authenticating users. PAM modules generally have no increased
  274. privilege over that possessed by the application that is making use of
  275. it. For this reason, the application must take ultimate responsibility
  276. for protecting the environment in which PAM operates.
  277. </para>
  278. <para>
  279. A poorly (or maliciously) written application can defeat any
  280. <emphasis remap='B'>Linux-PAM</emphasis> module's authentication
  281. mechanisms by simply ignoring it's return values. It is the
  282. applications task and responsibility to grant privileges and access
  283. to services. The <emphasis remap='B'>Linux-PAM</emphasis> library
  284. simply assumes the responsibility of <emphasis>authenticating</emphasis>
  285. the user; ascertaining that the user <emphasis>is</emphasis> who they
  286. say they are. Care should be taken to anticipate all of the documented
  287. behavior of the <emphasis remap='B'>Linux-PAM</emphasis> library
  288. functions. A failure to do this will most certainly lead to a future
  289. security breach.
  290. </para>
  291. <section id="adg-security-library-calls">
  292. <title>Care about standard library calls</title>
  293. <para>
  294. In general, writers of authorization-granting applications should
  295. assume that each module is likely to call any or
  296. <emphasis>all</emphasis> 'libc' functions. For 'libc' functions
  297. that return pointers to static/dynamically allocated structures
  298. (ie. the library allocates the memory and the user is not expected
  299. to '<function>free()</function>' it) any module call to this
  300. function is likely to corrupt a pointer previously
  301. obtained by the application. The application programmer should
  302. either re-call such a 'libc' function after a call to the
  303. <emphasis remap='B'>Linux-PAM</emphasis> library, or copy the
  304. structure contents to some safe area of memory before passing
  305. control to the <emphasis remap='B'>Linux-PAM</emphasis> library.
  306. </para>
  307. <para>
  308. Two important function classes that fall into this category are
  309. <citerefentry>
  310. <refentrytitle>getpwnam</refentrytitle><manvolnum>3</manvolnum>
  311. </citerefentry> and <citerefentry>
  312. <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
  313. </citerefentry>.
  314. </para>
  315. </section>
  316. <section id="adg-security-service-name">
  317. <title>Choice of a service name</title>
  318. <para>
  319. When picking the <emphasis>service-name</emphasis> that
  320. corresponds to the first entry in the
  321. <emphasis remap='B'>Linux-PAM</emphasis> configuration file,
  322. the application programmer should <emphasis>avoid</emphasis>
  323. the temptation of choosing something related to
  324. <varname>argv[0]</varname>. It is a trivial matter for any user
  325. to invoke any application on a system under a different name and
  326. this should not be permitted to cause a security breach.
  327. </para>
  328. <para>
  329. In general, this is always the right advice if the program is
  330. setuid, or otherwise more privileged than the user that invokes
  331. it. In some cases, avoiding this advice is convenient, but as an
  332. author of such an application, you should consider well the ways
  333. in which your program will be installed and used. (Its often the
  334. case that programs are not intended to be setuid, but end up
  335. being installed that way for convenience. If your program falls
  336. into this category, don't fall into the trap of making this mistake.)
  337. </para>
  338. <para>
  339. To invoke some <emphasis>target</emphasis> application by
  340. another name, the user may symbolically link the target application
  341. with the desired name. To be precise all the user need do is,
  342. <command>ln -s /target/application ./preferred_name</command>
  343. and then run <command>./preferred_name</command>.
  344. </para>
  345. <para>
  346. By studying the <emphasis remap='B'>Linux-PAM</emphasis>
  347. configuration file(s), an attacker can choose the
  348. <command>preferred_name</command> to be that of a service enjoying
  349. minimal protection; for example a game which uses
  350. <emphasis remap='B'>Linux-PAM</emphasis> to restrict access to
  351. certain hours of the day. If the service-name were to be linked
  352. to the filename under which the service was invoked, it
  353. is clear that the user is effectively in the position of
  354. dictating which authentication scheme the service uses. Needless
  355. to say, this is not a secure situation.
  356. </para>
  357. <para>
  358. The conclusion is that the application developer should carefully
  359. define the service-name of an application. The safest thing is to
  360. make it a single hard-wired name.
  361. </para>
  362. </section>
  363. <section id="adg-security-conv-function">
  364. <title>The conversation function</title>
  365. <para>
  366. Care should be taken to ensure that the <function>conv()</function>
  367. function is robust. Such a function is provided in the library
  368. <command>libpam_misc</command> (see
  369. <link linkend="adg-libpam-functions">below</link>).
  370. </para>
  371. </section>
  372. <section id="adg-security-user-identity">
  373. <title>The identity of the user</title>
  374. <para>
  375. The <emphasis remap='B'>Linux-PAM</emphasis> modules will need
  376. to determine the identity of the user who requests a service,
  377. and the identity of the user who grants the service. These two
  378. users will seldom be the same. Indeed there is generally a third
  379. user identity to be considered, the new (assumed) identity of
  380. the user once the service is granted.
  381. </para>
  382. <para>
  383. The need for keeping tabs on these identities is clearly an
  384. issue of security. One convention that is actively used by
  385. some modules is that the identity of the user requesting a
  386. service should be the current <emphasis>UID</emphasis>
  387. (user ID) of the running process; the identity of the
  388. privilege granting user is the <emphasis>EUID</emphasis>
  389. (effective user ID) of the running process; the identity of
  390. the user, under whose name the service will be executed, is
  391. given by the contents of the <emphasis>PAM_USER</emphasis>
  392. <citerefentry>
  393. <refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum>
  394. </citerefentry>. Note, modules can change the values of
  395. <emphasis>PAM_USER</emphasis> and <emphasis>PAM_RUSER</emphasis>
  396. during any of the <function>pam_*()</function> library calls.
  397. For this reason, the application should take care to use the
  398. <function>pam_get_item()</function> every time it wishes to
  399. establish who the authenticated user is (or will currently be).
  400. </para>
  401. <para>
  402. For network-serving databases and other applications that provide
  403. their own security model (independent of the OS kernel) the above
  404. scheme is insufficient to identify the requesting user.
  405. </para>
  406. <para>
  407. A more portable solution to storing the identity of the requesting
  408. user is to use the <emphasis>PAM_RUSER</emphasis> <citerefentry>
  409. <refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum>
  410. </citerefentry>. The application should supply this value before
  411. attempting to authenticate the user with
  412. <function>pam_authenticate()</function>. How well this name can be
  413. trusted will ultimately be at the discretion of the local
  414. administrator (who configures PAM for your application) and a
  415. selected module may attempt to override the value where it can
  416. obtain more reliable data. If an application is unable to determine
  417. the identity of the requesting entity/user, it should not call
  418. <citerefentry>
  419. <refentrytitle>pam_set_item</refentrytitle><manvolnum>3</manvolnum>
  420. </citerefentry> to set <emphasis>PAM_RUSER</emphasis>.
  421. </para>
  422. <para>
  423. In addition to the <emphasis>PAM_RUSER</emphasis> item, the
  424. application should supply the <emphasis>PAM_RHOST</emphasis>
  425. (<emphasis>requesting host</emphasis>) item. As a general rule,
  426. the following convention for its value can be assumed:
  427. NULL = unknown; localhost = invoked directly from the local system;
  428. <emphasis>other.place.xyz</emphasis> = some component of the
  429. user's connection originates from this remote/requesting host. At
  430. present, PAM has no established convention for indicating whether
  431. the application supports a trusted path to communication from
  432. this host.
  433. </para>
  434. </section>
  435. <section id="adg-security-resources">
  436. <title>Sufficient resources</title>
  437. <para>
  438. Care should be taken to ensure that the proper execution of an
  439. application is not compromised by a lack of system resources. If an
  440. application is unable to open sufficient files to perform its service,
  441. it should fail gracefully, or request additional resources.
  442. Specifically, the quantities manipulated by the <citerefentry>
  443. <refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum>
  444. </citerefentry> family of commands should be taken into consideration.
  445. </para>
  446. <para>
  447. This is also true of conversation prompts. The application should not
  448. accept prompts of arbitrary length with out checking for resource
  449. allocation failure and dealing with such extreme conditions gracefully
  450. and in a manner that preserves the PAM API. Such tolerance may be
  451. especially important when attempting to track a malicious adversary.
  452. </para>
  453. </section>
  454. </chapter>
  455. <chapter id='adg-libpam_misc'>
  456. <title>A library of miscellaneous helper functions</title>
  457. <para>
  458. To aid the work of the application developer a library of
  459. miscellaneous functions is provided. It is called
  460. <command>libpam_misc</command>, and contains a text based
  461. conversation function, and routines for enhancing the standard
  462. PAM-environment variable support.
  463. </para>
  464. <para>
  465. The functions, structures and macros, made available by this
  466. library can be defined by including
  467. <function>&lt;security/pam_misc.h&gt;</function>. It should be
  468. noted that this library is specific to
  469. <emphasis remap='B'>Linux-PAM</emphasis> and is not referred to in
  470. the defining DCE-RFC (see <link linkend="adg-see-also">See also</link>)
  471. below.
  472. </para>
  473. <section id='adg-libpam-functions'>
  474. <title>Functions supplied</title>
  475. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  476. href="pam_misc_conv.xml"/>
  477. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  478. href="pam_misc_paste_env.xml"/>
  479. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  480. href="pam_misc_drop_env.xml"/>
  481. <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
  482. href="pam_misc_setenv.xml"/>
  483. </section>
  484. </chapter>
  485. <chapter id='adg-porting'>
  486. <title>Porting legacy applications</title>
  487. <para>
  488. The point of PAM is that the application is not supposed to
  489. have any idea how the attached authentication modules will choose
  490. to authenticate the user. So all they can do is provide a conversation
  491. function that will talk directly to the user(client) on the modules'
  492. behalf.
  493. </para>
  494. <para>
  495. Consider the case that you plug a retinal scanner into the login
  496. program. In this situation the user would be prompted: "please look
  497. into the scanner". No username or password would be needed - all this
  498. information could be deduced from the scan and a database lookup. The
  499. point is that the retinal scanner is an ideal task for a "module".
  500. </para>
  501. <para>
  502. While it is true that a pop-daemon program is designed with the POP
  503. protocol in mind and no-one ever considered attaching a retinal
  504. scanner to it, it is also the case that the "clean" PAM'ification of
  505. such a daemon would allow for the possibility of a scanner module
  506. being be attached to it. The point being that the "standard"
  507. pop-authentication protocol(s) [which will be needed to satisfy
  508. inflexible/legacy clients] would be supported by inserting an
  509. appropriate pam_qpopper module(s). However, having rewritten
  510. <command>popd</command> once in this way any new protocols can be
  511. implemented in-situ.
  512. </para>
  513. <para>
  514. One simple test of a ported application would be to insert the
  515. <command>pam_permit</command> module and see if the application
  516. demands you type a password... In such a case, <command>xlock</command>
  517. would fail to lock the terminal - or would at best be a screen-saver,
  518. ftp would give password free access to all etc.. Neither of
  519. these is a very secure thing to do, but they do illustrate how
  520. much flexibility PAM puts in the hands of the local admin.
  521. </para>
  522. <para>
  523. The key issue, in doing things correctly, is identifying what is part
  524. of the authentication procedure (how many passwords etc..) the
  525. exchange protocol (prefixes to prompts etc., numbers like 331 in the
  526. case of ftpd) and what is part of the service that the application
  527. delivers. PAM really needs to have total control in the
  528. authentication "procedure", the conversation function should only
  529. deal with reformatting user prompts and extracting responses from raw
  530. input.
  531. </para>
  532. </chapter>
  533. <chapter id='adg-glossary'>
  534. <title>Glossary of PAM related terms</title>
  535. <para>
  536. The following are a list of terms used within this document.
  537. </para>
  538. <variablelist>
  539. <varlistentry>
  540. <term>Authentication token</term>
  541. <listitem>
  542. <para>
  543. Generally, this is a password. However, a user can authenticate
  544. him/herself in a variety of ways. Updating the user's
  545. authentication token thus corresponds to
  546. <emphasis>refreshing</emphasis> the object they use to
  547. authenticate themself with the system. The word password is
  548. avoided to keep open the possibility that the authentication
  549. involves a retinal scan or other non-textual mode of
  550. challenge/response.
  551. </para>
  552. </listitem>
  553. </varlistentry>
  554. <varlistentry>
  555. <term>Credentials</term>
  556. <listitem>
  557. <para>
  558. Having successfully authenticated the user, PAM is able to
  559. establish certain characteristics/attributes of the user.
  560. These are termed <emphasis>credentials</emphasis>. Examples
  561. of which are group memberships to perform privileged tasks
  562. with, and <emphasis>tickets</emphasis> in the form of
  563. environment variables etc. . Some user-credentials, such as
  564. the user's UID and GID (plus default group memberships) are
  565. not deemed to be PAM-credentials. It is the responsibility
  566. of the application to grant these directly.
  567. </para>
  568. </listitem>
  569. </varlistentry>
  570. </variablelist>
  571. </chapter>
  572. <chapter id='adg-example'>
  573. <title>An example application</title>
  574. <para>
  575. To get a flavor of the way a <emphasis remap='B'>Linux-PAM</emphasis>
  576. application is written we include the following example. It prompts
  577. the user for their password and indicates whether their account
  578. is valid on the standard output, its return code also indicates
  579. the success (<returnvalue>0</returnvalue> for success;
  580. <returnvalue>1</returnvalue> for failure).
  581. </para>
  582. <programlisting><![CDATA[
  583. /*
  584. This program was contributed by Shane Watts
  585. [modifications by AGM and kukuk]
  586. You need to add the following (or equivalent) to the
  587. /etc/pam.d/check_user file:
  588. # check authorization
  589. auth required pam_unix.so
  590. account required pam_unix.so
  591. */
  592. #include <security/pam_appl.h>
  593. #include <security/pam_misc.h>
  594. #include <stdio.h>
  595. static struct pam_conv conv = {
  596. misc_conv,
  597. NULL
  598. };
  599. int main(int argc, char *argv[])
  600. {
  601. pam_handle_t *pamh=NULL;
  602. int retval;
  603. const char *user="nobody";
  604. if(argc == 2) {
  605. user = argv[1];
  606. }
  607. if(argc > 2) {
  608. fprintf(stderr, "Usage: check_user [username]\n");
  609. exit(1);
  610. }
  611. retval = pam_start("check_user", user, &conv, &pamh);
  612. if (retval == PAM_SUCCESS)
  613. retval = pam_authenticate(pamh, 0); /* is user really user? */
  614. if (retval == PAM_SUCCESS)
  615. retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
  616. /* This is where we have been authorized or not. */
  617. if (retval == PAM_SUCCESS) {
  618. fprintf(stdout, "Authenticated\n");
  619. } else {
  620. fprintf(stdout, "Not Authenticated\n");
  621. }
  622. if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
  623. pamh = NULL;
  624. fprintf(stderr, "check_user: failed to release authenticator\n");
  625. exit(1);
  626. }
  627. return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
  628. }
  629. ]]>
  630. </programlisting>
  631. </chapter>
  632. <chapter id='adg-files'>
  633. <title>Files</title>
  634. <variablelist>
  635. <varlistentry>
  636. <term><filename>/usr/include/security/pam_appl.h</filename></term>
  637. <listitem>
  638. <para>
  639. Header file with interfaces for
  640. <emphasis remap='B'>Linux-PAM</emphasis> applications.
  641. </para>
  642. </listitem>
  643. </varlistentry>
  644. <varlistentry>
  645. <term><filename>/usr/include/security/pam_misc.h</filename></term>
  646. <listitem>
  647. <para>
  648. Header file for useful library functions for making
  649. applications easier to write.
  650. </para>
  651. </listitem>
  652. </varlistentry>
  653. </variablelist>
  654. </chapter>
  655. <chapter id="adg-see-also">
  656. <title>See also</title>
  657. <itemizedlist>
  658. <listitem>
  659. <para>
  660. The Linux-PAM System Administrators' Guide.
  661. </para>
  662. </listitem>
  663. <listitem>
  664. <para>
  665. The Linux-PAM Module Writers' Guide.
  666. </para>
  667. </listitem>
  668. <listitem>
  669. <para>
  670. The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
  671. PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation
  672. Request For Comments 86.0, October 1995.
  673. </para>
  674. </listitem>
  675. </itemizedlist>
  676. </chapter>
  677. <chapter id='adg-author'>
  678. <title>Author/acknowledgments</title>
  679. <para>
  680. This document was written by Andrew G. Morgan (morgan@kernel.org)
  681. with many contributions from
  682. Chris Adams, Peter Allgeyer, Tim Baverstock, Tim Berger, Craig S. Bell,
  683. Derrick J. Brashear, Ben Buxton, Seth Chaiklin, Oliver Crow, Chris Dent,
  684. Marc Ewing, Cristian Gafton, Emmanuel Galanos, Brad M. Garcia,
  685. Eric Hester, Roger Hu, Eric Jacksch, Michael K. Johnson, David Kinchlea,
  686. Olaf Kirch, Marcin Korzonek, Thorsten Kukuk, Stephen Langasek,
  687. Nicolai Langfeldt, Elliot Lee, Luke Kenneth Casson Leighton,
  688. Al Longyear, Ingo Luetkebohle, Marek Michalkiewicz, Robert Milkowski,
  689. Aleph One, Martin Pool, Sean Reifschneider, Jan Rekorajski, Erik Troan,
  690. Theodore Ts'o, Jeff Uphoff, Myles Uyema, Savochkin Andrey Vladimirovich,
  691. Ronald Wahl, David Wood, John Wilmes, Joseph S. D. Yao
  692. and Alex O. Yuriev.
  693. </para>
  694. <para>
  695. Thanks are also due to Sun Microsystems, especially to Vipin Samar and
  696. Charlie Lai for their advice. At an early stage in the development of
  697. <emphasis remap='B'>Linux-PAM</emphasis>, Sun graciously made the
  698. documentation for their implementation of PAM available. This act
  699. greatly accelerated the development of
  700. <emphasis remap='B'>Linux-PAM</emphasis>.
  701. </para>
  702. </chapter>
  703. <chapter id='adg-copyright'>
  704. <title>Copyright information for this document</title>
  705. <programlisting>
  706. Copyright (c) 2006 Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;
  707. Copyright (c) 1996-2002 Andrew G. Morgan &lt;morgan@kernel.org&gt;
  708. </programlisting>
  709. <para>
  710. Redistribution and use in source and binary forms, with or without
  711. modification, are permitted provided that the following conditions are
  712. met:
  713. </para>
  714. <programlisting>
  715. 1. Redistributions of source code must retain the above copyright
  716. notice, and the entire permission notice in its entirety,
  717. including the disclaimer of warranties.
  718. 2. Redistributions in binary form must reproduce the above copyright
  719. notice, this list of conditions and the following disclaimer in the
  720. documentation and/or other materials provided with the distribution.
  721. 3. The name of the author may not be used to endorse or promote
  722. products derived from this software without specific prior
  723. written permission.
  724. </programlisting>
  725. <para>
  726. Alternatively, this product may be distributed under the terms of
  727. the GNU General Public License (GPL), in which case the provisions
  728. of the GNU GPL are required instead of the above restrictions.
  729. (This clause is necessary due to a potential bad interaction between
  730. the GNU GPL and the restrictions contained in a BSD-style copyright.)
  731. </para>
  732. <programlisting>
  733. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  734. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  735. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  736. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  737. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  738. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  739. OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  740. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  741. TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  742. USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  743. </programlisting>
  744. </chapter>
  745. </book>