  IF YOU ARE RUNNING LINUX AS A SERVER, WHERE SEVERAL DIFFERENT
  SERVICES ARE BEING PROVIDED (E.G., WWW WITH AREAS RESTRICTED BY
  PASSWORD CONTROL, PPP), THEN THERE CAN BE SOME REAL AND INTERESTING
  VALUE FOR PAM.  IN PARTICULAR, THROUGH THE USE OF MODULES, PAM CAN
  ENABLE A PROGRAM TO SEARCH THROUGH SEVERAL DIFFERENT PASSWORD
  DATABASES, EVEN IF THAT PROGRAM IS NOT EXPLICITLY CODED FOR
  THAT PARTICULAR DATABASE.  HERE ARE SOME EXAMPLES OF THE POSSIBILITIES
  THAT THIS ENABLES.

     O  APACHE HAS A MODULE THAT PROVIDES PAM SERVICES.  NOW
     AUTHENTICATION
        TO USE PARTICULAR DIRECTORIES CAN BE CONDUCTED BY PAM, WHICH
        MEANS THAT THE RANGE OF MODULES THAT ARE AVAILABLE TO PAM CAN
        BE USED, INCLUDING RADIUS, NIS, NCP (WHICH MEANS THAT NOVELL
        PASSWORD DATABASES CAN BE USED).

     O  PPPD HAS A PAMIFIED VERSION (AVAILABLE FROM REDHAT)  NOW IT IS
        POSSIBLE TO USE A SERIES OF DATABASES TO AUTHENTICATE PPP USERS.
        IN ADDITION TO THE NORMAL LINUX-BASED PASSWORD DATABASES (SUCH
        AS /ETC/PASSWD AND /ETC/SHADOW), YOU CAN USE PAM MODULES TO
        AUTHENTICATE AGAINST NOVELL PASSWORD DATABASES OR NT-BASED
        PASSWORD DATABASES.

     O  THE PRECEDING TWO EXAMPLES CAN BE COMBINED.  IMAGAINE THAT THE
        PERSONS IN YOUR OFFICE/DEPARTMENT ARE ALREADY REGISTERED WITH A
        USERNAME AND PASSWORD IN A NOVELL OR NT LAN.  IF YOU WANTED TO
        USE THIS DATABASE ON YOUR LINUX SERVER (FOR PPP ACCESS, FOR
        WEB ACCESS, OR EVEN FOR NORMAL SHELL ACCESS), YOU CAN USE PAM
        TO AUTHENTICATE AGAINST THIS EXISTING DATABASE, RATHER THAN
        MAINTAIN A SEPARATE DATABASE ON BOTH LINUX AND THE LAN SERVER.


  CAN I USE PAM FOR ANY PROGRAM THAT REQUIRES AUTHENTICATION?

  YES AND NO.   YES, IF YOU HAVE ACCESS TO THE SOURCE CODE, AND CAN
  ADD THE APPROPRIATE PAM FUNCTIONS.  NO, IF YOU DO NOT HAVE ACCESS
  TO THE SOURCE CODE, AND THE BINARY DOES NOT HAVE THE PAM FUNCTIONS
  INCLUDED.

  IN OTHER WORDS, IF A PROGRAM IS GOING TO USE PAM, THEN IT HAS TO
  HAVE PAM FUNCTIONS EXPLICITLY CODED INTO THE PROGRAM.  IF THEY
  ARE NOT, THEN IT IS NOT POSSIBLE TO USE PAM.

  HOW CAN I TELL WHETHER A PROGRAM HAS PAM CODED INTO IT OR NOT?

  A QUICK-AND-DIRTY (BUT NOT ALWAYS RELIABLE) METHOD IS TO LDD
  <PROGRAMNAME>
  IF LIBPAM AND LIBPAM_MISC ARE NOT AMONG THE LIBRARIES THAT THE PROGRAM
  USES, THEN IT IS NOT GOING TO WORK WITH PAM.  HOWEVER, IT IS POSSIBLE
  THAT THE LIBRARIES ARE INCLUDED, BUT THERE ARE STILL PROBLEMS, BECAUSE
  THE PAM CODING IN THE PROGRAM DOES NOT WORK AS IT SHOULD.  SO A
  MORE RELIABLE METHOD IS TO MAKE THE FOLLOW TESTS.

  IN THE /ETC/PAM.D DIRECTORY, ONE NEEDS TO MAKE A CONFIGURATION FILE
  FOR THE PROGRAM THAT ONE WANTS TO RUN.  THE EXACT NAME OF THE
  CONFIGURATION
  FILE IS HARD-CODED INTO THE PROGRAM.  USUALLY, IT IS THE SAME NAME AS
  THE
  PROGRAM, BUT NOT ALWAYS.  FOR SAKE OF ILLUSTRATION, LET'S ASSUME THAT
  THE PROGRAM IS NAMED "PAMPROG" AND THE NAME OF THE CONFIGURATION FILE
  IS /ETC/PAM.D/PAMPROG.

  IN THE /ETC/PAM.D/PAMPROG BUT THE FOLLOWING TWO LINES:

  AUTH    REQUIRED  PAM_PERMIT.SO
  AUTH    REQUIRED  PAM_WARN.SO
  NOW TRY TO USE PAMPROG.  THE FIRST LINE IN THE CONFIGURATION FILE
  SAYS THAT ALL USERS ARE PERMITTED.  THE SECOND LINE WILL WRITE A
  WARNING TO YOUR SYSLOG FILE (OR WHETHER YOU SYSLOG IS WRITING

  MESSAGES).  IF THIS TEST SUCCEEDS, THEN YOU KNOW THAT YOU HAVE
  A PROGRAM THAT CAN UNDERSTAND PAM, AND YOU CAN START THE MORE
  INTERESTING WORK OF DECIDING HOW TO STACK MODULES IN YOUR
  /ETC/PAM.D/PAMPROG  FILE.

  (...)
  
        THIS PART OF THE PAM_UNIX MODULE PERFORMS THE TASK OF UPDATING
        THE USER'S PASSWORD.


        IN THE CASE OF CONVENTIONAL UNIX DATABASES (WHICH STORE THE
        PASSWORD ENCRYPTED) THE MD5 ARGUMENT IS USED TO DO THE
        ENCRYPTION WITH THE MD5 FUNCTION AS OPPOSED TO THE CONVENTIONAL
        CRYPT(3) CALL.  AS AN ALTERNATIVE TO THIS, THE BIGCRYPT ARGUMENT
        CAN BE USED TO ENCRYPT MORE THAN THE FIRST 8 CHARACTERS OF A
        PASSWORD WITH DEC'S (DIGITAL EQUIPMENT COOPERATION) `C2'
        EXTENSION TO THE STANDARD UNIX CRYPT() ALGORITHM.


        THE NULLOK ARGUMENT IS USED TO PERMIT THE CHANGING OF A PASSWORD
        FROM AN EMPTY ONE. WITHOUT THIS ARGUMENT, EMPTY PASSWORDS ARE
        TREATED AS ACCOUNT-LOCKING ONES.


        THE ARGUMENT USE_FIRST_PASS IS USED TO LOCK THE CHOICE OF OLD
        AND NEW PASSWORDS TO THAT DICTATED BY THE PREVIOUSLY STACKED
        PASSWORD MODULE.  THE TRY_FIRST_PASS ARGUMENT IS USED TO AVOID
        THE USER HAVING TO RE-ENTER AN OLD PASSWORD WHEN PAM_UNIX
        FOLLOWS A MODULE THAT POSSIBLY SHARED THE USER'S OLD PASSWORD -
        IF THIS OLD PASSWORD IS NOT CORRECT THE USER WILL BE PROMPTED
        FOR THE CORRECT ONE.  THE ARGUMENT USE_AUTHTOK IS USED TO FORCE
        THIS MODULE TO SET THE NEW PASSWORD TO THE ONE PROVIDED BY THE
        PREVIOUSLY STACKED PASSWORD MODULE (THIS IS USED IN AN EXAMPLE
        OF THE STACKING OF THE CRACKLIB MODULE DOCUMENTED ABOVE).


        THE NOT_SET_PASS ARGUMENT IS USED TO INFORM THE MODULE THAT IT
        IS NOT TO PAY ATTENTION TO/MAKE AVAILABLE THE OLD OR NEW
        PASSWORDS FROM/TO OTHER (STACKED) PASSWORD MODULES.


        THE DEBUG ARGUMENT MAKES THE PASSWORD FUNCTIONS OF THIS MODULE
        SYSLOG(3) MORE INFORMATION ON ITS ACTIONS. OTHER ARGUMENTS MAY
        BE LOGGED AS ERRONEOUS TO SYSLOG(3). THE AUDIT ARGUMENT CAUSES
        EVEN MORE INFORMATION TO BE LOGGED.


        WITH THE NIS ARGUMENT, PAM_UNIX WILL ATTEMPT TO USE NIS RPC FOR
        SETTING NEW PASSWORDS.


        THE REMEMBER ARGUMENT TAKES ONE VALUE. THIS IS THE NUMBER OF
        MOST RECENT PASSWORDS TO SAVE FOR EACH USER. THESE ARE SAVED IN
        /ETC/SECURITY/OPASSWD IN ORDER TO FORCE PASSWORD CHANGE HISTORY
        AND KEEP THE USER FROM ALTERNATING BETWEEN THE SAME PASSWORD TOO
        FREQUENTLY.
  
  (...)
  
  FOLLOWING THE CALL PAM_GET_ITEM(PAMH,PAM_CONV,&ITEM), THE POINTER ITEM
  POINTS TO A CONVERSATION-FUNCTION THAT PROVIDES LIMITED BUT DIRECT
  ACCESS TO THE APPLICATION.  THE PURPOSE OF THIS FUNCTION IS TO ALLOW
  THE MODULE TO PROMPT THE USER FOR THEIR PASSWORD AND PASS OTHER
  INFORMATION IN A MANNER CONSISTENT WITH THE APPLICATION. FOR EXAMPLE,
  AN X-WINDOWS BASED PROGRAM MIGHT POP UP A DIALOG BOX TO REPORT A LOGIN
  FAILURE. JUST AS THE APPLICATION SHOULD NOT BE CONCERNED WITH THE
  METHOD OF AUTHENTICATION, SO THE MODULE SHOULD NOT DICTATE THE MANNER
  IN WHICH INPUT (OUTPUT) IS OBTAINED FROM (PRESENTED TO) TO THE USER.


  THE READER IS STRONGLY URGED TO READ THE MORE COMPLETE DESCRIPTION OF
  THE PAM_CONV STRUCTURE, WRITTEN FROM THE PERSPECTIVE OF THE
  APPLICATION DEVELOPER, IN THE LINUX-PAM APPLICATION DEVELOPERS' GUIDE.


  THE PAM_RESPONSE STRUCTURE RETURNED AFTER A CALL TO THE PAM_CONV
  FUNCTION MUST BE FREE()'D BY THE MODULE. SINCE THE CALL TO THE
  CONVERSATION FUNCTION ORIGINATES FROM THE MODULE, IT IS CLEAR THAT
  EITHER THIS PAM_RESPONSE STRUCTURE COULD BE EITHER STATICALLY OR
  DYNAMICALLY (USING MALLOC() ETC.) ALLOCATED WITHIN THE APPLICATION.
  REPEATED CALLS TO THE CONVERSATION FUNCTION WOULD LIKELY OVERWRITE
  STATIC MEMORY, SO IT IS REQUIRED THAT FOR A SUCCESSFUL RETURN FROM THE
  CONVERSATION FUNCTION THE MEMORY FOR THE RESPONSE STRUCTURE IS
  DYNAMICALLY ALLOCATED BY THE APPLICATION WITH ONE OF THE MALLOC()
  FAMILY OF COMMANDS AND MUST BE FREE()'D BY THE MODULE.


  IF THE PAM_CONV MECHANISM IS USED TO ENTER AUTHENTICATION TOKENS, THE
  MODULE SHOULD EITHER PASS THE RESULT TO THE PAM_SET_ITEM() LIBRARY
  FUNCTION, OR COPY IT ITSELF. IN SUCH A CASE, ONCE THE TOKEN HAS BEEN
  STORED (BY ONE OF THESE METHODS OR ANOTHER ONE), THE MEMORY RETURNED
  BY THE APPLICATION SHOULD BE OVERWRITTEN WITH 0'S, AND THEN FREE()'D.

  (...)
  
  THE FOLLOWING IS EXTRACTED FROM AN EMAIL.  I'LL TIDY IT UP LATER.


  THE POINT OF PAM IS THAT THE APPLICATION IS NOT SUPPOSED TO HAVE ANY
  IDEA HOW THE ATTATCHED AUTHENTICATION MODULES WILL CHOOSE TO
  AUTHENTICATE THE USER.  SO ALL THEY CAN DO IS PROVIDE A CONVERSATION
  FUNCTION THAT WILL TALK DIRECTLY TO THE USER(CLIENT) ON THE MODULES'
  BEHALF.


  CONSIDER THE CASE THAT YOU PLUG A RETINAL SCANNER INTO THE LOGIN
  PROGRAM.  IN THIS SITUATION THE USER WOULD BE PROMPTED: "PLEASE LOOK
  INTO THE SCANNER".  NO USERNAME OR PASSWORD WOULD BE NEEDED - ALL THIS
  INFORMATION COULD BE DEDUCED FROM THE SCAN AND A DATABASE LOOKUP.  THE
  POINT IS THAT THE RETINAL SCANNER IS AN IDEAL TASK FOR A "MODULE".


  WHILE IT IS TRUE THAT A POP-DAEMON PROGRAM IS DESIGNED WITH THE POP
  PROTOCOL IN MIND AND NO-ONE EVER CONSIDERED ATTATCHING A RETINAL
  SCANNER TO IT, IT IS ALSO THE CASE THAT THE "CLEAN" PAM'IFICATION OF
  SUCH A DAEMON WOULD ALLOW FOR THE POSSIBILITY OF A SCANNER MODULE
  BEING BE ATTATCHED TO IT.  THE POINT BEING THAT THE "STANDARD" POP-
  AUTHENTICATION PROTOCOL(S) [WHICH WILL BE NEEDED TO SATISFY
  INFLEXIBLE/LEGACY CLIENTS] WOULD BE SUPPORTED BY INSERTING AN
  APPROPRIATE PAM_QPOPPER MODULE(S).  HOWEVER, HAVING REWRITTEN POPD
  ONCE IN THIS WAY ANY NEW PROTOCOLS CAN BE IMPLEMENTED IN-SITU.


  ONE SIMPLE TEST OF A PORTED APPLICATION WOULD BE TO INSERT THE
  PAM_PERMIT MODULE AND SEE IF THE APPLICATION DEMANDS YOU TYPE A
  PASSWORD...  IN SUCH A CASE, XLOCK WOULD FAIL TO LOCK THE TERMINAL -
  OR WOULD AT BEST BE A SCREEN-SAVER, FTP WOULD GIVE PASSWORD FREE
  ACCESS TO ALL ETC..  NEITHER OF THESE IS A VERY SECURE THING TO DO,
  BUT THEY DO ILLUSTRATE HOW MUCH FLEXIBILITY PAM PUTS IN THE HANDS OF
  THE LOCAL ADMIN.


  THE KEY ISSUE, IN DOING THINGS CORRECTLY, IS IDENTIFYING WHAT IS PART
  OF THE AUTHENTICATION PROCEDURE (HOW MANY PASSWORDS ETC..) THE
  EXCHANGE PROTOCOL (PREFIXES TO PROMPTS ETC., NUMBERS LIKE 331 IN THE
  CASE OF FTPD) AND WHAT IS PART OF THE SERVICE THAT THE APPLICATION
  DELIVERS.  PAM REALLY NEEDS TO HAVE TOTAL CONTROL IN THE
  AUTHENTICATION "PROCEEDURE", THE CONVERSATION FUNCTION SHOULD ONLY
  DEAL WITH REFORMATTING USER PROMPTS AND EXTRACTING RESPONSES FROM RAW
  INPUT.
  