5 @ISA @EXPORT_OK $cgi $freeside_uid $user $conf_dir $cache_dir
6 $secrets $datasrc $db_user $db_pass $schema $dbh $driver_name
7 $AutoCommit %callback @callback
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%%%/";
25 $cache_dir = "%%%FREESIDE_CACHE%%%";
27 $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 foreach ( keys %callback ) {
110 # breaks multi-database installs # delete $callback{$_}; #run once
113 &{$_} foreach @callback;
119 my $handle = DBI->connect( getsecrets(@_), { 'AutoCommit' => 0,
121 'ShowErrorStatement' => 1,
124 or die "DBI->connect error: $DBI::errstr\n";
127 use DBIx::DBSchema::_util qw(_load_driver ); #quelle hack
128 my $driver = _load_driver($handle);
129 if ( $driver =~ /^Pg/ ) {
130 no warnings 'redefine';
131 eval "sub DBIx::DBSchema::DBD::${driver}::default_db_schema {'$schema'}";
139 =item install_callback
141 A package can install a callback to be run in adminsuidsetup by passing
142 a coderef to the FS::UID->install_callback class method. If adminsuidsetup has
143 run already, the callback will also be run immediately.
145 $coderef = sub { warn "Hi, I'm returning your call!" };
146 FS::UID->install_callback($coderef);
148 install_callback FS::UID sub {
149 warn "Hi, I'm returning your call!"
154 sub install_callback {
156 my $callback = shift;
157 push @callback, $callback;
158 &{$callback} if $dbh;
161 =item cgisuidsetup CGI_object
163 Takes a single argument, which is a CGI (see L<CGI>) or Apache (see L<Apache>)
164 object (CGI::Base is depriciated). Runs cgisetotaker and then adminsuidsetup.
170 if ( $cgi->isa('CGI::Base') ) {
171 carp "Use of CGI::Base is depriciated";
172 } elsif ( $cgi->isa('Apache') ) {
174 } elsif ( ! $cgi->isa('CGI') ) {
175 croak "fatal: unrecognized object $cgi";
178 adminsuidsetup($user);
183 Returns the CGI (see L<CGI>) object.
188 carp "warning: \$FS::UID::cgi isa Apache" if $cgi->isa('Apache');
194 Returns the DBI database handle.
204 Returns the DBI data source.
214 Returns just the driver name portion of the DBI data source.
219 return $driver_name if defined $driver_name;
220 $driver_name = ( split(':', $datasrc) )[1];
224 croak "suidsetup depriciated";
229 Returns the current Freeside user.
239 Sets and returns the CGI REMOTE_USER. $cgi should be defined as a CGI.pm
240 object (see L<CGI>) or an Apache object (see L<Apache>). Support for CGI::Base
241 and derived classes is depriciated.
246 if ( $cgi && $cgi->isa('CGI::Base') && defined $cgi->var('REMOTE_USER')) {
247 carp "Use of CGI::Base is depriciated";
248 $user = lc ( $cgi->var('REMOTE_USER') );
249 } elsif ( $cgi && $cgi->isa('CGI') && defined $cgi->remote_user ) {
250 $user = lc ( $cgi->remote_user );
251 } elsif ( $cgi && $cgi->isa('Apache') ) {
252 $user = lc ( $cgi->connection->user );
254 die "fatal: Can't get REMOTE_USER! for cgi $cgi - you need to setup ".
255 "Apache user authentication as documented in httemplate/docs/install.html";
262 Returns true if effective UID is that of the freeside user.
267 ( $> == $freeside_uid );
272 Returns true if the real UID is that of the freeside user.
277 ( $< == $freeside_uid );
280 =item getsecrets [ USER ]
282 Sets the user to USER, if supplied.
283 Sets and returns the DBI datasource, username and password for this user from
284 the `/usr/local/etc/freeside/mapsecrets' file.
289 my($setuser) = shift;
290 $user = $setuser if $setuser;
291 my($conf) = new FS::Conf $conf_dir;
293 if ( $conf->exists('mapsecrets') ) {
294 die "No user!" unless $user;
295 my($line) = grep /^\s*($user|\*)\s/, $conf->config('mapsecrets');
296 confess "User $user not found in mapsecrets!" unless $line;
297 $line =~ /^\s*($user|\*)\s+(.*)$/;
299 die "Illegal mapsecrets line for user?!" unless $secrets;
301 # no mapsecrets file at all, so do the default thing
302 $secrets = 'secrets';
305 ($datasrc, $db_user, $db_pass, $schema) = $conf->config($secrets)
306 or die "Can't get secrets: $secrets: $!\n";
310 $FS::Conf::default_dir = $conf_dir. "/conf.$datasrc";
312 ($datasrc, $db_user, $db_pass);
319 Warning: this interface is (still) likely to change in future releases.
321 New (experimental) callback interface:
323 A package can install a callback to be run in adminsuidsetup by passing
324 a coderef to the FS::UID->install_callback class method. If adminsuidsetup has
325 run already, the callback will also be run immediately.
327 $coderef = sub { warn "Hi, I'm returning your call!" };
328 FS::UID->install_callback($coderef);
330 install_callback FS::UID sub {
331 warn "Hi, I'm returning your call!"
334 Old (deprecated) callback interface:
336 A package can install a callback to be run in adminsuidsetup by putting a
337 coderef into the hash %FS::UID::callback :
339 $coderef = sub { warn "Hi, I'm returning your call!" };
340 $FS::UID::callback{'Package::Name'} = $coderef;
344 Too many package-global variables.
348 No capabilities yet. When mod_perl and Authen::DBI are implemented,
349 cgisuidsetup will go away as well.
351 Goes through contortions to support non-OO syntax with multiple datasrc's.
353 Callbacks are (still) inelegant.
357 L<FS::Record>, L<CGI>, L<DBI>, config.html from the base documentation.