1 # Copyright 2002-2007 Interchange Development Group and others
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version. See the LICENSE file for details.
8 # $Id: su.coretag,v 1.8 2007-03-30 23:40:54 pajamian Exp $
10 UserTag su Description Switch User Tag for catalog superuser
11 UserTag su Order username
12 UserTag su attrAlias user username
14 UserTag su Version $Revision: 1.8 $
15 UserTag su Routine <<EOR
17 my ($user, $opt) = @_;
18 use vars qw/$Session $Tag $ready_safe $Scratch/;
20 # Note: If adding any new %$opt keys, make sure to also add them to
21 # the list of options to be stripped before passing the remainder
22 # to tag userdb; search below for $new_user.
24 $opt->{profile} = 'ui' if $opt->{admin} and ! $opt->{profile};
28 $u = $Vend::Cfg->{UserDB_repository}{$opt->{profile}};
31 $u = $Vend::Cfg->{UserDB};
35 my $place = $opt->{profile} || 'default';
36 ::logError("Can't find UserDB repository, profile '%s'", $place);
39 my $table = $u->{database} || 'userdb';
40 my $ufield = $u->{user_field} || 'username';
41 my $going_to_admin = $u->{admin} || $opt->{admin};
42 #::logDebug("user table=$table ufield=$ufield");
44 if ($opt->{create_user}) {
45 # these settings must be done before any access to the table
46 $Vend::WriteDatabase{$table} = 1;
49 my $super = $Tag->if_mm('super');
50 my $former = $Vend::username;
52 if($user and $going_to_admin and ! $super) {
53 ::logError("attempt to su to admin user %s by non-super user %s",
59 elsif($user and ! $Vend::admin) {
60 ::logError("attempt to su to user %s by non-admin user %s",
67 my $dir = "$Global::ConfDir/tmp";
70 logGlobal("Global tmp directory exists as file, aborting su");
73 File::Path::mkpath($dir);
77 if(! $Session->{su}) {
78 logError("attempt to return to superuser without saved session.");
81 my $string = delete $Session->{su};
82 my $key = $Tag->read_cookie({ name => 'MV_SU_KEY'})
84 logError("no session key in cookie, cannot exit");
87 my $fn = "$dir/$Session->{id}";
88 open(MDCHECK, "< $fn")
90 logError("no saved session key in %s, cannot exit", $fn);
95 if(generate_key($rand . $string) ne $key) {
96 logError("mismatched session key with saved session, cannot exit");
100 my $former = $Session->{username};
102 undef $Vend::Session;
104 $Vend::Session = $ready_safe->reval($string);
105 $Session = $Vend::Session;
106 delete $Session->{su};
107 $Vend::admin = $Vend::Session->{admin};
108 $Vend::username = $Vend::Session->{username};
109 $Tag->if_mm('logged_in')
111 "Admin user %s returned from login as %s",
112 $Session->{username},
120 if(! $Tag->data($table, $ufield, $user) ) {
121 if ($opt->{create_user}) {
125 $Scratch->{ui_error} = errmsg("attempt to su to non-existent user %s", $user);
130 my $rand = random_string();
131 my $sess = uneval_it($Session);
132 #::logDebug("sess is $sess");
133 my $sesskey = generate_key($rand . $sess);
135 open(MDIT, "> $dir/$Session->{id}")
136 or die errmsg("Can't create check file for su: %s\n", $!);
139 $Tag->set_cookie( { name => 'MV_SU_KEY', value => $sesskey } );
140 my $former = $Session->{username};
143 undef $Vend::superuser;
144 undef $Vend::UI_entry;
146 Vend::Session::init_session();
147 $Session = $Vend::Session;
150 # pass on any non-su options to userdb tag
151 my $newopt = { %$opt };
152 delete @{$newopt}{qw( admin exit create_user )};
153 $newopt->{username} = $user;
154 my $result = $Tag->userdb('new_account', $newopt);
156 my $error = errmsg("Failed to create new user '%s' in su tag", $user);
158 $Scratch->{ui_error} = $error;
161 $Session->{su} = $sess;
164 $Vend::username = $Session->{username} = $user;
165 $Vend::admin = $Session->{admin} = $going_to_admin;
166 $Session->{logged_in} = 1;
167 $Session->{su} = $sess;
168 $Tag->userdb('load');
171 my $dest = $Tag->if_mm('logged_in') ? 'admin user' : 'regular user';
173 "superuser %s switched user to %s %s",
176 $Session->{username},
181 ::logError("unknown su operation: " . uneval_it($opt));