(related to
Re: [EMAIL PROTECTED] A NetHack-esque Journey of the dark arts for
DBD(mysql) under httpd-2.2.3 and
Re: [EMAIL PROTECTED] Apache 2.2.3 and MySQL 5.0.24a
Re: [EMAIL PROTECTED] mod_dbd mod_authn_dbd mod_authz_dbd confusion
)
The following method should build correctly. Moreover, error reporting
is more informative - and has saved me a lot of time already -
It's easy to misconfigure something, and get an error happening
somewhere.
Here are a set of buildsteps for a linux install (considerably revised
since the NetHack-esque mailing) - it appears to build and install
more reliably now.
This mail doesn't include the fact that you must make sure your
libmysqlclient_r is available to be linked to.
===========================================================
Install - with example values.
===========================================================
wget http://apache.rmplc.co.uk/httpd/httpd-2.2.3.tar.gz
tar -xzf httpd-2.2.3.tar.gz
cd httpd-2.2.3
HP_SRC=`pwd`
#The above is just to have a way of jumping around directories more
easily... HP_SRC is an arbitrary name.
#Now sort out apr and apr-util installs
#Now manually change the install locations for apr and apr-util (ONLY
IF using a custom install directory - eg /opt/httpd/apr)
vi $HP_SRC/srclib/apr/config.layout # line 14 - in Layout apr,
change prefix to /opt/httpd/apr
#I had to change the libtool identity in build/buildcheck.sh for it to
work with me...
vi $HP_SRC/srclib/apr/build/buildcheck.sh #line 42 :
lt_pversion=`$libtool --version | grep ltmain.sh |sed -e
's/([^)]*)//g;s/^[^0-9]*//;s/[- ].*//g;q'`
#Now manually change the install locations for apr and apr-util (ONLY
IF using a custom install directory - eg /opt/httpd/apr)
vi $HP_SRC/srclib/apr-util/config.layout # line 14 - in Layout apr,
change prefix to /opt/httpd/apr
#Now get rid of the dbd general error (which is not informative), and
return the error that was received
vi $HP_SRC/srclib/apr-util/dbd/apr_dbd.c #Line, 170: Change
APR_EGENERAL to rv
#Now get the mysql driver
#remember the magic magic vi command :set paste to stop autoindents
when pasting into vi editor..
cd $HP_SRC/srclib/apr-util/dbd
wget http://apache.webthing.com/svn/apache/apr/apr_dbd_mysql.c
vi apr_dbd_mysql.c #rewrite the functions dbd_mysql_error and
dbd_mysql_check_conn as follows -
/*---------------------------- apr_dbd_mysql.c
---------------------------------*/
//Rewrite function dbd_mysql_check_conn (5 lines at line 744)
static apr_status_t dbd_mysql_check_conn(apr_pool_t *pool, apr_dbd_t
*handle) {
unsigned int mysql_err_num = mysql_ping(handle->conn);
if (mysql_err_num == 0) {
return APR_SUCCESS;
} else {
return APR_OS_START_USERERR + mysql_err_num;
}
}
//Rewrite function dbd_mysql_error (4 lines at 245)
static const char *dbd_mysql_error(apr_dbd_t *sql, int n)
{
const char *mysql_error_msg_string = mysql_error(sql->conn);
if (mysql_error_msg_string != NULL) {
return mysql_error_msg_string;
} else {
switch (n) {
case 0: return "no error";
case CR_CANT_READ_CHARSET: return "mysql error: CANT_READ_CHARSET";
case CR_COMMANDS_OUT_OF_SYNC: return "mysql error:
COMMANDS_OUT_OF_SYNC";
case CR_CONN_HOST_ERROR: return "mysql error: CONN_HOST_ERROR";
case CR_CONN_UNKNOW_PROTOCOL: return "mysql error:
CONN_UNKNOW_PROTOCOL";
case CR_CONNECTION_ERROR: return "mysql error: CONNECTION_ERROR";
case CR_DATA_TRUNCATED: return "mysql error: DATA_TRUNCATED";
case CR_EMBEDDED_CONNECTION: return "mysql error:
EMBEDDED_CONNECTION";
case CR_FETCH_CANCELED: return "mysql error: FETCH_CANCELED";
case CR_INVALID_BUFFER_USE: return "mysql error:
INVALID_BUFFER_USE";
case CR_INVALID_CONN_HANDLE: return "mysql error:
INVALID_CONN_HANDLE";
case CR_INVALID_PARAMETER_NO: return "mysql error:
INVALID_PARAMETER_NO";
case CR_IPSOCK_ERROR: return "mysql error: IPSOCK_ERROR";
case CR_LOCALHOST_CONNECTION: return "mysql error:
LOCALHOST_CONNECTION";
case CR_MALFORMED_PACKET: return "mysql error: MALFORMED_PACKET";
case CR_NAMEDPIPE_CONNECTION: return "mysql error:
NAMEDPIPE_CONNECTION";
case CR_NAMEDPIPEOPEN_ERROR: return "mysql error:
NAMEDPIPEOPEN_ERROR";
case CR_NAMEDPIPESETSTATE_ERROR: return "mysql error:
NAMEDPIPESETSTATE_ERROR";
case CR_NAMEDPIPEWAIT_ERROR: return "mysql error:
NAMEDPIPEWAIT_ERROR";
case CR_NET_PACKET_TOO_LARGE: return "mysql error:
NET_PACKET_TOO_LARGE";
case CR_NO_DATA: return "mysql error: NO_DATA";
case CR_NO_PARAMETERS_EXISTS: return "mysql error:
NO_PARAMETERS_EXISTS";
case CR_NO_PREPARE_STMT: return "mysql error: NO_PREPARE_STMT";
case CR_NO_RESULT_SET: return "mysql error: NO_RESULT_SET";
case CR_NO_STMT_METADATA: return "mysql error: NO_STMT_METADATA";
case CR_NOT_IMPLEMENTED: return "mysql error: NOT_IMPLEMENTED";
case CR_NULL_POINTER: return "mysql error: NULL_POINTER";
case CR_OUT_OF_MEMORY: return "mysql error: OUT_OF_MEMORY";
case CR_PARAMS_NOT_BOUND: return "mysql error: PARAMS_NOT_BOUND";
case CR_PROBE_MASTER_CONNECT: return "mysql error:
PROBE_MASTER_CONNECT";
case CR_PROBE_SLAVE_CONNECT: return "mysql error:
PROBE_SLAVE_CONNECT";
case CR_PROBE_SLAVE_HOSTS: return "mysql error: PROBE_SLAVE_HOSTS";
case CR_PROBE_SLAVE_STATUS: return "mysql error:
PROBE_SLAVE_STATUS";
case CR_SECURE_AUTH: return "mysql error: SECURE_AUTH";
case CR_SERVER_GONE_ERROR: return "mysql error: SERVER_GONE_ERROR";
case CR_SERVER_HANDSHAKE_ERR: return "mysql error:
SERVER_HANDSHAKE_ERR";
case CR_SERVER_LOST: return "mysql error: SERVER_LOST";
case CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR: return "mysql
error: SHARED_MEMORY_CONNECT_ABANDONED_ERROR";
case CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR: return "mysql error:
SHARED_MEMORY_CONNECT_ANSWER_ERROR";
case CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR: return "mysql
error: SHARED_MEMORY_CONNECT_FILE_MAP_ERROR";
case CR_SHARED_MEMORY_CONNECT_MAP_ERROR: return "mysql error:
SHARED_MEMORY_CONNECT_MAP_ERROR";
case CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR: return "mysql
error: SHARED_MEMORY_CONNECT_REQUEST_ERROR";
case CR_SHARED_MEMORY_CONNECT_SET_ERROR: return "mysql error:
SHARED_MEMORY_CONNECT_SET_ERROR";
case CR_SHARED_MEMORY_CONNECTION: return "mysql error:
SHARED_MEMORY_CONNECTION";
case CR_SHARED_MEMORY_EVENT_ERROR: return "mysql error:
SHARED_MEMORY_EVENT_ERROR";
case CR_SHARED_MEMORY_FILE_MAP_ERROR: return "mysql error:
SHARED_MEMORY_FILE_MAP_ERROR";
case CR_SHARED_MEMORY_MAP_ERROR: return "mysql error:
SHARED_MEMORY_MAP_ERROR";
case CR_SOCKET_CREATE_ERROR: return "mysql error:
SOCKET_CREATE_ERROR";
case CR_SSL_CONNECTION_ERROR: return "mysql error:
SSL_CONNECTION_ERROR";
case CR_TCP_CONNECTION: return "mysql error: TCP_CONNECTION";
case CR_UNKNOWN_ERROR: return "mysql error: UNKNOWN_ERROR";
case CR_UNKNOWN_HOST: return "mysql error: UNKNOWN_HOST";
case CR_UNSUPPORTED_PARAM_TYPE: return "mysql error:
UNSUPPORTED_PARAM_TYPE";
case CR_VERSION_ERROR: return "mysql error: VERSION_ERROR";
case CR_WRONG_HOST_INFO: return "mysql error: WRONG_HOST_INFO";
case CR_WRONG_LICENSE: return "mysql error: WRONG_LICENSE";
default: return "unspecified mysql error";
}
}
}
/*------------------------------------------------------------------------------*/
Make sure that the mysql file is now included in dbd -
cd $HP_SRC/srclib/apr-util
./buildconf #Otherwise the mysql file will not be found.
--------
//cd $HP_SRC/srclib/apr-util/build
//#Now we need to patch the bugged dbd.m4 file -- we can spend hours
reading the threads regarding this issue - if we can find them.
//wget -O dbd.patch
"http://marc2.theaimsgroup.com/?l=apr-dev&m=114384830419072&q=p3"
//cp dbd.m4 dbd.m4.orig
//patch -p0 dbd.m4 dbd.patch #(Use ctrl-d to skip the second patch.)
---------
#Apache devteam. don't like us using nph- anymore. But I live in the
real world and have legacy systems to look after.
#Only use this if you must use legacy nph- cgi scripts. It's unlikely
you need it
cd $HP_SRC/modules/generators
wget -O mod_cgi.patch
"http://issues.apache.org/bugzilla/attachment.cgi?id=17891"
cp mod_cgi.c mod_cgi.c.orig
patch mod_cgi.c mod_cgi.patch
#We also need to adjust mod_dbd to handle errors a little more
usefully...
cd $HP_SRC/modules/database
vi mod_dbd.c #rewrite the function dbd_construct as follows -
remember the magic vi command :set paste to stop autoindents
/*---------------------------- mod_dbd.c
----------------------------------*/
//Rewrite function dbd_construct at line 249 to 311 (lazy? :249 <cr>
63dd :set paste <cr> O and paste the following.. )
static apr_status_t dbd_construct(void **db, void *params, apr_pool_t
*pool)
{
svr_cfg *svr = (svr_cfg*) params;
ap_dbd_t *rec = apr_pcalloc(pool, sizeof(ap_dbd_t));
apr_status_t rv;
/* this pool is mostly so dbd_close can destroy the prepared stmts */
rv = apr_pool_create(&rec->pool, pool);
if (rv != APR_SUCCESS) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, pool,
"DBD: Failed to create memory pool");
}
/* The driver is loaded at config time now, so this just checks a hash.
* If that changes, the driver DSO could be registered to unload against
* our pool, which is probably not what we want. Error checking isn't
* necessary now, but in case that changes in the future ...
*/
rv = apr_dbd_get_driver(rec->pool, svr->name, &rec->driver);
switch (rv) {
case APR_ENOTIMPL:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: driver for %s not available", svr->name);
return rv;
case APR_EDSOOPEN:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: can't find driver for %s", svr->name);
return rv;
case APR_ESYMNOTFOUND:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: driver for %s is invalid or corrupted",
svr->name);
return rv;
default:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: mod_dbd not compatible with apr in
get_driver");
return rv;
case APR_SUCCESS:
break;
}
rv = apr_dbd_open(rec->driver, rec->pool, svr->params, &rec->handle);
switch (rv) {
case APR_EGENERAL:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: Can't connect to %s. Null returned using
parms: %s", svr->name,svr->params);
return rv;
default: {
const char *errmsg = apr_dbd_error(rec->driver, rec->handle, rv);
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: apr_dbd_open with parms (%s) failed:
%s",svr->params,(errmsg ? errmsg : "[???]"));
}
break;
case APR_SUCCESS:
break;
}
*db = rec;
rv = dbd_prepared_init(rec->pool, svr, rec);
if (rv != APR_SUCCESS) {
const char *errmsg = apr_dbd_error(rec->driver, rec->handle, rv);
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: dbd_prepared_init with parms (%s) failed:
%s",svr->params,(errmsg ? errmsg : "[???]"));
}
return rv;
}
/*------------------------------------------------------------------------------*/
#It may be a good idea to keep a copy of the files now.
cd $HP_SRC/..
tar -czf httpd-223adj.tgz httpd-2.2.3
#Now we need to move any current install directory (to stop some silly
logic from ruining the day. My install directory is eg /opt/httpd )
mv /opt/httpd /opt/httpd.x
cd $HP_SRC
./buildconf
vi config.layout #( Copy the 22 lines of the Apache Layout and call
it Opt - change just the prefix line to /opt/httpd ) (ONLY IF using
a custom install directory - eg /opt/httpd)
Now, because there are all sorts of issues finding the mysql include
and mysql library directories, prefix configure with CCFLAGS paths for
mysql..
CFLAGS="-DHAVE_MYSQL_H -I/opt/include/mysql -L/opt/lib/mysql"
./configure --prefix=/opt/httpd --enable-layout=Opt --enable-dbd
--with-ldap-lib=/usr/lib --with-ldap=ldap --with-mysql=/opt
--enable-access --enable-ldap --enable-actions --enable-alias
--enable-auth --enable-auth_dbm --enable-auth_digest
--enable-authn_dbd --enable-authnz-ldap --enable-cache --enable-cgi
--enable-dir --enable-disk_cache --enable-dumpio --enable-env
--enable-expires --enable-fastcgi --enable-file_cache --enable-headers
--enable-include --enable-info --enable-log_config
--enable-log_forensic --enable-logio --enable-mem_cache --enable-mime
--enable-mime_magic --enable-negotiation --enable-rewrite
--enable-setenvif --enable-ssl --enable-status --enable-unique_id
--enable-usertrack --enable-ldap --enable-version
--enable-vhost_alias --enable-so --enable-module=all --enable-shared=max
make
#Now move back the install directory (To keep conf files) the
following is a custom directory, but it doesn;'t have to be)
mv /opt/httpd.x /opt/httpd
make install
===========================================================
Configure - with example values.
===========================================================
httpd.conf
DBDriver mysql
#the Persist option fails in a major way for me, so I left it off.
DBDPersist Off
DBDMin 1
DBDKeep 1
DBDMax 1
#DBDExptime 10
#An example virt host:
Listen 10.0.0.2:80
<VirtualHost 10.0.0.2:80>
# [...]
DBDParams "dbname=mydatabase user=myuser"
# [...]
<Directory />
AuthType Basic
AuthName "Database access"
AuthBasicProvider dbd
Require valid-user
AuthDBDUserPWQuery "select password from httpuser where
active='on' and username = %s"
</Directory>
</VirtualHost>
------------------- The example mysql table httpuser looks like
-------------------------
CREATE TABLE `httuser` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(68) NOT NULL default '',
`password` varchar(250) default NULL,
`active` char(2) default 'on',
`email` varchar(128) default NULL,
PRIMARY KEY (`id`)
);
The password field must contain an encrypted password.
For instance if user 'joeblogs' has password 'unclebob' the following
query would suffice:
insert into httuser set
username='joeblogs',password=encrypt('unclebob'),active='on',email='[EMAIL PROTECTED]';
---------------------------------------------------------------------------------------------
===========================================================
Potential Error messages - You get these errors if you built httpd
with the function amends as above.
===========================================================
During build
dbd/apr_dbd_mysql.c:157: undefined reference to `mysql_stmt_fetch'
###Your libmysqlclient_r library isn't being found
mod_authnz_ldap.c:40:2: error: #error mod_authnz_ldap requires
APR-util to have LDAP support built in. To fix add --with-ldap to
./configure.
###Add the following to the ./configure line --with-ldap-lib=/usr/lib
--with-ldap=ldap_r
A 500 Error for a database protected area and the httpd error_log
says ....
[crit] (20014)Internal error: DBD: dbd_prepared_init with parms ()
failed: No database selected
###You need to add a DBDParams line to your virtual host
[crit] (20014)Internal error: DBD: dbd_prepared_init with parms
(dbname= mydatabase user= myuser) failed: Unknown column 'pssword' in
'field list'
###You have got your query wrong in the AuthDBDUserPWQuery line
[crit] (20014)Internal error: DBD: Can't connect to mysql. Null
returned using parms: dbname= mydatabase user= myuser
###The mysql server is probably NOT running. start it up and try again
###Or, if it is definitely running, check that the DBDParams 'dbname'
database exists.
###Or, if it is running, and the database exists, make sure that the
DBDParams 'user' user exists
###Test all of your DBDParams by accessing your database using it's
values - mysql -u<user> -p<pass> -D<dbname>
===========================================================
Further Thoughts
===========================================================
The above methods of error reporting keep errors away from the APR
library and give something meaningful in the error log also.
There is just one difference made to the mod_dbd API - which is that
apr_dbd_open now returns some errors in user_space, which is a good
way of dealing with error handling from the driver back to mod_dbd and
then back down via apr_dbd to retrieve the actual driver error. Nick
- I hope you can see the advantages of this approach.
===========================================================
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server
Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: [EMAIL PROTECTED]
" from the digest: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]