LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 536|回复: 1

有人懂mod_auth_pgsql么???

[复制链接]
发表于 2005-4-14 14:04:41 | 显示全部楼层 |阅读模式


  1. #define         AUTH_PGSQL_VERSION                "2.0.2b1"

  2. #include "apr_hooks.h"
  3. #include "apr.h"
  4. #include "apr_compat.h"
  5. #include "apr_lib.h"
  6. #include "apr_strings.h"
  7. #include "apr_buckets.h"
  8. #include "apr_md5.h"
  9. #include "apr_network_io.h"
  10. #include "apr_pools.h"
  11. #include "apr_uri.h"
  12. #include "apr_date.h"
  13. #include "apr_fnmatch.h"
  14. #define APR_WANT_STRFUNC
  15. #include "apr_want.h"

  16. #include "httpd.h"
  17. #include "http_config.h"
  18. #include "http_core.h"
  19. #include "http_log.h"
  20. #include "http_main.h"
  21. #include "http_protocol.h"
  22. #include "http_request.h"
  23. #include "util_script.h"

  24. #ifdef WIN32
  25. #define crypt apr_password_validate
  26. #else
  27. #include <unistd.h>
  28. #endif
  29. #include "libpq-fe.h"

  30. #if (MODULE_MAGIC_NUMBER_MAJOR < 20020628)
  31. #error  Apache 2.0.40 required
  32. #endif

  33. /*
  34. ** uncomment the following line if you're having problem. The debug messages
  35. ** will be written to the server error log.
  36. ** WARNING: we log sensitive data, do not use on production systems
  37. */

  38. /* #define DEBUG_AUTH_PGSQL 1 */



  39. #ifndef MAX_STRING_LEN
  40. #define MAX_STRING_LEN 8192
  41. #endif

  42. /* Cache table size */
  43. #ifndef MAX_TABLE_LEN
  44. #define MAX_TABLE_LEN 50
  45. #endif

  46. #define AUTH_PG_HASH_TYPE_CRYPT         1
  47. #define AUTH_PG_HASH_TYPE_MD5           2
  48. #define AUTH_PG_HASH_TYPE_BASE64        3


  49. typedef struct {
  50.         const char *dir;
  51.         const char *auth_pg_host;
  52.         const char *auth_pg_database;
  53.         const char *auth_pg_port;
  54.         const char *auth_pg_options;
  55.         const char *auth_pg_user;
  56.         const char *auth_pg_pwd;
  57.         const char *auth_pg_pwd_table;
  58.         const char *auth_pg_uname_field;
  59.         const char *auth_pg_pwd_field;
  60.         const char *auth_pg_grp_table;
  61.         const char *auth_pg_grp_group_field;
  62.         const char *auth_pg_grp_user_field;
  63.         const char *auth_pg_pwd_whereclause;
  64.         const char *auth_pg_grp_whereclause;

  65.         int auth_pg_nopasswd;
  66.         int auth_pg_authoritative;
  67.         int auth_pg_lowercaseuid;
  68.         int auth_pg_uppercaseuid;
  69.         int auth_pg_pwdignorecase;
  70.         int auth_pg_encrypted;
  71.         int auth_pg_hash_type;
  72.         int auth_pg_cache_passwords;
  73.         int auth_pg_connection_reuse;

  74.         const char *auth_pg_log_table;
  75.         const char *auth_pg_log_addrs_field;
  76.         const char *auth_pg_log_uname_field;
  77.         const char *auth_pg_log_pwd_field;
  78.         const char *auth_pg_log_date_field;
  79.         const char *auth_pg_log_uri_field;

  80.         apr_table_t *cache_pass_table;

  81. } pg_auth_config_rec;

  82. static apr_pool_t *auth_pgsql_pool = NULL;
  83. static apr_pool_t *auth_pgsql_pool_base64 = NULL;
  84. static PGconn *auth_pgsql_connection = NULL;

  85. module AP_MODULE_DECLARE_DATA auth_pgsql_module;



  86. int pg_log_auth_user(request_rec * r, pg_auth_config_rec * sec, char *user,
  87.                                          char *sent_pw);
  88. char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec);


  89. void *create_pg_auth_dir_config(apr_pool_t * p, char *d)
  90. {
  91.         pg_auth_config_rec *new_rec;

  92. #ifdef DEBUG_AUTH_PGSQL
  93.         ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p,
  94.                                   "[mod_auth_pgsql.c] - going to configure directory "%s" ",
  95.                                   d);
  96. #endif                                                        /* DEBUG_AUTH_PGSQL */

  97.         new_rec = apr_pcalloc(p, sizeof(pg_auth_config_rec));
  98.         if (new_rec == NULL)
  99.                 return NULL;

  100.         if (auth_pgsql_pool == NULL)
  101.                 apr_pool_create_ex(&auth_pgsql_pool, NULL, NULL, NULL);
  102.         if (auth_pgsql_pool == NULL)
  103.                 return NULL;

  104.         /* sane defaults */
  105.         if (d != NULL)
  106.                 new_rec->dir = apr_pstrdup(p, d);
  107.         else
  108.                 new_rec->dir = NULL;
  109.         new_rec->auth_pg_host = NULL;
  110.         new_rec->auth_pg_database = NULL;
  111.         new_rec->auth_pg_port = NULL;
  112.         new_rec->auth_pg_options = NULL;
  113.         new_rec->auth_pg_user = NULL;
  114.         new_rec->auth_pg_pwd = NULL;
  115.         new_rec->auth_pg_pwd_table = NULL;
  116.         new_rec->auth_pg_uname_field = NULL;
  117.         new_rec->auth_pg_pwd_field = NULL;
  118.         new_rec->auth_pg_grp_table = NULL;
  119.         new_rec->auth_pg_grp_user_field = NULL;
  120.         new_rec->auth_pg_grp_group_field = NULL;
  121.         new_rec->auth_pg_pwd_whereclause = NULL;
  122.         new_rec->auth_pg_grp_whereclause = NULL;

  123.         new_rec->auth_pg_nopasswd = 0;
  124.         new_rec->auth_pg_authoritative = 1;
  125.         new_rec->auth_pg_lowercaseuid = 0;
  126.         new_rec->auth_pg_uppercaseuid = 0;
  127.         new_rec->auth_pg_pwdignorecase = 0;
  128.         new_rec->auth_pg_encrypted = 1;
  129.         new_rec->auth_pg_hash_type = AUTH_PG_HASH_TYPE_CRYPT;
  130.         new_rec->auth_pg_cache_passwords = 0;
  131.         new_rec->auth_pg_connection_reuse = 0;

  132.         new_rec->auth_pg_log_table = NULL;
  133.         new_rec->auth_pg_log_addrs_field = NULL;
  134.         new_rec->auth_pg_log_uname_field = NULL;
  135.         new_rec->auth_pg_log_pwd_field = NULL;
  136.         new_rec->auth_pg_log_date_field = NULL;
  137.         new_rec->auth_pg_log_uri_field = NULL;

  138.         /* make a per directory cache table */
  139.         new_rec->cache_pass_table =
  140.                 apr_table_make(auth_pgsql_pool, MAX_TABLE_LEN);
  141.         if (new_rec->cache_pass_table == NULL)
  142.                 return NULL;

  143. #ifdef DEBUG_AUTH_PGSQL
  144.         ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p,
  145.                                   "[mod_auth_pgsql.c] - configured directory "%s" ", d);
  146. #endif                                                        /* DEBUG_AUTH_PGSQL */

  147.         return new_rec;
  148. }


  149. const char *pg_set_hash_type(cmd_parms * cmd, void *mconfig,
  150.                                                          const char *hash_type)
  151. {
  152.         pg_auth_config_rec *sec = mconfig;

  153.         if (!strcasecmp(hash_type, "MD5"))
  154.                 sec->auth_pg_hash_type = AUTH_PG_HASH_TYPE_MD5;
  155.         else if (!strcasecmp(hash_type, "CRYPT"))
  156.                 sec->auth_pg_hash_type = AUTH_PG_HASH_TYPE_CRYPT;
  157.         else if (!strcasecmp(hash_type, "BASE64"))
  158.                 sec->auth_pg_hash_type = AUTH_PG_HASH_TYPE_BASE64;
  159.         else
  160.                 return apr_pstrcat(cmd->pool,
  161.                                                    "Invalid hash type for Auth_PG_hash_type: ",
  162.                                                    hash_type, NULL);
  163.         return NULL;
  164. }

  165. const char *pg_set_authoritative_flag(cmd_parms * cmd,
  166.                                                                           pg_auth_config_rec * sec,
  167.                                                                           const int arg)
  168. {
  169.         sec->auth_pg_authoritative = arg;
  170.         return NULL;
  171. }

  172. static const char *pg_set_lowercaseuid_flag(cmd_parms * cmd, void *sec,
  173.                                                                                         const int arg)
  174. {
  175.         ((pg_auth_config_rec *) sec)->auth_pg_lowercaseuid = arg;
  176.         ((pg_auth_config_rec *) sec)->auth_pg_uppercaseuid = 0;
  177.         return NULL;
  178. }

  179. static const char *pg_set_uppercaseuid_flag(cmd_parms * cmd, void *sec,
  180.                                                                                         int arg)
  181. {
  182.         ((pg_auth_config_rec *) sec)->auth_pg_uppercaseuid = arg;
  183.         ((pg_auth_config_rec *) sec)->auth_pg_lowercaseuid = 0;
  184.         return NULL;
  185. }


  186. static const command_rec pg_auth_cmds[] = {
  187.         AP_INIT_TAKE1("Auth_PG_host", ap_set_string_slot,
  188.                                   (void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_host),
  189.                                   OR_AUTHCFG,
  190.                                   "the host name of the postgreSQL server."),
  191.         AP_INIT_TAKE1("Auth_PG_database", ap_set_string_slot,
  192.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  193.                                                                                 auth_pg_database), OR_AUTHCFG,
  194.                                   "the name of the database that contains authorization information."),
  195.         AP_INIT_TAKE1("Auth_PG_port", ap_set_string_slot,
  196.                                   (void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_port),
  197.                                   OR_AUTHCFG,
  198.                                   "the port the postmaster is running on."),
  199.         AP_INIT_TAKE1("Auth_PG_options", ap_set_string_slot,
  200.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  201.                                                                                 auth_pg_options), OR_AUTHCFG,
  202.                                   "an options string to be sent to the postgres backed process."),
  203.         AP_INIT_TAKE1("Auth_PG_user", ap_set_string_slot,
  204.                                   (void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_user),
  205.                                   OR_AUTHCFG,
  206.                                   "user name connect as"),
  207.         AP_INIT_TAKE1("Auth_PG_pwd", ap_set_string_slot,
  208.                                   (void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_pwd),
  209.                                   OR_AUTHCFG,
  210.                                   "password to connect"),
  211.         AP_INIT_TAKE1("Auth_PG_pwd_table", ap_set_string_slot,
  212.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  213.                                                                                 auth_pg_pwd_table), OR_AUTHCFG,
  214.                                   "the name of the table containing username/password tuples."),
  215.         AP_INIT_TAKE1("Auth_PG_pwd_field", ap_set_string_slot,
  216.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  217.                                                                                 auth_pg_pwd_field), OR_AUTHCFG,
  218.                                   "the name of the password field."),
  219.         AP_INIT_TAKE1("Auth_PG_uid_field", ap_set_string_slot,
  220.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  221.                                                                                 auth_pg_uname_field), OR_AUTHCFG,
  222.                                   "the name of the user-id field."),
  223.         AP_INIT_TAKE1("Auth_PG_grp_table", ap_set_string_slot,
  224.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  225.                                                                                 auth_pg_grp_table), OR_AUTHCFG,
  226.                                   "the name of the table containing username/group tuples."),
  227.         AP_INIT_TAKE1("Auth_PG_grp_group_field", ap_set_string_slot,
  228.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  229.                                                                                 auth_pg_grp_group_field),
  230.                                   OR_AUTHCFG,
  231.                                   "the name of the group-name field."),
  232.         AP_INIT_TAKE1("Auth_PG_grp_user_field", ap_set_string_slot,
  233.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  234.                                                                                 auth_pg_grp_user_field),
  235.                                   OR_AUTHCFG,
  236.                                   "the name of the group-name field."),
  237.         AP_INIT_FLAG("Auth_PG_nopasswd", ap_set_flag_slot,
  238.                                  (void *) APR_OFFSETOF(pg_auth_config_rec,
  239.                                                                            auth_pg_nopasswd),
  240.                                  OR_AUTHCFG,
  241.                                  "'on' or 'off'"),
  242.         AP_INIT_FLAG("Auth_PG_encrypted", ap_set_flag_slot,
  243.                                  (void *) APR_OFFSETOF(pg_auth_config_rec,
  244.                                                                            auth_pg_encrypted),
  245.                                  OR_AUTHCFG,
  246.                                  "'on' or 'off'"),
  247.         AP_INIT_TAKE1("Auth_PG_hash_type", pg_set_hash_type, NULL, OR_AUTHCFG,
  248.                                   "password hash type (CRYPT|MD5|BASE64)."),
  249.         AP_INIT_FLAG("Auth_PG_cache_passwords", ap_set_flag_slot,
  250.                                  (void *) APR_OFFSETOF(pg_auth_config_rec,
  251.                                                                            auth_pg_cache_passwords),
  252.                                  OR_AUTHCFG,
  253.                                  "'on' or 'off'"),
  254.         AP_INIT_FLAG("Auth_PG_connection_reuse", ap_set_flag_slot,
  255.                                  (void *) APR_OFFSETOF(pg_auth_config_rec,
  256.                                                                            auth_pg_connection_reuse),
  257.                                  OR_AUTHCFG,
  258.                                  "'on' or 'off'"),
  259.         AP_INIT_FLAG("Auth_PG_authoritative", ap_set_flag_slot,
  260.                                  (void *) APR_OFFSETOF(pg_auth_config_rec,
  261.                                                                            auth_pg_authoritative), OR_AUTHCFG,
  262.                                  "'on' or 'off'"),
  263.         AP_INIT_FLAG("Auth_PG_lowercase_uid", pg_set_lowercaseuid_flag, NULL,
  264.                                  OR_AUTHCFG,
  265.                                  "'on' or 'off'"),
  266.         AP_INIT_FLAG("Auth_PG_uppercase_uid", pg_set_uppercaseuid_flag, NULL,
  267.                                  OR_AUTHCFG,
  268.                                  "'on' or 'off'"),
  269.         AP_INIT_FLAG("Auth_PG_pwd_ignore_case", ap_set_flag_slot,
  270.                                  (void *) APR_OFFSETOF(pg_auth_config_rec,
  271.                                                                            auth_pg_pwdignorecase), OR_AUTHCFG,
  272.                                  "'on' or 'off'"),
  273.         AP_INIT_TAKE1("Auth_PG_grp_whereclause", ap_set_string_slot,
  274.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  275.                                                                                 auth_pg_grp_whereclause),
  276.                                   OR_AUTHCFG,
  277.                                   "an SQL fragement that can be attached to the end of a where clause."),
  278.         AP_INIT_TAKE1("Auth_PG_pwd_whereclause", ap_set_string_slot,
  279.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  280.                                                                                 auth_pg_pwd_whereclause),
  281.                                   OR_AUTHCFG,
  282.                                   "an SQL fragement that can be attached to the end of a where clause."),
  283.         AP_INIT_TAKE1("Auth_PG_log_table", ap_set_string_slot,
  284.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  285.                                                                                 auth_pg_log_table),
  286.                                   OR_AUTHCFG,
  287.                                   "the name of the table containing log tuples."),
  288.         AP_INIT_TAKE1("Auth_PG_log_addrs_field", ap_set_string_slot,
  289.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  290.                                                                                 auth_pg_log_addrs_field),
  291.                                   OR_AUTHCFG,
  292.                                   "the name of the field containing addrs in the log table (type char)."),
  293.         AP_INIT_TAKE1("Auth_PG_log_uname_field", ap_set_string_slot,
  294.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  295.                                                                                 auth_pg_log_uname_field),
  296.                                   OR_AUTHCFG,
  297.                                   "the name of the field containing username in the log table (type char)."),
  298.         AP_INIT_TAKE1("Auth_PG_log_pwd_field", ap_set_string_slot,
  299.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  300.                                                                                 auth_pg_log_pwd_field),
  301.                                   OR_AUTHCFG,
  302.                                   "the name of the field containing password in the log table (type char)."),
  303.         AP_INIT_TAKE1("Auth_PG_log_date_field", ap_set_string_slot,
  304.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  305.                                                                                 auth_pg_log_date_field),
  306.                                   OR_AUTHCFG,
  307.                                   "the name of the field containing date in the log table (type char)."),
  308.         AP_INIT_TAKE1("Auth_PG_log_uri_field", ap_set_string_slot,
  309.                                   (void *) APR_OFFSETOF(pg_auth_config_rec,
  310.                                                                                 auth_pg_log_uri_field),
  311.                                   OR_AUTHCFG,
  312.                                   "the name of the field containing uri (Object fetched) in the log table (type char)."),
  313.         {NULL}
  314. };


  315. char pg_errstr[MAX_STRING_LEN];
  316.                  /* global errno to be able to handle config/sql
  317.                   * failures separately
  318.                   */

  319. char *auth_pg_md5(char *pw)
  320. {
  321.         apr_md5_ctx_t ctx;
  322.         unsigned char digest[MD5_DIGESTSIZE];
  323.         static unsigned char md5hash[MD5_DIGESTSIZE * 2 + 1];
  324.         int i;

  325.         apr_md5(digest, (const unsigned char *) pw, strlen(pw));

  326.         for (i = 0; i < MD5_DIGESTSIZE; i++)
  327.                 apr_snprintf((char *) &md5hash[i + i], 3, "%02x", digest[i]);

  328.         md5hash[MD5_DIGESTSIZE * 2] = '\0';
  329.         return (char *) md5hash;
  330. }


  331. char *auth_pg_base64(char *pw)
  332. {
  333.         if (auth_pgsql_pool_base64 == NULL)
  334.                 apr_pool_create_ex(&auth_pgsql_pool_base64, NULL, NULL, NULL);
  335.         if (auth_pgsql_pool == NULL)
  336.                 return NULL;

  337.         return ap_pbase64encode(auth_pgsql_pool, pw);
  338. }



  339. /* Got from POstgreSQL 7.2 */
  340. /* ---------------
  341. * Escaping arbitrary strings to get valid SQL strings/identifiers.
  342. *
  343. * Replaces "\" with "\\\" and "'" with "''".
  344. * length is the length of the buffer pointed to by
  345. * from.  The buffer at to must be at least 2*length + 1 characters
  346. * long.  A terminating NUL character is written.
  347. * ---------------
  348. */

  349. size_t pg_check_string(char *to, const char *from, size_t length)
  350. {
  351.         const char *source = from;
  352.         char *target = to;
  353.         unsigned int remaining = length;

  354.         while (remaining > 0) {
  355.                 switch (*source) {
  356.                 case '\\':
  357.                         *target = '\\';
  358.                         target++;
  359.                         *target = '\\';
  360.                         /* target and remaining are updated below. */
  361.                         break;

  362.                 case '\'':
  363.                         *target = '\'';
  364.                         target++;
  365.                         *target = '\'';
  366.                         /* target and remaining are updated below. */
  367.                         break;

  368.                 default:
  369.                         *target = *source;
  370.                         /* target and remaining are updated below. */
  371.                 }
  372.                 source++;
  373.                 target++;
  374.                 remaining--;
  375.         }

  376.         /* Write the terminating NUL character. */
  377.         *target = '\0';

  378.         return target - to;
  379. }


  380. /* Do a query and return the (0,0) value.  The query is assumed to be
  381. * a select.
  382. */
  383. char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec)
  384. {

  385.         PGresult *pg_result;

  386.         char *val;
  387.         char *result = NULL;
  388.        
  389.         char *s;
  390.        
  391.         pg_errstr[0] = '\0';
  392.        
  393.        

  394.         /* Validate current connection for current dir setting*/
  395.         if (!(auth_pgsql_connection == NULL) ) {
  396.                 if ( !strcmp(sec->auth_pg_database, PQdb(auth_pgsql_connection)) &&
  397.                         !strcmp(sec->auth_pg_user, PQuser(auth_pgsql_connection))) {
  398. #ifdef DEBUG_AUTH_PGSQL
  399.                         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "Connection is valid");
  400. #endif                                                        /* DEBUG_AUTH_PGSQL */
  401.                 } else {
  402.                         PQfinish (auth_pgsql_connection);
  403.                         auth_pgsql_connection = NULL;
  404. #ifdef DEBUG_AUTH_PGSQL
  405.                         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "Connection is NOT valid");
  406. #endif                                                        /* DEBUG_AUTH_PGSQL */
  407.                 }  
  408.        
  409.         } /* end connection validation */
  410.        
  411.        
  412.        
  413.         if (auth_pgsql_connection == NULL) {
  414. #ifdef DEBUG_AUTH_PGSQL
  415.                 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  416.                                           "[mod_auth_pgsql.c] - do_pg_query - going to connect database "%s" ",
  417.                                           sec->auth_pg_database);
  418. #endif                                                        /* DEBUG_AUTH_PGSQL */

  419.                 auth_pgsql_connection =
  420.                         PQsetdbLogin(sec->auth_pg_host, sec->auth_pg_port,
  421.                                                  sec->auth_pg_options, NULL, sec->auth_pg_database,
  422.                                                  sec->auth_pg_user, sec->auth_pg_pwd);
  423.         }
  424.         if (PQstatus(auth_pgsql_connection) != CONNECTION_OK) {
  425.                 PQreset(auth_pgsql_connection);
  426.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  427.                                          "mod_auth_pgsql database connection error resetting %s",
  428.                                          PQerrorMessage(auth_pgsql_connection));
  429.                 if (PQstatus(auth_pgsql_connection) != CONNECTION_OK) {
  430.                         apr_snprintf(pg_errstr, MAX_STRING_LEN,
  431.                                                  "mod_auth_pgsql database connection error reset failed %s",
  432.                                                  PQerrorMessage(auth_pgsql_connection));
  433.                         return NULL;
  434.                 }
  435.         }
  436. #ifdef DEBUG_AUTH_PGSQL
  437.         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  438.                                   "[mod_auth_pgsql.c] - do_pg_query - going to execute query "%s" ",
  439.                                   query);
  440. #endif                                                        /* DEBUG_AUTH_PGSQL */

  441.         pg_result = PQexec(auth_pgsql_connection, query);

  442.         if (pg_result == NULL) {
  443.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  444.                                          "PGSQL 2: %s -- Query: %s ",
  445.                                          PQerrorMessage(auth_pgsql_connection), query);
  446.         }

  447.         if (PQresultStatus(pg_result) == PGRES_EMPTY_QUERY) {
  448.                 PQclear(pg_result);
  449.                 if (sec->auth_pg_connection_reuse==0){
  450.                         PQfinish(auth_pgsql_connection);
  451.                         auth_pgsql_connection=NULL;
  452.                 }
  453.                 return NULL;
  454.         }

  455.         if (PQresultStatus(pg_result) != PGRES_TUPLES_OK) {
  456.                 apr_snprintf(pg_errstr, MAX_STRING_LEN, "PGSQL 3: %s -- Query: %s",
  457.                                          PQerrorMessage(auth_pgsql_connection), query);
  458.                 PQclear(pg_result);
  459.                 if (sec->auth_pg_connection_reuse==0){
  460.                         PQfinish(auth_pgsql_connection);
  461.                         auth_pgsql_connection=NULL;
  462.                 }
  463.                 return NULL;
  464.         }

  465.         if (PQntuples(pg_result) == 1) {
  466.                 val = PQgetvalue(pg_result, 0, 0);
  467.                 if (val == NULL) {
  468.                         apr_snprintf(pg_errstr, MAX_STRING_LEN, "PGSQL 4: %s",
  469.                                                  PQerrorMessage(auth_pgsql_connection));
  470.                         PQclear(pg_result);
  471.                         if (sec->auth_pg_connection_reuse==0){
  472.                                 PQfinish(auth_pgsql_connection);
  473.                                 auth_pgsql_connection=NULL;
  474.                         }
  475.                         return NULL;
  476.                 }

  477.                 if (!(result = (char *) ap_palloc(r->pool, strlen(val) + 1))) {
  478.                         apr_snprintf(pg_errstr, MAX_STRING_LEN,
  479.                                                  "Could not get memory for Postgres query.");
  480.                         PQclear(pg_result);
  481.                         if (sec->auth_pg_connection_reuse==0){
  482.                                 PQfinish(auth_pgsql_connection);
  483.                                 auth_pgsql_connection=NULL;
  484.                         }
  485.                         return NULL;
  486.                 }

  487.                 strcpy(result, val);
  488.         }

  489.         /* ignore errors here ! */
  490.         PQclear(pg_result);
  491.         if (sec->auth_pg_connection_reuse==0){
  492.                 PQfinish(auth_pgsql_connection);
  493.                 auth_pgsql_connection=NULL;
  494.         }

  495.         return result;
  496. }

  497. char *get_pg_pw(request_rec * r, char *user, pg_auth_config_rec * sec)
  498. {
  499.         char query[MAX_STRING_LEN];
  500.         char *safe_user;
  501.         int n;

  502.         safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user));
  503.         pg_check_string(safe_user, user, strlen(user));

  504. #ifdef DEBUG_AUTH_PGSQL
  505.         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  506.                                   "[mod_auth_pgsql.c] - get_pg_pw - going to retrieve password for user "%s" from database",
  507.                                   user);
  508. #endif                                                        /* DEBUG_AUTH_PGSQL */

  509.         if ((!sec->auth_pg_pwd_table) ||
  510.                 (!sec->auth_pg_pwd_field) || (!sec->auth_pg_uname_field)) {
  511.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  512.                                          "PG: Missing parameters for password lookup: %s%s%s",
  513.                                          (sec->auth_pg_pwd_table ? "" : "Password table "),
  514.                                          (sec->
  515.                                           auth_pg_pwd_field ? "" : "Password field name "),
  516.                                          (sec->
  517.                                           auth_pg_uname_field ? "" : "UserID field name "));
  518.                 return NULL;
  519.         };

  520.         if (sec->auth_pg_lowercaseuid) {
  521.                 /* and force it to lowercase */
  522.                 n = 0;
  523.                 while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
  524.                         if (isupper(safe_user[n])) {
  525.                                 safe_user[n] = tolower(safe_user[n]);
  526.                         }
  527.                         n++;
  528.                 }
  529.         }

  530.         if (sec->auth_pg_uppercaseuid) {
  531.                 /* and force it to uppercase */
  532.                 n = 0;
  533.                 while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
  534.                         if (islower(safe_user[n])) {
  535.                                 safe_user[n] = toupper(safe_user[n]);
  536.                         }
  537.                         n++;
  538.                 }
  539.         }

  540.         n = apr_snprintf(query, MAX_STRING_LEN,
  541.                                          "select %s from %s where %s='%s' %s",
  542.                                          sec->auth_pg_pwd_field, sec->auth_pg_pwd_table,
  543.                                          sec->auth_pg_uname_field, safe_user,
  544.                                          sec->auth_pg_pwd_whereclause ? sec->
  545.                                          auth_pg_pwd_whereclause : "");

  546.         if (n < 0 || n > MAX_STRING_LEN) {
  547.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  548.                                          "PG: Detected SQL-truncation attack. Auth aborted.");
  549.                 return NULL;
  550.         }
  551.         return do_pg_query(r, query, sec);
  552. }

  553. char *get_pg_grp(request_rec * r, char *group, char *user,
  554.                                  pg_auth_config_rec * sec)
  555. {
  556.         char query[MAX_STRING_LEN];
  557.         char *safe_user;
  558.         char *safe_group;
  559.         int n;

  560.         safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user));
  561.         safe_group = apr_palloc(r->pool, 1 + 2 * strlen(group));

  562. #ifdef DEBUG_AUTH_PGSQL
  563.         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  564.                                   "[mod_auth_pgsql.c] - get_pg_grp - going to retrieve group for user "%s" from database",
  565.                                   user);
  566. #endif                                                        /* DEBUG_AUTH_PGSQL */

  567.         query[0] = '\0';
  568.         pg_check_string(safe_user, user, strlen(user));
  569.         pg_check_string(safe_group, group, strlen(group));

  570.         if ((!sec->auth_pg_grp_table) ||
  571.                 (!sec->auth_pg_grp_group_field) || (!sec->auth_pg_grp_user_field))
  572.         {
  573.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  574.                                          "PG: Missing parameters for password lookup: %s%s%s",
  575.                                          (sec->auth_pg_grp_table ? "" : "Group table name"),
  576.                                          (sec->
  577.                                           auth_pg_grp_group_field ? "" :
  578.                                           "GroupID field name "),
  579.                                          (sec->
  580.                                           auth_pg_grp_user_field ? "" :
  581.                                           "Group table user field name "));
  582.                 return NULL;
  583.         };

  584.         if (sec->auth_pg_lowercaseuid) {
  585.                 /* and force it to lowercase */
  586.                 n = 0;
  587.                 while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
  588.                         if (isupper(safe_user[n])) {
  589.                                 safe_user[n] = tolower(safe_user[n]);
  590.                         }
  591.                         n++;
  592.                 }
  593.         }

  594.         if (sec->auth_pg_uppercaseuid) {
  595.                 /* and force it to uppercase */
  596.                 n = 0;
  597.                 while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
  598.                         if (islower(safe_user[n])) {
  599.                                 safe_user[n] = toupper(safe_user[n]);
  600.                         }
  601.                         n++;
  602.                 }
  603.         }


  604.         n = apr_snprintf(query, MAX_STRING_LEN,
  605.                                          "select %s from %s where %s='%s' and %s='%s' %s",
  606.                                          sec->auth_pg_grp_group_field, sec->auth_pg_grp_table,
  607.                                          sec->auth_pg_grp_user_field, safe_user,
  608.                                          sec->auth_pg_grp_group_field, safe_group,
  609.                                          sec->auth_pg_grp_whereclause ? sec->
  610.                                          auth_pg_grp_whereclause : "");

  611.         if (n < 0 || n > MAX_STRING_LEN) {
  612.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  613.                                          "PG: Detected SQL-truncation attack. Auth aborted.");
  614.                 return NULL;
  615.         }

  616.         return do_pg_query(r, query, sec);
  617. }

  618. /* Process authentication request from Apache*/
  619. int pg_authenticate_basic_user(request_rec * r)
  620. {
  621.         pg_auth_config_rec *sec =
  622.                 (pg_auth_config_rec *) ap_get_module_config(r->per_dir_config,
  623.                                                                                                         &auth_pgsql_module);
  624.         char *val = NULL;
  625.         char *sent_pw, *real_pw;
  626.         int res;
  627.         char *user;
  628.         user = r->user;

  629.         if ((res = ap_get_basic_auth_pw(r, (const char **) &sent_pw)))
  630.                 return res;

  631. #ifdef DEBUG_AUTH_PGSQL
  632.         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  633.                                   "[mod_auth_pgsql.c] - pg_authenticate_basic_user - going to auth user "%s" pass "%s" uri "%s"",
  634.                                   user, sent_pw, r->unparsed_uri);
  635. #endif                                                        /* DEBUG_AUTH_PGSQL */

  636.         /* if *password* checking is configured in any way, i.e. then
  637.          * handle it, if not decline and leave it to the next in line..  
  638.          * We do not check on dbase, group, userid or host name, as it is
  639.          * perfectly possible to only do group control and leave
  640.          * user control to the next guy in line.
  641.          */
  642.         if ((!sec->auth_pg_pwd_table) && (!sec->auth_pg_pwd_field)) {
  643.                 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  644.                                           "[mod_auth_pgsql.c] - missing configuration parameters");
  645.                 return DECLINED;
  646.         }
  647.         pg_errstr[0] = '\0';

  648.         if (sec->auth_pg_cache_passwords
  649.                 && (!apr_is_empty_table(sec->cache_pass_table))) {
  650.                 val = (char *) apr_table_get(sec->cache_pass_table, user);

  651.                 if (val)
  652.                         real_pw = val;
  653.                 else
  654.                         real_pw = get_pg_pw(r, user, sec);
  655.         } else
  656.                 real_pw = get_pg_pw(r, user, sec);

  657.         if (!real_pw) {
  658.                 if (pg_errstr[0]) {
  659.                         res = HTTP_INTERNAL_SERVER_ERROR;
  660.                 } else {
  661.                         if (sec->auth_pg_authoritative) {
  662.                                 /* force error and access denied */
  663.                                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  664.                                                          "mod_auth_pgsql: Password for user %s not found (PG-Authoritative)",
  665.                                                          user);
  666.                                 ap_note_basic_auth_failure(r);
  667.                                 res = HTTP_UNAUTHORIZED;
  668.                         } else {
  669.                                 /* allow fall through to another module */
  670.                                 return DECLINED;
  671.                         }
  672.                 }
  673.                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  674.                 return res;
  675.         }

  676.         /* allow no password, if the flag is set and the password
  677.          * is empty. But be sure to log this.
  678.          */
  679.         if ((sec->auth_pg_nopasswd) && (!strlen(real_pw))) {
  680.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  681.                                          "[mod_auth_pgsql.c] - Empty password accepted for user "%s"",
  682.                                          user);
  683.                 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, pg_errstr);
  684.                 pg_log_auth_user(r, sec, user, sent_pw);
  685.                 return OK;
  686.         };

  687.         /* if the flag is off however, keep that kind of stuff at
  688.          * an arms length.
  689.          */
  690.         if ((!strlen(real_pw)) || (!strlen(sent_pw))) {
  691.                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  692.                                          "[mod_auth_pgsql.c] - Empty password rejected for user "%s"",
  693.                                          user);
  694.                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  695.                 ap_note_basic_auth_failure(r);
  696.                 return HTTP_UNAUTHORIZED;
  697.         };

  698.         if (sec->auth_pg_encrypted)
  699.                 switch (sec->auth_pg_hash_type) {
  700.                 case AUTH_PG_HASH_TYPE_MD5:
  701.                         sent_pw = auth_pg_md5(sent_pw);
  702.                         break;
  703.                 case AUTH_PG_HASH_TYPE_CRYPT:
  704.                         sent_pw = (char *) crypt(sent_pw, real_pw);
  705.                         break;
  706.                 case AUTH_PG_HASH_TYPE_BASE64:
  707.                         sent_pw = auth_pg_base64(sent_pw);
  708.                         break;
  709.                 }


  710.         if ((sec->auth_pg_hash_type == AUTH_PG_HASH_TYPE_MD5
  711.                  || sec->auth_pg_pwdignorecase != 0) ? strcasecmp(real_pw,
  712.                                                                                                                   sent_pw) :
  713.                 strcmp(real_pw, sent_pw))

  714.                 if ((sec->auth_pg_hash_type == AUTH_PG_HASH_TYPE_MD5
  715.                          || sec->auth_pg_hash_type == AUTH_PG_HASH_TYPE_BASE64
  716.                          || sec->auth_pg_pwdignorecase)
  717.                         ? strcasecmp(real_pw, sent_pw) : strcmp(real_pw, sent_pw)) {
  718.                         apr_snprintf(pg_errstr, MAX_STRING_LEN,
  719.                                                  "PG user %s: password mismatch", user);
  720.                         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  721.                         ap_note_basic_auth_failure(r);
  722.                         return HTTP_UNAUTHORIZED;
  723.                 }

  724.         /*  store password in the cache */
  725.         if (sec->auth_pg_cache_passwords && !val && sec->cache_pass_table) {
  726.                 if ((apr_table_elts(sec->cache_pass_table))->nelts >=
  727.                         MAX_TABLE_LEN) {
  728.                         apr_table_clear(sec->cache_pass_table);
  729.                 }
  730.                 apr_table_set(sec->cache_pass_table, user, real_pw);
  731.         }

  732.         pg_log_auth_user(r, sec, user, sent_pw);
  733.         return OK;
  734. }

  735. /* Checking ID */

  736. int pg_check_auth(request_rec * r)
  737. {
  738.         pg_auth_config_rec *sec =
  739.                 (pg_auth_config_rec *) ap_get_module_config(r->per_dir_config,
  740.                                                                                                         &auth_pgsql_module);
  741.         char *user = r->user;
  742.         int m = r->method_number;
  743.         int group_result = DECLINED;



  744.         apr_array_header_t *reqs_arr = (apr_array_header_t *) ap_requires(r);
  745.         require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL;

  746.         register int x, res;
  747.         const char *t;
  748.         char *w;

  749.         pg_errstr[0] = '\0';

  750. #ifdef DEBUG_AUTH_PGSQL
  751.         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
  752.                                   "[mod_auth_pgsql.c] - pg_check_auth - going to check auth for user "%s" ",
  753.                                   user);
  754. #endif                                                        /* DEBUG_AUTH_PGSQL */



  755.         /* if we cannot do it; leave it to some other guy
  756.          */
  757.         if ((!sec->auth_pg_grp_table) && (!sec->auth_pg_grp_group_field)
  758.                 && (!sec->auth_pg_grp_user_field))
  759.                 return DECLINED;

  760.         if (!reqs_arr) {
  761.                 if (sec->auth_pg_authoritative) {
  762.                         /* force error and access denied */
  763.                         apr_snprintf(pg_errstr, MAX_STRING_LEN,
  764.                                                  "mod_auth_pgsql: user %s denied, no access rules specified (PG-Authoritative)",
  765.                                                  user);
  766.                         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  767.                         ap_note_basic_auth_failure(r);
  768.                         res = HTTP_UNAUTHORIZED;
  769.                 } else {
  770.                         return DECLINED;
  771.                 }
  772.         }

  773.         for (x = 0; x < reqs_arr->nelts; x++) {

  774.                 if (!(reqs[x].method_mask & (1 << m)))
  775.                         continue;

  776.                 t = reqs[x].requirement;
  777.                 w = ap_getword(r->pool, &t, ' ');

  778.                 if (!strcmp(w, "valid-user"))
  779.                         return OK;

  780.                 if (!strcmp(w, "user")) {
  781.                         while (t[0]) {
  782.                                 w = ap_getword_conf(r->pool, &t);
  783.                                 if (!strcmp(user, w))
  784.                                         return OK;
  785.                         }
  786.                         if (sec->auth_pg_authoritative) {
  787.                                 /* force error and access denied */
  788.                                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  789.                                                          "mod_auth_pgsql: user %s denied, no access rules specified (PG-Authoritative)",
  790.                                                          user);
  791.                                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  792.                                 ap_note_basic_auth_failure(r);
  793.                                 return HTTP_UNAUTHORIZED;
  794.                         }

  795.                 } else if (!strcmp(w, "group")) {
  796.                         /* look up the membership for each of the groups in the table */
  797.                         pg_errstr[0] = '\0';

  798.                         while (t[0]) {
  799.                                 if (get_pg_grp(r, ap_getword(r->pool, &t, ' '), user, sec)) {
  800.                                         group_result = OK;
  801.                                 };
  802.                         };

  803.                         if (pg_errstr[0]) {
  804.                                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  805.                                 return HTTP_INTERNAL_SERVER_ERROR;
  806.                         }

  807.                         if (group_result == OK)
  808.                                 return OK;

  809.                         if (sec->auth_pg_authoritative) {
  810.                                 apr_snprintf(pg_errstr, MAX_STRING_LEN,
  811.                                                          "[mod_auth_pgsql.c] - user %s not in right groups (PG-Authoritative)",
  812.                                                          user);
  813.                                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, pg_errstr);
  814.                                 ap_note_basic_auth_failure(r);
  815.                                 return HTTP_UNAUTHORIZED;
  816.                         };
  817.                 }
  818.         }

  819.         return DECLINED;
  820. }


  821. /* Send the authentication to the log table */
  822. int
  823. pg_log_auth_user(request_rec * r, pg_auth_config_rec * sec, char *user,
  824.                                  char *sent_pw)
  825. {
  826.         char sql[MAX_STRING_LEN];
  827.         char *s;
  828.         int n;
  829.         char fields[MAX_STRING_LEN];
  830.         char values[MAX_STRING_LEN];
  831.         char *safe_user;
  832.         char *safe_pw;
  833.         char *safe_req;
  834.         char ts[MAX_STRING_LEN];        /* time in string format */
  835.         apr_time_exp_t t;                        /* time of request start */
  836.         apr_size_t retsize;

  837.         safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user));
  838.         safe_pw = apr_palloc(r->pool, 1 + 2 * strlen(sent_pw));
  839.         safe_req = apr_palloc(r->pool, 1 + 2 * strlen(r->the_request));

  840.         /* we do not want to process internal redirect  */
  841.         if (!ap_is_initial_req(r))
  842.                 return DECLINED;
  843.         if ((!sec->auth_pg_log_table) || (!sec->auth_pg_log_uname_field) || (!sec->auth_pg_log_date_field)) {        // At least table name, username and date field are specified
  844.                 // send error message and exit
  845.                 return DECLINED;
  846.         }

  847.         /* AUD: MAX_STRING_LEN probably isn't always correct */
  848.         pg_check_string(safe_user, user, strlen(user));
  849.         pg_check_string(safe_pw, sent_pw, strlen(sent_pw));
  850.         pg_check_string(safe_req, r->the_request, strlen(r->the_request));


  851.         if (sec->auth_pg_lowercaseuid) {
  852.                 /* and force it to lowercase */
  853.                 n = 0;
  854.                 while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
  855.                         if (isupper(safe_user[n])) {
  856.                                 safe_user[n] = tolower(safe_user[n]);
  857.                         }
  858.                         n++;
  859.                 }
  860.         }

  861.         if (sec->auth_pg_uppercaseuid) {
  862.                 /* and force it to uppercase */
  863.                 n = 0;
  864.                 while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
  865.                         if (islower(safe_user[n])) {
  866.                                 safe_user[n] = toupper(safe_user[n]);
  867.                         }
  868.                         n++;
  869.                 }
  870.         }


  871.         /* time field format  */
  872.         apr_time_exp_lt(&t, r->request_time);
  873.         apr_strftime(ts, &retsize, 100, "%Y-%m-%d %H:%M:%S", &t);



  874.         /* SQL Statement, required fields: Username, Date */
  875.         apr_snprintf(fields, MAX_STRING_LEN, "%s,%s",
  876.                                  sec->auth_pg_log_uname_field,
  877.                                  sec->auth_pg_log_date_field);
  878.         apr_snprintf(values, MAX_STRING_LEN, "'%s','%s'", safe_user, ts);

  879.         /* Optional parameters */
  880.         if (sec->auth_pg_log_addrs_field) {        /* IP Address field */
  881.                 apr_snprintf(sql, MAX_STRING_LEN, ", %s",
  882.                                          sec->auth_pg_log_addrs_field);
  883.                 strncat(fields, sql, MAX_STRING_LEN - strlen(fields) - 1);
  884.                 apr_snprintf(sql, MAX_STRING_LEN, ", '%s'",
  885.                                          r->connection->remote_ip);
  886.                 strncat(values, sql, MAX_STRING_LEN - strlen(values) - 1);
  887.         }
  888.         if (sec->auth_pg_log_pwd_field) {        /* Password field , clear WARNING */
  889.                 apr_snprintf(sql, MAX_STRING_LEN, ", %s",
  890.                                          sec->auth_pg_log_pwd_field);
  891.                 strncat(fields, sql, MAX_STRING_LEN - strlen(fields) - 1);
  892.                 apr_snprintf(sql, MAX_STRING_LEN, ", '%s'", safe_pw);
  893.                 strncat(values, sql, MAX_STRING_LEN - strlen(values) - 1);
  894.         }
  895.         if (sec->auth_pg_log_uri_field) {        /* request string */
  896.                 apr_snprintf(sql, MAX_STRING_LEN, ", %s",
  897.                                          sec->auth_pg_log_uri_field);
  898.                 strncat(fields, sql, MAX_STRING_LEN - strlen(fields) - 1);
  899.                 apr_snprintf(sql, MAX_STRING_LEN, ", '%s'", safe_req);
  900.                 strncat(values, sql, MAX_STRING_LEN - strlen(values) - 1);
  901.         }

  902.         apr_snprintf(sql, MAX_STRING_LEN, "insert into %s (%s) values(%s) ; ",
  903.                                  sec->auth_pg_log_table, fields, values);

  904.         s = do_pg_query(r, sql, sec);
  905.         return (0);
  906. }

  907. static int
  908. pg_auth_init_handler(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp,
  909.                                          server_rec * s)
  910. {
  911. #ifdef DEBUG_AUTH_PGSQL
  912.         ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p,
  913.                                   "[mod_auth_pgsql.c] - pg_auth_init_handler -  ");
  914. #endif                                                        /* DEBUG_AUTH_PGSQL */

  915.         ap_add_version_component(p, "mod_auth_pgsql/" AUTH_PGSQL_VERSION);
  916.         return OK;
  917. }

  918. /* Init the module private memory pool, used for the per directory cache tables */
  919. static void *pg_auth_server_config(apr_pool_t * p, server_rec * s)
  920. {
  921. #ifdef DEBUG_AUTH_PGSQL
  922.         ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p,
  923.                                   "[mod_auth_pgsql.c] - pg_auth_server_config -  ");
  924. #endif                                                        /* DEBUG_AUTH_PGSQL */

  925.         if (auth_pgsql_pool == NULL)
  926.                 apr_pool_create_ex(&auth_pgsql_pool, NULL, NULL, NULL);

  927.         return OK;
  928. }


  929. static void register_hooks(apr_pool_t * p)
  930. {
  931.         ap_hook_post_config(pg_auth_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
  932.         ap_hook_auth_checker(pg_check_auth, NULL, NULL, APR_HOOK_MIDDLE);
  933.         ap_hook_check_user_id(pg_authenticate_basic_user, NULL, NULL,
  934.                                                   APR_HOOK_MIDDLE);
  935. };

  936. module AP_MODULE_DECLARE_DATA auth_pgsql_module = {
  937.         STANDARD20_MODULE_STUFF,
  938.         create_pg_auth_dir_config,        /* dir config creater */
  939.         NULL,                                                /* dir merger --- default is to override */
  940.         pg_auth_server_config,                /* server config */
  941.         NULL,                                                /* merge server config */
  942.         pg_auth_cmds,                                /* command table */
  943.         register_hooks                                /* Apache2 register hooks */
  944. };
复制代码


现在我需要修改一下实现这么一个功能,就是通过pgsql模块的认证,但是每个帐户只能认证一次.也就是说,只要一个用户认证过了并且在线,那么这个用户帐户再来认证的时候就拒绝..


哪儿位高手来指教一下啊??
 楼主| 发表于 2005-4-15 10:04:17 | 显示全部楼层
up
and
up
!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表