9.5 Configuring the PDBA ToolkitPDBA Toolkit configuration works the same way for both Unix and Win32. As we mentioned earlier, it's based upon a flat-file system.
We'll begin with the actual PDBA module and then continue with Connection Manager, the Password Server, and then the Password Client, each with its own configuration file, as shown in Figure 9-2. 9.5.1 PDBA Module ConfigurationThe PDBA module requires little configuration. It needs to know just two things:
The configuration file is PDBA_HOME/pdba.conf. The default contents are shown in Example 9-12. Example 9-12. pdba.conf — Default valuespackage pdbaparms; # who should mail be from? # does not need to be a valid address fromAddress => '[email protected]', ); Simply adjust the values to those for your own site. The mailServer parameter needs to be a valid mail server, but fromAddress can be a purely informational FROM: address. For example, if your domain is mydomain.com, you may want to simply set it to [email protected]. Or you can set it to a real address, if you prefer, to make potential replies easier. For instance, you could change the two key lines like this: mailServer => 'mail.mydomain.com', ... fromAddress => '[email protected]', When you're finished, check the file for syntactic correctness with the -cw switches: $ perl -cw pdba.conf 9.5.2 PDBA::CM Module ConfigurationWe've included the PDBA::CM (Connection Manager) module in the toolkit as an optional convenience, although we hope you'll want to set it up. The default PDBA_HOME/cm.conf is shown in Example 9-13. Example 9-13. cm.conf — CM configuration filepackage cmconf; ORACLE_BASE => '/u02/app/oracle', TNS_ADMIN => '/u02/app/oracle/product/8.1.7/network/admin' }, ts99 => { ORACLE_HOME => '/u02/app/oracle/product/8.1.7', ORACLE_BASE => '/u02/app/oracle', TNS_ADMIN => '/u02/app/oracle/product/8.1.7/network/admin' }, ); New database connection attempts made via PDBA::CM check for this file as follows: Setting the environment variables in this way means you get them right every time you connect to a target database — and you don't have to remember them. This is useful for scripts running from a system scheduler. The usual method used to run an ordinary Perl script is to wrap it. The wrapper sets the environment and then executes the script. Example 9-14 may look familiar to cron users. When running a script via the Unix cron scheduler, you normally must explicitly set all Oracle environment variables in the script. This is because scripts that run via cron do not inherit the environment variables that are normally set when logged into an interactive Unix account. Example 9-14. mybatch.sh — Setting up a Perl script in a wrapper script#!/bin/ksh
# Set the environment
export ORACLE_SID=ts01
export ORAENV_ASK=NO
. /usr/local/bin/oraenv $ORACLE_SID
# Execute the script
mybatch.pl -database -username ayn -password rand
Using PDBA::CM's configuration file eliminates the need for this kind of logic. You simply run the Perl script mybatch.pl directly via the system scheduler. For most situations, you set up cm.conf with just the default values and it works fine. You need only add specific database parameters as necessary. For Win32 users who need a simple default, edit the supplied cm.conf file to make it look like Example 9-15: Example 9-15. cm.conf — Basic CM configuration filepackage cmconf; use vars qw(%env); %env = ( default => { ORACLE_BASE => 'c:/oracle', TNS_ADMIN => 'c:/oracle/ora81/network/admin' }, ); Note that by default PDBA::CM ignores the cm.conf file if ORACLE_HOME is set. You can override that behavior with the FORCE_CONFIG attribute. You can also tell PDBA::CM to look beyond PDBA_HOME for a configuration file via PATH and FILE: my $dbh = new PDBA::CM ( DATABASE => $db, USERNAME => $username, PASSWORD => $password, FORCE_CONFIG=> 1, # Use the config file! :-) PATH => '/u02/app/oracle/config', FILE => 'oracle_cm.conf' ); 9.5.3 Password Server ConfigurationThe password server configuration file, PDBA_HOME/pwd.conf, contains five data structures:
We'll describe these in the following sections. 9.5.3.1 $port: Setting the TCP port for the password serverFirst you need to set the TCP port to be used by the password server. The setting in the file is currently 1579. You can change this to any other setting as follows: package pwd; use vars qw($port %pwd %instanceAuth %users %encryption ); $port=1579;
9.5.3.2 %pwd: Setting the passwords for password serverThis is where the passwords for each account are specified by machine or database server name, Oracle instance name, and account name, in a manner similar to the tnsnames.ora file structure. Example 9-16 is taken directly from the pwd.conf file included in the PDBA distribution. It contains passwords for the sys and system users, for the databases ts98 and ts99 on the watson server, and for database ts01 on the sherlock server. Example 9-16. pwd.conf%pwd = ( sherlock => { ts01 => { system => 'hoser', sys => 'hosehead' } }, watson => { ts99 => { system => 'wazzup', sys => 'wizard' }, ts98 => { system => 'whyn0t', sys => 'bcuz' } } ); This type of data structure is known as a hash of hashes (see Appendix A). The%pwd Perl hash contains a list of hash keys, in this case sherlock and watson. Each of these contains another Perl hash. Inside these hashes are the actual accounts and passwords. Here's what you need to do:
The method used to access this data may appear initially to be somewhat daunting, but scrutiny reveals that it's only a loop extracting servers, instances, usernames, and passwords, as Example 9-17 shows. Example 9-17. pwd.pl — Accessing data elements1 use PDBA::ConfigFile; 2 3 unless ( new PDBA::ConfigLoad( FILE => 'pwd.conf', PATH => './' ) ) 4 die "could not load pwd.conf\n"; 5 } 6 7 $t=0; 8 for my $server ( keys %pwd::pwd ) { 9 print "\t" x $t, "server: $server\n"; 10 $t++; 11 for my $instance ( keys %{$pwd::pwd{$server}} ) { 12 print "\t" x $t, "instance: $instance\n"; 13 $t++; 14 for my $user ( keys %{$pwd::pwd{$server}->{$instance}} ) { 15 print "\t" x $t, "username: $user", 16 "password: $pwd::pwd{$server}->{$instance}{$user}\n"; 17 } 18 $t--; 19 } 20 $t--; 21 } Here's what is going on.
Fortunately, PDBA::PWD takes care of all these technical difficulties. The only place this password structure is used is within the PDBA::PWD module. Retrieving a single password in a real-life script is actually fairly simple, as you can see here: my $password = $pwd::pwd{$server}->{$instance}{$user}; 9.5.3.3 %users: Setting up password server usersThe password server is only available for clients specified in the %users hash. These require a password. In case you're thinking "Oh great, another password to remember, let's use P4SSW0RDF1V3 or something," keep in mind that this one greatly reduces the number of other passwords you need to remember. Attempts to retrieve a password without a correct username and password will return no data. There are no informational messages declaring that the password or username is incorrect. Simply change the content for your own users in pwd.conf as follows: %users = ( andyd => 'perlgeek', # Needs to get out more! :-) jkstill => 'getalife', # Gotta turn off that computer! 8-) scott => 'tiger' ); 9.5.3.4 %encryption: Encrypting passwordsMost folks have become increasingly security-conscious lately, and rightly so. Sending clear text passwords over a network is now considered unacceptable practice, because the routing of TCP/IP packets over a multiply-redundant network makes it easy for unauthorized persons to compromise security. With that in mind, we designed the PDBA::PWD module to ensure that passwords are transmitted in encrypted form. To assist in the encryption, we've chosen the RC4 encryption algorithm available via the Crypt::RC4 Perl module. It is fast, easy to install, and available for both Unix and Win32 platforms.[9] All you need do is specify a string to use as the encryption key. This is done via the %encryption hash in PDBA/pwd.conf, shown in Example 9-18.
Example 9-18. pwd.conf — The %encryption hash%encryption = ( level => 'simple', # don't change this maxKeyLen => 56 ); There are three pieces of data in the %encryption hash, and the only one you need to be concerned with for now is key. Here are the requirements for key:
You may recognize our own key as being from J.R.R.Tolkien's The Lord of The Rings. It is too predictable for an actual encryption key, but demonstrates that the key can be anything you like. Change the key, and then check the configuration file with perl -cw pwd.conf. 9.5.3.5 %instanceAuth: Setting up per-account authorizationThe %instanceAuth hash provides an optional security feature. It can be used to limit which users are able to retrieve passwords for a particular account. If you have some sensitive accounts, you can limit access to them with %instanceAuth. Any accounts unspecified will be available to all authorized users. If the %instanceAuth structure is missing completely, all users found in %users have access to all passwords for all accounts. Consider Example 9-19: it's a subset of the servers found within Example 9-16. In the %pwd hash, there are two servers, with three Oracle instances, and two accounts in each instance, sys and system. This is a total of six passwords, and we want to filter their access as follows:
The entries in %instanceAuth shown in Example 9-19 create the required filter. The only entries needed are for accounts where you wish to limit the users who can retrieve passwords. Example 9-19. pwd.conf — Using the %instanceAuth structure%instanceAuth = ( sherlock => { ts01 => { system => [ qw(andyd jkstill) ], sys => [qw(andyd)] } }, watson => { ts99 => { sys => [qw( scott andyd )] } } ); Let's see what's going on here.
9.5.3.6 Securing pwd.confThe PDBA/pwd.conf file is sensitive, so you need to set Fort Knox file permissions enabling only authorized users to read or edit it. On Unix, this is done via chmod: $ chmod 640 pwd.conf
$ ls -la pwd.conf
-rw-r----- 1 oramon dba 8508 Apr 14 07:27 pwd.conf
Setting the permission to 0640 allows users belonging to the DBA group to view the file, while only the file owner can edit it. Win32 security is different. Setting the proper permissions on Win32 is a point-and-click operation that works as follows:
Figure 9-3. Setting file security on Win329.5.3.7 Running the password server on UnixThose on Unix are now ready to run the password server via the command line as follows: $ pwd.pl That's all there is to it. The password server has landed. You can verify its operation via a ps command, using either the -fea or -aux switches, depending on your own Unix flavor: $ ps -fea | grep pwd | grep -v grep oramon 25771 1 0 08:12 ? 00:00:00 perl /usr/bin/pwd.pl $ ps -aux | grep pwd | grep -v grep oramon 25771 0.0 0.8 5668 4540 ? S 08:12 0:00 perl /usr/bin/pwd.pl 9.5.3.8 Running the password server on Win32Running the password server on Win32 is slightly more involved. You need to install the pwd.pl script as a service. Thanks to the Win32::Daemon module, this is straightforward.
Example 9-20. pwd_service.pl — Install password server service on Win32use File::Basename; use Getopt::Long; use Win32::Daemon; my %optctl=( ); my $perlExe = $EXECUTABLE_NAME; # build a path to pwd.pl my @dirs = File::Spec->splitdir($perlPath); %Hash = ( name => 'Oracle_PWD_Server', display => 'Oracle_PWD_Server', path => $perlExe, user => '', # Unnecessary, for this particular application. pwd => '', # Unnecessary, for this particular application. parameters => $pwdPath ); unless ( GetOptions(\%optctl, "install!", "remove!" ) ) { usage(1); } if ( $optctl{remove} ) { if( Win32::Daemon::DeleteService( $Hash{name} ) ) { print "Successfully removed.\n"; } else { print "Failed to remove service: " . GetError( ) . "\n"; } } print "finished.\n"; sub GetError { return( Win32::FormatMessage( Win32::Daemon::GetLastError( ) ) ); } If you should happen to have a nonstandard installation of Perl, you can use Table 9-11 (password server parameters) as a guide in editing the attributes of the %Hash data structure in pwd.pl.
9.5.3.9 Starting the serviceNow all you need do is run Win32 Service Manager to start the service. There are two different paths, shown in Table 9-12, depending on which Win32 platform you're on.
9.5.4 Password Client ConfigurationWe're in the home stretch now. All that's left is to set up the password client pwc.pl and give it a whirl. As with the password server, the client program uses a configuration file. Unlike the server, the configuration file is optional. We hope you'll want to use it though, as it makes the client program considerably easier to use. Bring up PDBA_HOME/pwc.conf in your favorite editor and take a look at it. The contents of the file, as it appears in the PDBA distribution, are shown in Example 9-21. Example 9-21. pwc.conf — Password client configurationpackage pwc; use vars qw(%optctl); %optctl = ( host => 'sherlock', port => 1579, machine => 'watson', instance => 'ts98', username => 'sys', my_username => 'scott', my_password => 'tiger', key => 'One Ring to bring them all and in the darkness bind them'); All of the command-line options except -conf can be specified in this file, thus avoiding long command-line entries and the use of clear text passwords (which is what we were trying to avoid in the first place). It assumes that the configuration file name is PDBA_HOME/pwc.conf, unless another name is specified directly on the command line with the -conf filename option. Typing pwc.pl -help on the command line displays all of the options as a useful reminder of what you'll need to input. Table 9-13 summarizes these options.
Note the following:
One common approach is to create a configuration file specifying the password server and port, your username and password, and the key used to encrypt data across the network. With those options present in the configuration file, you would only need to specify the configuration file, database server machine, database instance, and account name on the command line. For example, your command line would look something like this when you're retrieving the password for account system in instance vdr on database server elfenwood: $ pwc.pl -machine elfenwood -instance VDR -username system -conf pwc.conf To connect to a different host's password server, you would modify the command line as follows: $ pwc.pl -host mycroft -machine elfenwood -instance VDR \ -username system -conf pwc.conf Example 9-22 is an example of connecting to an alternate password server. In this case the password server on Unix server sherlock was unavailable, so a connection was made to the alternate password server on the Win32 server mycroft. Example 9-22. Connecting to an alternate password server%oramon > pwc.pl %oramon > Let's see what's happening in Example 9-22.
The pwc.pl script is useful in demonstrating how to use the password server in your own scripts. It is also useful as a standalone script for retrieving passwords at the command line. On Unix systems, it may even be used to retrieve passwords and use them directly as input. This example demonstrates its use in logging in to SQL*Plus without any need to type the password: sqlplus system/$(pwc.pl -machine sherlock -database ts01 -username system) This uses the Korn shell's $( ) subshell mechanism, returning the output of pwc.pl to the current shell. Alas, we do not know of an equivalent subshell mechanism on the Win32 platform. 9.5.4.1 Using PDBA::PWC in your own Perl scriptsThe password client module is available for use in your own Perl scripts as well. Here are the basic pieces you'll need to include in order to connect to the password server: use PDBA::PWC; my $client = new PDBA::PWC( host => $remote_host, port => $remote_port ); $client->authenticate( username => $myusername, password => $mypassword, key => $key, debug => $optctl{debug} ); my $password = $client->getPassword( machine => $machine, instance => $instance, username => $username, key => $key ); This completes the toolkit installation. In the following chapters, we'll see what it can do for us. |