su —
Attribute | Pos. | Req. | Default | Description |
---|---|---|---|---|
username | user | ||||
profile | ||||
admin | ||||
create_user | ||||
exit | ||||
interpolate | 0 | interpolate output? | ||
hide | 0 | Hide the tag return value? |
Interchange 5.9.0:
Source: code/UI_Tag/su.coretag
Lines: 188
# Copyright 2002-2007 Interchange Development Group and others # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. See the LICENSE file for details. # # $Id: su.coretag,v 1.8 2007-03-30 23:40:54 pajamian Exp $ UserTag su Description Switch User Tag for catalog superuser UserTag su Order username UserTag su attrAlias user username UserTag su addAttr UserTag su Version $Revision: 1.8 $ UserTag su Routine <<EOR sub { my ($user, $opt) = @_; use vars qw/$Session $Tag $ready_safe $Scratch/; # Note: If adding any new %$opt keys, make sure to also add them to # the list of options to be stripped before passing the remainder # to tag userdb; search below for $new_user. $opt->{profile} = 'ui' if $opt->{admin} and ! $opt->{profile}; my $u; if($opt->{profile}) { $u = $Vend::Cfg->{UserDB_repository}{$opt->{profile}}; } else { $u = $Vend::Cfg->{UserDB}; } if(! $u) { my $place = $opt->{profile} || 'default'; ::logError("Can't find UserDB repository, profile '%s'", $place); return undef; } my $table = $u->{database} || 'userdb'; my $ufield = $u->{user_field} || 'username'; my $going_to_admin = $u->{admin} || $opt->{admin}; #::logDebug("user table=$table ufield=$ufield"); if ($opt->{create_user}) { # these settings must be done before any access to the table $Vend::WriteDatabase{$table} = 1; } my $super = $Tag->if_mm('super'); my $former = $Vend::username; if($user and $going_to_admin and ! $super) { ::logError("attempt to su to admin user %s by non-super user %s", $user, $former, ); return undef; } elsif($user and ! $Vend::admin) { ::logError("attempt to su to user %s by non-admin user %s", $user, $former, ); return undef; } my $dir = "$Global::ConfDir/tmp"; if (! -d $dir) { if(-e $dir) { logGlobal("Global tmp directory exists as file, aborting su"); return undef; } File::Path::mkpath($dir); } if($opt->{exit}) { if(! $Session->{su}) { logError("attempt to return to superuser without saved session."); return; } my $string = delete $Session->{su}; my $key = $Tag->read_cookie({ name => 'MV_SU_KEY'}) or do { logError("no session key in cookie, cannot exit"); return; }; my $fn = "$dir/$Session->{id}"; open(MDCHECK, "< $fn") or do { logError("no saved session key in %s, cannot exit", $fn); return; }; my $rand = <MDCHECK>; close MDCHECK; if(generate_key($rand . $string) ne $key) { logError("mismatched session key with saved session, cannot exit"); return; } my $former = $Session->{username}; ## Authenticated undef $Vend::Session; undef $Session; $Vend::Session = $ready_safe->reval($string); $Session = $Vend::Session; delete $Session->{su}; $Vend::admin = $Vend::Session->{admin}; $Vend::username = $Vend::Session->{username}; $Tag->if_mm('logged_in') and logError( "Admin user %s returned from login as %s", $Session->{username}, $former, ) and return 1; return; } elsif ($user) { my $new_user; if(! $Tag->data($table, $ufield, $user) ) { if ($opt->{create_user}) { $new_user = 1; } else { $Scratch->{ui_error} = errmsg("attempt to su to non-existent user %s", $user); return undef; } } my $rand = random_string(); my $sess = uneval_it($Session); #::logDebug("sess is $sess"); my $sesskey = generate_key($rand . $sess); open(MDIT, "> $dir/$Session->{id}") or die errmsg("Can't create check file for su: %s\n", $!); print MDIT $rand; close MDIT; $Tag->set_cookie( { name => 'MV_SU_KEY', value => $sesskey } ); my $former = $Session->{username}; undef $Vend::admin; undef $Vend::superuser; undef $Vend::UI_entry; Vend::Session::init_session(); $Session = $Vend::Session; if ($new_user) { # pass on any non-su options to userdb tag my $newopt = { %$opt }; delete @{$newopt}{qw( admin exit create_user )}; $newopt->{username} = $user; my $result = $Tag->userdb('new_account', $newopt); unless ($result) { my $error = errmsg("Failed to create new user '%s' in su tag", $user); logError($error); $Scratch->{ui_error} = $error; return undef; } $Session->{su} = $sess; } else { $Vend::username = $Session->{username} = $user; $Vend::admin = $Session->{admin} = $going_to_admin; $Session->{logged_in} = 1; $Session->{su} = $sess; $Tag->userdb('load'); } ## Reconnect session variables Vend::Interpolate::init_calc; my $dest = $Tag->if_mm('logged_in') ? 'admin user' : 'regular user'; logError( "superuser %s switched user to %s %s", $former, $dest, $Session->{username}, ); return 1; } else { ::logError("unknown su operation: " . uneval_it($opt)); return undef; } } EOR