5 @ISA @EXPORT_OK $cgi $dbh $freeside_uid $user
6 $conf_dir $secrets $datasrc $db_user $db_pass %callback @callback
7 $driver_name $AutoCommit $callback_hack
10 getsecrets cgisetotaker
13 use Carp qw(carp croak cluck confess);
19 @EXPORT_OK = qw(checkeuid checkruid cgisuidsetup adminsuidsetup forksuidsetup
20 getotaker dbh datasrc getsecrets driver_name myconnect );
22 $freeside_uid = scalar(getpwnam('freeside'));
24 $conf_dir = "%%%FREESIDE_CONF%%%/";
26 $AutoCommit = 1; #ours, not DBI
31 FS::UID - Subroutines for database login and assorted other stuff
35 use FS::UID qw(adminsuidsetup cgisuidsetup dbh datasrc getotaker
41 $dbh = cgisuidsetup($cgi);
47 $driver_name = driver_name;
51 Provides a hodgepodge of subroutines.
57 =item adminsuidsetup USER
59 Sets the user to USER (see config.html from the base documentation).
60 Cleans the environment.
61 Make sure the script is running as freeside, or setuid freeside.
62 Opens a connection to the database.
63 Swaps real and effective UIDs.
64 Runs any defined callbacks (see below).
65 Returns the DBI database handle (usually you don't need this).
70 $dbh->disconnect if $dbh;
78 if ( $FS::CurrentUser::upgrade_hack ) {
79 $user = 'fs_bootstrap';
81 croak "fatal: adminsuidsetup called without arguements" unless $user;
83 $user =~ /^([\w\-\.]+)$/ or croak "fatal: illegal user $user";
87 $ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin';
88 $ENV{'SHELL'} = '/bin/sh';
89 $ENV{'IFS'} = " \t\n";
92 $ENV{'BASH_ENV'} = '';
94 croak "Not running uid freeside!" unless checkeuid();
96 if ( $FS::CurrentUser::upgrade_hack && $olduser ) {
97 $dbh = &myconnect($olduser);
102 use FS::Schema qw(reload_dbdef);
103 reload_dbdef("$conf_dir/dbdef.$datasrc")
104 unless $FS::Schema::setup_hack;
106 FS::CurrentUser->load_user($user);
108 unless($callback_hack) {
109 foreach ( keys %callback ) {
111 # breaks multi-database installs # delete $callback{$_}; #run once
114 &{$_} foreach @callback;
121 DBI->connect( getsecrets(@_), { 'AutoCommit' => 0,
123 'ShowErrorStatement' => 1,
126 or die "DBI->connect error: $DBI::errstr\n";
129 =item install_callback
131 A package can install a callback to be run in adminsuidsetup by passing
132 a coderef to the FS::UID->install_callback class method. If adminsuidsetup has
133 run already, the callback will also be run immediately.
135 $coderef = sub { warn "Hi, I'm returning your call!" };
136 FS::UID->install_callback($coderef);
138 install_callback FS::UID sub {
139 warn "Hi, I'm returning your call!"
144 sub install_callback {
146 my $callback = shift;
147 push @callback, $callback;
148 &{$callback} if $dbh;
151 =item cgisuidsetup CGI_object
153 Takes a single argument, which is a CGI (see L<CGI>) or Apache (see L<Apache>)
154 object (CGI::Base is depriciated). Runs cgisetotaker and then adminsuidsetup.
160 if ( $cgi->isa('CGI::Base') ) {
161 carp "Use of CGI::Base is depriciated";
162 } elsif ( $cgi->isa('Apache') ) {
164 } elsif ( ! $cgi->isa('CGI') ) {
165 croak "fatal: unrecognized object $cgi";
168 adminsuidsetup($user);
173 Returns the CGI (see L<CGI>) object.
178 carp "warning: \$FS::UID::cgi isa Apache" if $cgi->isa('Apache');
184 Returns the DBI database handle.
194 Returns the DBI data source.
204 Returns just the driver name portion of the DBI data source.
209 return $driver_name if defined $driver_name;
210 $driver_name = ( split(':', $datasrc) )[1];
214 croak "suidsetup depriciated";
219 Returns the current Freeside user.
229 Sets and returns the CGI REMOTE_USER. $cgi should be defined as a CGI.pm
230 object (see L<CGI>) or an Apache object (see L<Apache>). Support for CGI::Base
231 and derived classes is depriciated.
236 if ( $cgi && $cgi->isa('CGI::Base') && defined $cgi->var('REMOTE_USER')) {
237 carp "Use of CGI::Base is depriciated";
238 $user = lc ( $cgi->var('REMOTE_USER') );
239 } elsif ( $cgi && $cgi->isa('CGI') && defined $cgi->remote_user ) {
240 $user = lc ( $cgi->remote_user );
241 } elsif ( $cgi && $cgi->isa('Apache') ) {
242 $user = lc ( $cgi->connection->user );
244 die "fatal: Can't get REMOTE_USER! for cgi $cgi - you need to setup ".
245 "Apache user authentication as documented in httemplate/docs/install.html";
252 Returns true if effective UID is that of the freeside user.
257 ( $> == $freeside_uid );
262 Returns true if the real UID is that of the freeside user.
267 ( $< == $freeside_uid );
270 =item getsecrets [ USER ]
272 Sets the user to USER, if supplied.
273 Sets and returns the DBI datasource, username and password for this user from
274 the `/usr/local/etc/freeside/mapsecrets' file.
279 my($setuser) = shift;
280 $user = $setuser if $setuser;
282 if ( -e "$conf_dir/mapsecrets" ) {
283 die "No user!" unless $user;
284 my($line) = grep /^\s*($user|\*)\s/,
285 map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/mapsecrets");
286 confess "User $user not found in mapsecrets!" unless $line;
287 $line =~ /^\s*($user|\*)\s+(.*)$/;
289 die "Illegal mapsecrets line for user?!" unless $secrets;
291 # no mapsecrets file at all, so do the default thing
292 $secrets = 'secrets';
295 ($datasrc, $db_user, $db_pass) =
296 map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/$secrets")
297 or die "Can't get secrets: $conf_dir/$secrets: $!\n";
299 ($datasrc, $db_user, $db_pass);
306 Warning: this interface is (still) likely to change in future releases.
308 New (experimental) callback interface:
310 A package can install a callback to be run in adminsuidsetup by passing
311 a coderef to the FS::UID->install_callback class method. If adminsuidsetup has
312 run already, the callback will also be run immediately.
314 $coderef = sub { warn "Hi, I'm returning your call!" };
315 FS::UID->install_callback($coderef);
317 install_callback FS::UID sub {
318 warn "Hi, I'm returning your call!"
321 Old (deprecated) callback interface:
323 A package can install a callback to be run in adminsuidsetup by putting a
324 coderef into the hash %FS::UID::callback :
326 $coderef = sub { warn "Hi, I'm returning your call!" };
327 $FS::UID::callback{'Package::Name'} = $coderef;
331 Too many package-global variables.
335 No capabilities yet. When mod_perl and Authen::DBI are implemented,
336 cgisuidsetup will go away as well.
338 Goes through contortions to support non-OO syntax with multiple datasrc's.
340 Callbacks are (still) inelegant.
344 L<FS::Record>, L<CGI>, L<DBI>, config.html from the base documentation.