previously, users could create sessions under wrong uids or delete sessions from other users. This patch implements prevents this by checking the userid of the caller with the session id. --- x2goserver/lib/x2gosqlitewrapper.pl | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/x2goserver/lib/x2gosqlitewrapper.pl b/x2goserver/lib/x2gosqlitewrapper.pl index 70ee4e5..8483f32 100755 --- a/x2goserver/lib/x2gosqlitewrapper.pl +++ b/x2goserver/lib/x2gosqlitewrapper.pl @@ -25,14 +25,14 @@ use strict; use DBI; use POSIX; -# retrieve home dir of x2gouser +# retrieve home dir of x2gouser my $x2gouser='x2gouser'; my ($uname, $pass, $uid, $pgid, $quota, $comment, $gcos, $homedir, $shell, $expire) = getpwnam($x2gouser); my $dbfile="$homedir/x2go_sessions"; # retrieve account data of real user my $realuser=$<; -my ($uname, $pass, $uid, $pgid, $quota, $comment, $gcos, $homedir, $shell, $expire) = getpwnam($realuser); +my ($uname, $pass, $uid, $pgid, $quota, $comment, $gcos, $homedir, $shell, $expire) = getpwuid($realuser); my $dbh=DBI->connect("dbi:SQLite:dbname=$dbfile","","",{AutoCommit => 1}) or die $_; @@ -81,6 +81,7 @@ elsif($cmd eq "listsessionsroot_all") elsif($cmd eq "getmounts") { my $sid=shift or die "argument \"session_id\" missed"; + check_user($sid); my @strings; my $sth=$dbh->prepare("select client, path from mounts where session_id=?"); $sth->execute($sid)or die; @@ -91,6 +92,7 @@ elsif($cmd eq "deletemount") { my $sid=shift or die "argument \"session_id\" missed"; my $path=shift or die "argument \"path\" missed"; + check_user($sid); my $sth=$dbh->prepare("delete from mounts where session_id=? and path=?"); $sth->execute($sid, $path); $sth->finish(); @@ -101,6 +103,7 @@ elsif($cmd eq "insertmount") my $sid=shift or die "argument \"session_id\" missed"; my $path=shift or die "argument \"path\" missed"; my $client=shift or die "argument \"client\" missed"; + check_user($sid); my $sth=$dbh->prepare("insert into mounts (session_id,path,client) values (?, ?, ?)"); $sth->execute($sid, $path, $client); if(!$sth->err()) @@ -115,6 +118,7 @@ elsif($cmd eq "insertsession") my $display=shift or die "argument \"display\" missed"; my $server=shift or die "argument \"server\" missed"; my $sid=shift or die "argument \"session_id\" missed"; + check_user($sid); my $sth=$dbh->prepare("insert into sessions (display,server,uname,session_id, init_time, last_time) values (?, ?, ?, ?, datetime('now','localtime'), datetime('now','localtime'))"); $sth->execute($display, $server, $realuser, $sid) or die $_; @@ -131,6 +135,7 @@ elsif($cmd eq "createsession") my $snd_port=shift or die"argument \"snd_port\" missed"; my $fs_port=shift or die"argument \"fs_port\" missed"; my $sid=shift or die "argument \"session_id\" missed"; + check_user($sid); my $sth=$dbh->prepare("update sessions set status='R',last_time=datetime('now','localtime'),cookie=?,agent_pid=?, client=?,gr_port=?,sound_port=?,fs_port=? where session_id=? and uname=?"); $sth->execute($cookie, $pid, $client, $gr_port, $snd_port, $fs_port, $sid, $realuser)or die; @@ -144,6 +149,7 @@ elsif($cmd eq "insertport") my $sid=shift or die "argument \"session_id\" missed"; my $sshport=shift or die "argument \"port\" missed"; my $sth=$dbh->prepare("insert into used_ports (server,session_id,port) values (?, ?, ?)"); + check_user($sid); $sth->execute($server, $sid, $sshport) or die; $sth->finish(); } @@ -152,6 +158,7 @@ elsif($cmd eq "resume") { my $client=shift or die "argument \"client\" missed"; my $sid=shift or die "argument \"session_id\" missed"; + check_user($sid); my $sth=$dbh->prepare("update sessions set last_time=datetime('now','localtime'),status='R', client=? where session_id = ? and uname=?"); $sth->execute($client, $sid, $realuser) or die; @@ -162,6 +169,7 @@ elsif($cmd eq "changestatus") { my $status=shift or die "argument \"status\" missed"; my $sid=shift or die "argument \"session_id\" missed"; + check_user($sid); my $sth=$dbh->prepare("update sessions set last_time=datetime('now','localtime'), status=? where session_id = ? and uname=?"); $sth->execute($status, $sid, $realuser)or die; @@ -170,7 +178,6 @@ elsif($cmd eq "changestatus") elsif($cmd eq "getdisplays") { - #ignore $server my @strings; my $sth=$dbh->prepare("select display from sessions"); @@ -222,6 +229,7 @@ elsif($cmd eq "getagent") { my $sid=shift or die "argument \"session_id\" missed"; my $agent; + check_user($sid); my $sth=$dbh->prepare("select agent_pid from sessions where session_id=?"); $sth->execute($sid)or die; @@ -239,6 +247,7 @@ elsif($cmd eq "getdisplay") { my $sid=shift or die "argument \"session_id\" missed"; my $display; + check_user($sid); my $sth=$dbh->prepare("select display from sessions where session_id =?"); $sth->execute($sid)or die; @@ -296,6 +305,14 @@ sub checkroot } } +sub check_user +{ + my $sid=shift or die "argument \"session_id\" missed"; + # session id looks like someuser-51-1304005895_stDgnome-session_dp24 + my ( $user, $rest ) = split('-', $sid, 2); + $user eq $uname or die "$uname is not authorized (should be $user)"; +} + sub fetchrow_printall_array { # print all arrays separated by the pipe symbol -- 1.7.4.1
Hi Reinhard,
On Mo 25 Jul 2011 00:10:03 CEST Reinhard Tartler wrote:
previously, users could create sessions under wrong uids or delete sessions from other users. This patch implements prevents this by checking the userid of the caller with the session id.
+1 from me...
[... patch ...]
Mike
--
DAS-NETZWERKTEAM mike gabriel, dorfstr. 27, 24245 barmissen fon: +49 (4302) 281418, fax: +49 (4302) 281419
GnuPG Key ID 0xB588399B mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de
freeBusy: https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xf...
On Mon, 2011-07-25 at 08:32 +0200, Mike Gabriel wrote:
Hi Reinhard,
On Mo 25 Jul 2011 00:10:03 CEST Reinhard Tartler wrote:
previously, users could create sessions under wrong uids or delete sessions from other users. This patch implements prevents this by checking the userid of the caller with the session id.
+1 from me...
[... patch ...]
<snip> We addressed this a little differently as it is one of the problems we immediately recognized in X2Go two years ago and one of the major modifications we made in our environment.
I'll have to dig out the specifics and your solution may be much better anyway but to scale to a large installation with a single database server and do it securely and without the users using the superuser database account, we changed all the scripts to use schemas named after the user's id. Each user has a schema and within the schema there is a trigger to update an instance of x2gosessions which is accessible by postgres. This table is used by a single x2gocleansessions routine which cleans up after all users rather than having 1000 such session all running every five seconds.
The end result is a single database and a single cleanup daemon for an unlimited number of x2go servers and users with users having access to only their schema and no user using the postgres account - John
Hi John,
On Mo 25 Jul 2011 12:32:44 CEST "John A. Sullivan III" wrote:
On Mon, 2011-07-25 at 08:32 +0200, Mike Gabriel wrote:
Hi Reinhard,
On Mo 25 Jul 2011 00:10:03 CEST Reinhard Tartler wrote:
previously, users could create sessions under wrong uids or delete sessions from other users. This patch implements prevents this by checking the userid of the caller with the session id.
+1 from me...
[... patch ...]
<snip> We addressed this a little differently as it is one of the problems we immediately recognized in X2Go two years ago and one of the major modifications we made in our environment.
The script Reinhard modified only concerns SQLite...
However, based on the current x2goserver code... if you come up with
postgres patches (I strongly guess that you were refering to postgres
changes on the x2goserver script) we will be happy to introspect them.
Unfortunately, there has been a complete rewrite of the database
scripts of X2go in the meantime, so I suppose your patches that you
sent to the ML 1-2 years ago will not apply anymore.
Greets, Mike
--
DAS-NETZWERKTEAM mike gabriel, dorfstr. 27, 24245 barmissen fon: +49 (4302) 281418, fax: +49 (4302) 281419
GnuPG Key ID 0xB588399B mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de
freeBusy: https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xf...
Hi John,
On Mo 25 Jul 2011 12:32:44 CEST "John A. Sullivan III" wrote:
On Mon, 2011-07-25 at 08:32 +0200, Mike Gabriel wrote:
Hi Reinhard,
On Mo 25 Jul 2011 00:10:03 CEST Reinhard Tartler wrote:
previously, users could create sessions under wrong uids or delete sessions from other users. This patch implements prevents this by checking the userid of the caller with the session id.
+1 from me...
[... patch ...]
<snip> We addressed this a little differently as it is one of the problems we immediately recognized in X2Go two years ago and one of the major modifications we made in our environment.
The script Reinhard modified only concerns SQLite...
However, based on the current x2goserver code... if you come up with
postgres patches (I strongly guess that you were refering to postgres
changes on the x2goserver script) we will be happy to introspect them.Unfortunately, there has been a complete rewrite of the database
scripts of X2go in the meantime, so I suppose your patches that you
sent to the ML 1-2 years ago will not apply anymore. <snip> Yes, it is actually a high priority project for me to adapt to the new
On Mon, 2011-07-25 at 13:19 +0200, Mike Gabriel wrote: scripts and issue our new Squeeze desktops to replace our Lenny ones. It's amazing how many even higher priority projects keep intruding! - John
On Mon, Jul 25, 2011 at 12:32:44 (CEST), John A. Sullivan III wrote:
On Mon, 2011-07-25 at 08:32 +0200, Mike Gabriel wrote:
Hi Reinhard,
On Mo 25 Jul 2011 00:10:03 CEST Reinhard Tartler wrote:
previously, users could create sessions under wrong uids or delete sessions from other users. This patch implements prevents this by checking the userid of the caller with the session id.
+1 from me...
the patch has whitespace/tab issues and is therefore not ready.
[... patch ...]
<snip> We addressed this a little differently as it is one of the problems we immediately recognized in X2Go two years ago and one of the major modifications we made in our environment.
I'll have to dig out the specifics and your solution may be much better anyway but to scale to a large installation with a single database server and do it securely and without the users using the superuser database account, we changed all the scripts to use schemas named after the user's id. Each user has a schema and within the schema there is a trigger to update an instance of x2gosessions which is accessible by postgres. This table is used by a single x2gocleansessions routine which cleans up after all users rather than having 1000 such session all running every five seconds.
While implementing this change, it occured to me as well that having an extra field in the database schema would be beneficial to determine the user. For now, I avoided a schema change, but if we have to touch the schema, this would be an addition to consider.
The end result is a single database and a single cleanup daemon for an unlimited number of x2go servers and users with users having access to only their schema and no user using the postgres account - John
To be honest, I'd like to remove the cleanup daemon completely and integrate the cleanup into the listsessions command. The current implementation of the cleanup daemon in perl that runs as root and doesn't work properly anyway makes me feel quite uneasy.
-- Gruesse/greetings, Reinhard Tartler, KeyID 945348A4
On 2011-07-25 13:37, Reinhard Tartler wrote:
To be honest, I'd like to remove the cleanup daemon completely and integrate the cleanup into the listsessions command. The current implementation of the cleanup daemon in perl that runs as root and doesn't work properly anyway makes me feel quite uneasy.
I think there are two things that nedd cleaning up:
The first is probably better done as daemon/cron-job. The daemon needs extended rights, because it needs access to all sessions (this is relevant due to the postgres-implementation), and needs to run on every server. Running as x2gouser should do the trick, though.
The second is probably best placed in x2gocreatesession, as the user should have the rights to clean up it's old sessions (root normally may not access foreign homes via NFS).
Cheers Morty
-- Dipl.-Ing. Moritz 'Morty' Struebe (Wissenschaftlicher Mitarbeiter) Lehrstuhl für Informatik 4 (Verteilte Systeme und Betriebssysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Martensstr. 1 91058 Erlangen
Tel : +49 9131 85-25419 Fax : +49 9131 85-28732 eMail : struebe@informatik.uni-erlangen.de WWW : http://www4.informatik.uni-erlangen.de/~morty
On Mon, Jul 25, 2011 at 13:52:30 (CEST), Moritz Struebe wrote:
On 2011-07-25 13:37, Reinhard Tartler wrote:
To be honest, I'd like to remove the cleanup daemon completely and integrate the cleanup into the listsessions command. The current implementation of the cleanup daemon in perl that runs as root and doesn't work properly anyway makes me feel quite uneasy.
I think there are two things that nedd cleaning up:
- Clean dead sessions from the DB to free displays.
- Clean up hold sessions in the home-dir to free memory.
The first is probably better done as daemon/cron-job. The daemon needs extended rights, because it needs access to all sessions (this is relevant due to the postgres-implementation), and needs to run on every server. Running as x2gouser should do the trick, though.
Why can't this run in user context? I mean the user has priviledges to create sessions, why can't he clean up after himself?
The second is probably best placed in x2gocreatesession, as the user should have the rights to clean up it's old sessions (root normally may not access foreign homes via NFS).
Why is this cleanup better done at 'create session' time rather than at 'listing sessions' time?
-- Gruesse/greetings, Reinhard Tartler, KeyID 945348A4
On 2011-07-25 14:19, Reinhard Tartler wrote:
On Mon, Jul 25, 2011 at 13:52:30 (CEST), Moritz Struebe wrote:
On 2011-07-25 13:37, Reinhard Tartler wrote:
To be honest, I'd like to remove the cleanup daemon completely and integrate the cleanup into the listsessions command. The current implementation of the cleanup daemon in perl that runs as root and doesn't work properly anyway makes me feel quite uneasy. I think there are two things that nedd cleaning up:
- Clean dead sessions from the DB to free displays.
- Clean up hold sessions in the home-dir to free memory.
The first is probably better done as daemon/cron-job. The daemon needs extended rights, because it needs access to all sessions (this is relevant due to the postgres-implementation), and needs to run on every server. Running as x2gouser should do the trick, though. Why can't this run in user context? I mean the user has priviledges to create sessions, why can't he clean up after himself?
He can, of course. But we also want to clean up sessions of people who only log in once in a while.
The second is probably best placed in x2gocreatesession, as the user should have the rights to clean up it's old sessions (root normally may not access foreign homes via NFS). Why is this cleanup better done at 'create session' time rather than at 'listing sessions' time?
List session should list sessions. You don't want it to have strange side-effects (IMO deleting files is such a strange side-effect). While not perfect, x2gocreatesession (and x2goresumesession?) is rather something you expect to do more, as it also creates a profile folder. You might even want it to wait a week before it cleans up, so you can "debug" your session.
Cheers Morty
-- Dipl.-Ing. Moritz 'Morty' Struebe (Wissenschaftlicher Mitarbeiter) Lehrstuhl für Informatik 4 (Verteilte Systeme und Betriebssysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Martensstr. 1 91058 Erlangen
Tel : +49 9131 85-25419 Fax : +49 9131 85-28732 eMail : struebe@informatik.uni-erlangen.de WWW : http://www4.informatik.uni-erlangen.de/~morty
Hi all,
On Mo 25 Jul 2011 15:12:32 CEST Moritz Struebe wrote:
The first is probably better done as daemon/cron-job. The daemon needs extended rights, because it needs access to all sessions (this is relevant due to the postgres-implementation), and needs to run on every server. Running as x2gouser should do the trick, though.
Why can't this run in user context? I mean the user has priviledges to create sessions, why can't he clean up after himself?
He can, of course. But we also want to clean up sessions of people who only log in once in a while.
One reason for keeping a house keeper (someone who cleans up after
you) is that you can fulfil your own tasks as quickly as possible.
Most of the x2goserver scripts do not fork to background: the clients
calls that script and waits for a return value. Each operation issued
in that way should be really fast.
The second is probably best placed in x2gocreatesession, as the user should have the rights to clean up it's old sessions (root normally may not access foreign homes via NFS). Why is this cleanup better done at 'create session' time rather than at 'listing sessions' time?
List session should list sessions. You don't want it to have strange side-effects (IMO deleting files is such a strange side-effect).
I agree here fully. Esp. x2golistsessions has to come up with results
quickly. One reason we use a database for querying session information
opposed to collecting the details from the system state (ps aux etc.).
The problem that occurs, however, is that we indeed have home
locations (NFS+Krb5, AFS, CIFS) that might not be accessible by some
generic local user (such as root). Thus: the clean process for files
in $HOME has to run as x2go user and should not delay any
communication between server and client.
My suggestion is to fork such a cleanup daemon in user space that
intellegently cleans up after the session has started up...
x2gostartagent ... sleep for 20 seconds -> then launch x2gocleanup-session
This is only necessary once per logged in user (you do not want a
session cleaner for each of multiple rootless applications, started on
the server).
While not perfect, x2gocreatesession (and x2goresumesession?) is rather something you expect to do more, as it also creates a profile folder. You might even want it to wait a week before it cleans up, so you can "debug" your session.
Indeed! Or at least have an option for that...
Cheers Morty
Greetings, Mike
--
DAS-NETZWERKTEAM mike gabriel, dorfstr. 27, 24245 barmissen fon: +49 (4302) 281418, fax: +49 (4302) 281419
GnuPG Key ID 0xB588399B mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de
freeBusy: https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xf...
Hi Morty,
On Mo 25 Jul 2011 13:52:30 CEST Moritz Struebe wrote:
On 2011-07-25 13:37, Reinhard Tartler wrote:
To be honest, I'd like to remove the cleanup daemon completely and integrate the cleanup into the listsessions command. The current implementation of the cleanup daemon in perl that runs as root and doesn't work properly anyway makes me feel quite uneasy.
I think there are two things that nedd cleaning up:
- Clean dead sessions from the DB to free displays.
This needs high prio (that is: before Baikal).
- Clean up hold sessions in the home-dir to free memory.
This is on the server as well as on the client. I am already working
on a concept for Python X2go, but the concept of Python X2go and
x2goclient should be similar...
greets, Mike
--
DAS-NETZWERKTEAM mike gabriel, dorfstr. 27, 24245 barmissen fon: +49 (4302) 281418, fax: +49 (4302) 281419
GnuPG Key ID 0xB588399B mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de
freeBusy: https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xf...