home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / iis4_07.cab / DB.C < prev    next >
Text File  |  1997-10-25  |  8KB  |  391 lines

  1. /*++
  2.  
  3. Copyright (c) 1996  Microsoft Corporation
  4.  
  5. This program is released into the public domain for any purpose.
  6.  
  7.  
  8. Module Name:
  9.  
  10.     db.c
  11.  
  12. Abstract:
  13.  
  14.     This module implements the database routines for the authentication filter.
  15.  
  16. --*/
  17.  
  18. #include <windows.h>
  19. #include <httpfilt.h>
  20. #include "authfilt.h"
  21.  
  22. //
  23. //  This is the name of the file that contains the username/password pairs and
  24. //  the appropriate NT account the username/password should be mapped to.
  25. //
  26. //  The format of the file is:
  27. //
  28. //  User1:Password1, NTUser1:NTPassword1
  29. //  User2:Password2, NTUser2:NTPassword2
  30. //  User3:Password3, NTUser1:NTPassword1
  31. //
  32. //
  33.  
  34. #define USER_LIST_FILE     "c:\\inetsrv\\userdb.txt"
  35.  
  36. //
  37. //  Globals
  38. //
  39.  
  40. CHAR * pszUserFile = NULL;
  41.  
  42.  
  43. BOOL
  44. ValidateUser(
  45.     IN OUT CHAR * pszUserName,
  46.     IN OUT CHAR * pszPassword,
  47.     OUT    BOOL * pfValid
  48.     )
  49. /*++
  50.  
  51. Routine Description:
  52.  
  53.     Looks up the username and confirms the user is allowed access to the
  54.     server
  55.  
  56. Arguments:
  57.  
  58.     pszUserName - The username to validate, will contain the mapped username
  59.                   on return.  Must be at least SF_MAX_USERNAME
  60.     pszPassword - The password for this user.  Will contain the mapped
  61.                   password on return.  Must be at least SF_MAX_PASSWORD
  62.     pfValid     - Set to TRUE if the user should be logged on.
  63.  
  64. Return Value:
  65.  
  66.     TRUE on success, FALSE on failure
  67.  
  68. --*/
  69. {
  70.     BOOL fFound;
  71.     CHAR achPassword[SF_MAX_PASSWORD];
  72.     CHAR achNTUser[SF_MAX_USERNAME];
  73.     CHAR achNTUserPassword[SF_MAX_PASSWORD];
  74.  
  75.     //
  76.     //  Assume we're going to fail validation
  77.     //
  78.  
  79.     *pfValid = FALSE;
  80.  
  81.     //
  82.     //  Lookup the user in the cache, if that fails, get the user from the
  83.     //  database and add the retrieved user to the cache
  84.     //
  85.  
  86.     if ( !LookupUserInCache( pszUserName,
  87.                              &fFound,
  88.                              achPassword,
  89.                              achNTUser,
  90.                              achNTUserPassword ))
  91.     {
  92.         return FALSE;
  93.     }
  94.  
  95.     if ( !fFound )
  96.     {
  97.         if ( !LookupUserInDb( pszUserName,
  98.                               &fFound,
  99.                               achPassword,
  100.                               achNTUser,
  101.                               achNTUserPassword ))
  102.         {
  103.             return FALSE;
  104.         }
  105.  
  106.         if ( fFound )
  107.         {
  108.             AddUserToCache( pszUserName,
  109.                             achPassword,
  110.                             achNTUser,
  111.                             achNTUserPassword );
  112.         }
  113.     }
  114.  
  115.     if ( !fFound )
  116.     {
  117.         DbgWrite(( DEST,
  118.                    "[ValidateUser] Failed to find user %s\n",
  119.                    pszUserName ));
  120.  
  121.         return TRUE;
  122.     }
  123.  
  124.     //
  125.     //  Do the passwords match?
  126.     //
  127.  
  128.     if ( !strcmp( pszPassword, achPassword ))
  129.     {
  130.         //
  131.         //  We have a match, map to the NT user and password
  132.         //
  133.  
  134.         strcpy( pszUserName, achNTUser );
  135.         strcpy( pszPassword, achNTUserPassword );
  136.         *pfValid = TRUE;
  137.     }
  138.  
  139.     return TRUE;
  140. }
  141.  
  142. BOOL
  143. InitializeUserDatabase(
  144.     VOID
  145.     )
  146. /*++
  147.  
  148. Routine Description:
  149.  
  150.     Retrieves the userlist from the file.  If the users were coming from a
  151.     database, this routine would connect to the database.
  152.  
  153. Return Value:
  154.  
  155.     TRUE on success, FALSE on failure
  156.  
  157. --*/
  158. {
  159.     HANDLE hFile;
  160.     DWORD  cbFile;
  161.     DWORD  cbRead;
  162.  
  163.     //
  164.     //  Open and read the file.  The System account must have access to the
  165.     //  file.
  166.     //
  167.  
  168.     hFile = CreateFile( USER_LIST_FILE,
  169.                         GENERIC_READ,
  170.                         FILE_SHARE_READ,
  171.                         NULL,
  172.                         OPEN_EXISTING,
  173.                         0,
  174.                         NULL );
  175.  
  176.     if ( hFile == INVALID_HANDLE_VALUE )
  177.     {
  178.         DbgWrite(( DEST,
  179.                    "[InitializeUserDatabase] Error %d openning %s\n",
  180.                    GetLastError(),
  181.                    USER_LIST_FILE ));
  182.  
  183.         return FALSE;
  184.     }
  185.  
  186.     cbFile = GetFileSize( hFile, NULL );
  187.  
  188.     if ( cbFile == (DWORD) -1 )
  189.     {
  190.         CloseHandle( hFile );
  191.         return FALSE;
  192.     }
  193.  
  194.     pszUserFile = LocalAlloc( LPTR, cbFile + 1 );
  195.  
  196.     if ( !pszUserFile )
  197.     {
  198.         SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  199.         CloseHandle( hFile );
  200.         return FALSE;
  201.     }
  202.  
  203.     if ( !ReadFile( hFile,
  204.                     pszUserFile,
  205.                     cbFile,
  206.                     &cbRead,
  207.                     NULL ))
  208.     {
  209.         CloseHandle( hFile );
  210.         LocalFree( pszUserFile );
  211.  
  212.         return FALSE;
  213.     }
  214.  
  215.     CloseHandle( hFile );
  216.  
  217.     //
  218.     //  Zero terminate the file data
  219.     //
  220.  
  221.     pszUserFile[cbRead] = '\0';
  222.  
  223.     return TRUE;
  224. }
  225.  
  226. BOOL
  227. LookupUserInDb(
  228.     IN CHAR * pszUser,
  229.     OUT BOOL * pfFound,
  230.     OUT CHAR * pszPassword,
  231.     OUT CHAR * pszNTUser,
  232.     OUT CHAR * pszNTUserPassword
  233.     )
  234. /*++
  235.  
  236. Routine Description:
  237.  
  238.     Looks up the username in the database and returns the other attributes
  239.     associated with this user
  240.  
  241.     The file data is not sorted to simulate the cost of an external database
  242.     lookup.
  243.  
  244. Arguments:
  245.  
  246.     pszUserName - The username to find in the database (case insensitive)
  247.     pfFound     - Set to TRUE if the specified user name was found in the
  248.                   database
  249.     pszPassword - The external password for the found user.  Buffer must be
  250.                   at least SF_MAX_PASSWORD bytes.
  251.     pszNTUser   - The NT username associated with this user, Buffer must be at
  252.                   least SF_MAX_USERNAME bytes
  253.     pszNTUserPassword - The password for NTUser. Buffer must be at least
  254.                   SF_MAX_PASSWORD
  255.  
  256. Return Value:
  257.  
  258.     TRUE on success, FALSE on failure
  259.  
  260. --*/
  261. {
  262.     CHAR * pch = pszUserFile;
  263.     CHAR * pchEnd;
  264.     DWORD  cchUser = strlen( pszUser );
  265.     DWORD  cch;
  266.  
  267.     *pfFound = FALSE;
  268.  
  269.     //
  270.     //  Find the external username.  We're expecting one user per line in
  271.     //  the form:
  272.     //
  273.     //      username:password, NTUser:NTUserPassword
  274.     //
  275.  
  276.     while ( pch && *pch )
  277.     {
  278.         while ( ISWHITE( *pch ) )
  279.             pch++;
  280.  
  281.         if ( toupper( *pch ) == toupper( *pszUser ) &&
  282.              !strnicmp( pszUser, pch, cchUser )     &&
  283.              pch[cchUser] == ':' )
  284.         {
  285.             pch += cchUser + 1;
  286.             goto Found;
  287.         }
  288.  
  289.         pch = strchr( pch+1, '\n' );
  290.     }
  291.  
  292.     //
  293.     //  Not found
  294.     //
  295.  
  296.     return TRUE;
  297.  
  298. Found:
  299.  
  300.     //
  301.     //  Break out the external username
  302.     //
  303.  
  304.     if ( !(pchEnd = strchr( pch, ',' )))
  305.     {
  306.         SetLastError( ERROR_INVALID_PASSWORDNAME );
  307.         return FALSE;
  308.     }
  309.  
  310.     cch = pchEnd - pch;
  311.  
  312.     if ( cch+1 > SF_MAX_PASSWORD )
  313.     {
  314.         SetLastError( ERROR_INVALID_PASSWORDNAME );
  315.         return FALSE;
  316.     }
  317.  
  318.     memcpy( pszPassword, pch, cch );
  319.     pszPassword[cch] = '\0';
  320.  
  321.     pch = pchEnd + 1;
  322.  
  323.     //
  324.     //  Get the NT username from the file
  325.     //
  326.  
  327.     while ( ISWHITE( *pch ) )
  328.         pch++;
  329.  
  330.     if ( !(pchEnd = strchr( pch, ':' )))
  331.     {
  332.         SetLastError( ERROR_BAD_USERNAME );
  333.         return FALSE;
  334.     }
  335.  
  336.     cch = pchEnd - pch;
  337.  
  338.     if ( cch+1 > SF_MAX_USERNAME )
  339.     {
  340.         SetLastError( ERROR_BAD_USERNAME );
  341.         return FALSE;
  342.     }
  343.  
  344.     memcpy( pszNTUser, pch, cch );
  345.     pszNTUser[cch] = '\0';
  346.  
  347.     pch = pchEnd + 1;
  348.  
  349.     //
  350.     //  Get the NT password from the file, look for a '\r' or '\n'
  351.     //
  352.  
  353.     pchEnd = pch;
  354.  
  355.     while ( *pchEnd && *pchEnd != '\r' && *pchEnd != '\n' )
  356.         pchEnd++;
  357.  
  358.     cch = pchEnd - pch;
  359.  
  360.     if ( cch+1 > SF_MAX_PASSWORD )
  361.     {
  362.         SetLastError( ERROR_INVALID_PASSWORDNAME );
  363.         return FALSE;
  364.     }
  365.  
  366.     memcpy( pszNTUserPassword, pch, cch );
  367.     pszNTUserPassword[cch] = '\0';
  368.  
  369.     *pfFound = TRUE;
  370.  
  371.     return TRUE;
  372. }
  373.  
  374. VOID
  375. TerminateUserDatabase(
  376.     VOID
  377.     )
  378. /*++
  379.  
  380. Routine Description:
  381.  
  382.     Shutsdown the user database.
  383.  
  384. --*/
  385. {
  386.     if ( pszUserFile )
  387.     {
  388.         LocalFree( pszUserFile );
  389.     }
  390. }
  391.