Skip to content
This repository has been archived by the owner on Dec 4, 2020. It is now read-only.

Commit

Permalink
Fix a bug with PCDM where the PAM session isn't closed fully at logout,
Browse files Browse the repository at this point in the history
this fixes and issue with PEFS not removing homedir keys.

The file /usr/local/share/PCDM/pcdm-session is now used to drop priv
and execute the target desktop at login, leaving the parent PCDM
process running as root and able to do cleanup.
  • Loading branch information
Kris Moore committed May 8, 2014
1 parent 3ff724e commit fb13c77
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 49 deletions.
5 changes: 4 additions & 1 deletion src-qt4/PCDM/PCDM.pro
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,13 @@ theme=themes
theme.path=/usr/local/share/PCDM
theme.extra=cp -r themes $(INSTALL_ROOT)/usr/local/share/PCDM/.

session.path=/usr/local/share/PCDM
session.extra=cc -o pcdm-session src/pcdm-session.c && install -o root -g wheel -m 755 pcdm-session $(INSTALL_ROOT)/usr/local/share/PCDM/

conf=pcdm.conf
conf.path=/usr/local/etc
conf.extra=cp pcdm.conf $(INSTALL_ROOT)/usr/local/etc/pcdm.conf.dist && chmod 600 $(INSTALL_ROOT)/usr/local/etc/pcdm.conf.dist

INSTALLS += dotrans scripts rcd cleanthemes theme conf target
INSTALLS += dotrans scripts rcd cleanthemes theme conf target session

RESOURCES += PCDM.qrc
62 changes: 62 additions & 0 deletions src-qt4/PCDM/src/pcdm-session.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Name: pcdm-session
Desc: Small executable to drop priv and execute the desktop
License: BSD (2 Clause)
Author: Kris Moore
*/
#include <sys/param.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char ** argv)
{

// Load the CLI args
uid_t my_gid;
uid_t my_uid;
char username[MAXPATHLEN];
char cmd[MAXPATHLEN];
char xcmd[MAXPATHLEN];
char xlog[MAXPATHLEN];
if ( argc != 6 ) {
exit(1);
}

char output[MAXPATHLEN];

// Set our values
strcpy(username, argv[1]);
my_uid = atoi(argv[2]);
my_gid = atoi(argv[3]);
strcpy(xcmd, argv[4]);
strcpy(xlog, argv[5]);

// Set the GID
if (setgid(my_gid) < 0) {
exit(1);
}

// Setup our other groups
if (initgroups(username, my_gid) < 0) {
exit(1);
}

// Lets drop to user privs
if (setuid(my_uid) < 0) {
exit(1);
}

// Run the app now
strcpy(cmd, "sh ");
strcat(cmd, xcmd);
strcat(cmd, " >");
strcat(cmd, xlog);
strcat(cmd, " 2>");
strcat(cmd, xlog);
int ret = system(cmd);
exit(ret);

}
80 changes: 33 additions & 47 deletions src-qt4/PCDM/src/pcdm-xprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <pwd.h>
#include <login_cap.h>
#include <QMessageBox>
#include <QTemporaryFile>

/*
Sub-classed QProcess for starting an XSession Process
Expand Down Expand Up @@ -115,62 +116,47 @@ bool XProcess::startXSession(){
QProcess::execute(xhostcmd);
//And finally set the login user before dropping priv
setlogin( xuser.toUtf8() );
//QWidget *wid = new QWidget();
if (setgid(pw->pw_gid) < 0) {
qDebug() << "setgid() failed!";
return FALSE;
}

// Setup our other groups
if (initgroups(xuser.toLatin1(), pw->pw_gid) < 0) {
qDebug() << "initgroups() failed!";
setgid(0);
return FALSE;
}

// Lets drop to user privs
if (setuid(pw->pw_uid) < 0) {
qDebug() << "setuid() failed!";
return FALSE;
}
//Startup the PAM session
if( !pam_startSession() ){ pam_shutdown(); return FALSE; }
pam_session_open = TRUE; //flag that pam has an open session
QString cmd;
// Configure the DE startup command

// - Add the DE startup command to the end
cmd.append("dbus-launch --exit-with-session "+xcmd);
//cmd.append(xcmd);
QString cmd;

//Backend::log("Startup command: "+cmd);
// Setup the process environment
setupSessionEnvironment();
//Log the DE startup outputs as well
this->setProcessChannelMode(QProcess::MergedChannels);
this->setStandardOutputFile(xhome+"/.pcdm-startup.log",QIODevice::Truncate);
//this->setStandardErrorFile(xhome+"/.pcdm-startup.err",QIODevice::Truncate);
// Startup the process(s)
// - Setup to run the user's <home-dir>/.xprofile startup script
if(QFile::exists(xhome+"/.xprofile")){
//Make sure the file is executable
QFile::setPermissions(xhome+"/.xprofile", QFile::permissions(xhome+"/.xprofile") | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther );
//Need to run a couple commands in sequence: so put them in a script file
QStringList contents;
contents << ". "+xhome+"/.xprofile";
contents << cmd; //end with the actual command for the DE
contents << "exit $?"; //Make sure we return the DE return value
if( Backend::writeFile(xhome+"/.pcdmsessionstart", contents) ){
//script created fine, change the command to just run it
cmd = "sh "+xhome+"/.pcdmsessionstart";
}else{
//Could not create script file, fallback on running them seperately
QString xpro = "sh "+xhome+"/.xprofile";
this->start(xpro);
this->waitForFinished(3000);
}
}

// Create our startup script
tFile = new QTemporaryFile();
if ( ! tFile->open() )
return FALSE;

QTextStream tOut(tFile);

// Configure the DE startup command
cmd.append("dbus-launch --exit-with-session "+xcmd);

// - Setup to run the user's <home-dir>/.xprofile startup script
QFile::setPermissions(xhome+"/.xprofile", QFile::permissions(xhome+"/.xprofile") | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther );

//Need to run a couple commands in sequence: so put them in a script file
tOut << "#!/bin/sh\n\n";
tOut << "if [ -e '"+xhome+"/.xprofile' ] ; then\n";
tOut << " . "+xhome+"/.xprofile\n";
tOut << "fi\n";
tOut << cmd + "\n"; //+ " >" + xhome+ "/.pcdm-startup.log" + " 2>" + xhome + "/.pcdm-startup.log\n";
tOut << "exit $?"; //Make sure we return the DE return value

QString tUid, tGid, logFile;
tUid.setNum(pw->pw_uid);
tGid.setNum(pw->pw_gid);
logFile=xhome + "/.pcdm-startup.log";
cmd = "/usr/local/share/PCDM/pcdm-session "+xuser+" "+tUid+" "+tGid+" "+tFile->fileName()+" "+logFile;
connect( this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotCleanup()) );
tFile->setPermissions(QFile::ReadOwner | QFile::WriteOwner |QFile::ReadGroup | QFile::ReadUser | QFile::ReadOther);
tFile->close();

Backend::log("Starting session with:\n" + cmd );
this->start(cmd);
return TRUE;
}
Expand Down
4 changes: 3 additions & 1 deletion src-qt4/PCDM/src/pcdm-xprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <QDebug>
#include <QProcess>
#include <QProcessEnvironment>
#include <QTemporaryFile>

#include <sys/types.h>
#include <security/pam_appl.h>
Expand Down Expand Up @@ -57,8 +58,9 @@ class XProcess : public QProcess
bool pam_stopSession();
void pam_logFailure(int);
void pam_shutdown(); //cleanly close all the PAM stuff


QTemporaryFile *tFile;

private slots:
void slotCleanup();

Expand Down

0 comments on commit fb13c77

Please sign in to comment.