kayak9630 has asked for the wisdom of the Perl Monks concerning the following question:

Great and wise purveyors of Perl wisdom, I beg your assistance once again in this simple but important matter.

I have a series of Perl CGI scripts that access a database for various useful reasons and would like to store the database connection information (i.e. server, database, username, password) in a safe place and reference them in such a way that I only need to change one file in order to point all of the scripts to the correct server.

What is the safest way to accomplish this? Thank you so much - I am learning much!
  • Comment on Seeking efficient and safe way to store database connection information

Replies are listed 'Best First'.
Re: Seeking efficient and safe way to store database connection information
by valdez (Monsignor) on Jul 26, 2004 at 22:28 UTC

    There are several options; DBIx::Password is one of them, but I prefer to reinvent wheels and use an hand-made configuration singleton. I keep all the configurable values in a file readable by Config::General and limited by Class::Singleton:

    #configuration file <system> dsn dbi:Oracle:dbname username dbuser password dbpwd <environment> ORACLE_HOME /ora92/product/9.2.1.0 </environment> </system>
    Values are accessible using paths inside configuration file; for example, the following code is used to connect to an Oracle database:
    my $conf = Configuration::Singleton->instance; my $address = $conf->value('system/dsn'); my $user = $conf->value('system/username'); my $pwd = $conf->value('system/password'); my $environment = $conf->value('system/environment'); while ( my ($variable, $value) = each %$environment ) { $ENV{ uc($variable) } = $value; } my $dbh = DBI->connect( $address, $user, $pwd, { RaiseError => 1, AutoCommit => 0 } ) or die "$DBI::errstr"; $dbh->{FetchHashKeyName} = 'NAME_lc';

    The summary is: use some sort of configuration method. BTW, if you are using MySQL please note that it accepts the name of a configuration file in the connect string, see this trick told to me by gmax for a useful example.
    Remeber to keep your configuration files out of the document root and restrict access to them.

    HTH, Valerio

Re: Seeking efficient and safe way to store database connection information
by dragonchild (Archbishop) on Jul 27, 2004 at 02:22 UTC
    I'm a big fan of Config::ApacheFormat. This allows you to set a bunch of other stuff in one configuration file.

    The biggest thing to make sure of is that the configuration files are writeable only by one user and readable only by one group. That group should only have as members those application users which will need to read the connection information. For example, I have a www user whose only purpose is to run the Apache process. That user would be in a group called dbi_user. The password file would be permissions 640 and owned by me. If my username is dragonchild, the permissions would be:

    • dragonchild can read and write the file
    • Members of the dbi_user group can read the file
    • No-one else even knows the file exists.

    Ideally, the directory this file is in would be 770, with the same user/group ownership.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: Seeking efficient and safe way to store database connection information
by bgreenlee (Friar) on Jul 27, 2004 at 06:23 UTC

    I usually just write a little MyDB module that has one method: connect. Then any script that wants to use the database just does:

    use MyDB; my $dbh = MyDB::connect();

    This method will also let you add connection pooling later without changing any code other than the MyDB module.

    Here's a sample MyDB module with a connect method that lets you override any of the default connect parameters (note: I just rewrote a good chunk of this as I posted it, and haven't tested it, so...):

    package MyDB; use DBI; my %Default = ( database => 'mydatabase', driver => 'mysql', hostname => 'localhost', port => 3306, username => 'someuser', password => 'topsecret', options => { AutoCommit => 1, RaiseError => 0, } ); sub connect { my %params = @_; my $connect_str=sprintf("dbi:%s:database=%s;hostname=%s;port=%s", $params{driver} || $Default{driver}, $params{database} || $Default{database}, $params{hostname} || $Default{hostname}, $params{port} || $Default{port}); return DBI->connect($connect_str, $params{username} || $Default{username}, $params{password} || $Default{password}, $params{options} || $Default{options} ); } 1;

    Brad

Re: Seeking efficient and safe way to store database connection information
by Plankton (Vicar) on Jul 26, 2004 at 22:12 UTC
    This has been asked before. Here's a least one node:DBI & CGI Security

    Plankton: 1% Evil, 99% Hot Gas.