bool XProcess::startXSession(){ //Returns true if the session can continue, or false if it needs to be closed down qDebug() << "Starting X Session:" << xuser << xcmd << xhome << xde << VT; //Check that the necessary info to start the session is available if( xuser.isEmpty() || xcmd.isEmpty() || xhome.isEmpty() || xde.isEmpty() ){ emit InvalidLogin(); //Make sure the GUI knows that it was a failure return true; } //Backend::log("Starting up Desktop environment ("+xcmd+") as user ("+xuser+")"); //Check for PAM username/password validity if( !pam_checkPW() ){ emit InvalidLogin(); pam_shutdown(); return true; } //Make sure the user is added to any required groups QStringList cgroups = Backend::runShellCommand("id -nG "+xuser).join("").split(" "); //current groups if(!cgroups.contains("video")){ Backend::runShellCommand("pw group mod video -m "+xuser); } //add user to video group (required for GPU access) //If this has a special device password, mount the personacrypt device if( !xanonlogin && !xdevpass.isEmpty() ){ //&& Backend::getAvailablePersonaCryptUsers().contains(xuser) ){ Backend::log(" - PersonaCrypt Login Detected"); if( !Backend::MountPersonaCryptUser(xuser, xdevpass) ){ //Could not mount the personacrypt device (invalid password?) xdevpass.clear(); //clear the invalid password emit InvalidLogin(); pam_shutdown(); return true; }else{ //overwrite the password in memory, but leave it flagged (not empty) if(DEBUG){ qDebug() << "Mounted PersonaCrypt Device"; } xdevpass.clear(); xdevpass = "******"; } } //Save the current user/desktop as the last login Backend::saveLoginInfo(xuser, xhome, xde); // Get the users uid/gid information struct passwd *pw; int uid; char *ok; if (!(pw = getpwnam(xuser.toLatin1()))) { uid = strtol(xuser.toLatin1(), &ok, 10); if (!(pw = getpwuid(uid))) { return false; } } //Emit the last couple logs before dropping privileges Backend::log("Starting session:"); Backend::log(" - Session Log: ~/.pcdm-startup.log"); QProcess::execute("killall compton"); //For sanity's sake, ensure that the ZFS mountpoint are all available first if(QFile::exists("/sbin/zfs")){ QProcess::execute("zfs mount -a"); //just to ensure the user's home dir is actually mounted } //Check/create the user's home-dir before dropping privs if(!QFile::exists(xhome)){ qDebug() << "No Home dir found - populating..."; QString hmcmd = "pw usermod "+xuser+" -m"; QProcess::execute(hmcmd); } //If this is an anonymous login, create the blank home-dir on top if(xanonlogin){ if(DEBUG){ qDebug() << " - Stealth Session selected"; } QProcess::execute("personacrypt tempinit "+xuser+" 10G"); //always use 10GB blank dir } // Get the environment before we drop priv this->setProcessEnvironment( QProcessEnvironment::systemEnvironment() ); //current environment //Now allow this user access to the Xserver QString xhostcmd = "xhost si:localuser:"******"/tmp/pcdm-session."+VT+".XXXXXX"); if ( ! tFile->open() ) return false; QTextStream tOut(tFile); // Configure the DE startup command if(QFile::exists("/usr/local/bin/dbus-launch") && !xcmd.contains("lumina-desktop") ){ cmd.append("dbus-launch --exit-with-session "+xcmd); }else{ cmd.append(xcmd); } QString tUid, tGid, logFile; tUid.setNum(pw->pw_uid); tGid.setNum(pw->pw_gid); logFile=xhome + "/.pcdm-startup.log"; // Locate the auth file QString authfile = qgetenv("XAUTHORITY"); if ( authfile.isEmpty() ) authfile = xhome + "/.Xauthority"; //Need to run a couple commands in sequence: so put them in a script file tOut << "#!/bin/sh\n\n"; QString PICOCLIENT = qgetenv("PICO_CLIENT_LOGIN"); QString PICOHOME = qgetenv("PICO_CLIENT_HOME"); if ( ! PICOCLIENT.isEmpty() && ! PICOHOME.isEmpty() ) { // Change ownership on the Xauthority file for PICO usage tOut << "rm "+authfile+"\n"; tOut << "ln -fs "+PICOHOME+"/.Xauthority "+authfile+"\n"; QString PICOPULSE = qgetenv("PICO_PULSE_COOKIE"); // Check if PULSE is enabled if ( ! PICOPULSE.isEmpty() ) { tOut << "mkdir -p "+xhome+"/.config/pulse 2>/dev/null\n"; tOut << "cp "+PICOPULSE+" "+xhome+"/.config/pulse/cookie\n"; tOut << "chown "+tUid+":"+tGid+" " +xhome+"/.config/pulse/cookie\n"; } QProcess::execute("chown "+tUid+" "+PICOHOME+"/.Xauthority"); // Change ownership on the pico login } else { // Change ownership on the Xauthority file QProcess::execute("chown "+tUid+":"+tGid+" "+authfile); } tOut << Backend::resetKbdCmd() + "\n"; //do this before sourcing .xprofile - in case there is a user-override set there tOut << "if [ -e '"+xhome+"/.xprofile' ] ; then\n"; tOut << " chmod 755 "+xhome+"/.xprofile\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 cmd = "/usr/local/share/PCDM/pcdm-session"; //+xuser+" "+tUid+" "+tGid+" "+tFile->fileName()+" "+logFile; QStringList cmdArgs; cmdArgs << 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(); if(DEBUG){ Backend::log("Starting session with:\n" + cmd ); } this->start(cmd, cmdArgs); return true; }
bool XProcess::startXSession(){ //Returns true if the session can continue, or false if it needs to be closed down //Check that the necessary info to start the session is available if( xuser.isEmpty() || xcmd.isEmpty() || xhome.isEmpty() || xde.isEmpty() ){ emit InvalidLogin(); //Make sure the GUI knows that it was a failure return true; } //Backend::log("Starting up Desktop environment ("+xcmd+") as user ("+xuser+")"); //Check for PAM username/password validity if( !pam_checkPW() ){ emit InvalidLogin(); pam_shutdown(); return true; } //If this has a special device password, mount the personacrypt device if( !xanonlogin && !xdevpass.isEmpty() && Backend::getAvailablePersonaCryptUsers().contains(xuser) ){ if( !Backend::MountPersonaCryptUser(xuser, xdevpass) ){ //Could not mount the personacrypt device (invalid password?) xdevpass.clear(); //clear the invalid password emit InvalidLogin(); pam_shutdown(); return true; }else{ //overwrite the password in memory, but leave it flagged (not empty) if(DEBUG){ qDebug() << "Mounted PersonaCrypt Device"; } xdevpass.clear(); xdevpass = "******"; } } //Save the current user/desktop as the last login Backend::saveLoginInfo(xuser,xde); // Get the users uid/gid information struct passwd *pw; int uid; char *ok; if (!(pw = getpwnam(xuser.toLatin1()))) { uid = strtol(xuser.toLatin1(), &ok, 10); if (!(pw = getpwuid(uid))) { return false; } } //Emit the last couple logs before dropping privileges Backend::log("Starting session:"); Backend::log(" - Session Log: ~/.pcdm-startup.log"); //For sanity's sake, ensure that the ZFS mountpoint are all available first if(QFile::exists("/sbin/zfs")){ QProcess::execute("zfs mount -a"); //just to ensure the user's home dir is actually mounted } //Check/create the user's home-dir before dropping privs if(!QFile::exists(xhome)){ qDebug() << "No Home dir found - populating..."; QString hmcmd = "pw usermod "+xuser+" -m"; QProcess::execute(hmcmd); } //If this is an anonymous login, create the blank home-dir on top if(xanonlogin){ if(DEBUG){ qDebug() << " - Stealth Session selected"; } QProcess::execute("personacrypt tempinit "+xuser+" 10G"); //always use 10GB blank dir } // Get the environment before we drop priv this->setProcessEnvironment( QProcessEnvironment::systemEnvironment() ); //current environment //Now allow this user access to the Xserver QString xhostcmd = "xhost si:localuser:"******"/usr/local/bin/dbus-launch")){ cmd.append("dbus-launch --exit-with-session "+xcmd); } //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 << " chmod 755 "+xhome+"/.xprofile\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(); if(DEBUG){ Backend::log("Starting session with:\n" + cmd ); } this->start(cmd); return true; }