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