summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-02-07 20:11:48 +0100
committerSimon Rettberg2014-02-07 20:11:48 +0100
commit2350016aeee4c71c9afad94c32ceaa73d92b8f24 (patch)
treecc6bbc82c76363d77d8c877a22e30ab12aae5b83
parentForgot header (diff)
downloadprintergui-2350016aeee4c71c9afad94c32ceaa73d92b8f24.tar.gz
printergui-2350016aeee4c71c9afad94c32ceaa73d92b8f24.tar.xz
printergui-2350016aeee4c71c9afad94c32ceaa73d92b8f24.zip
Finally make it work as intended.
There's probably some debug code and debug output left in some places that needs to be replaced. TODO: - Focus should be in password box when showing pwgui - Pressing return should be clicking OK - Pressing escape should be clicking Cancel
-rw-r--r--src/maingui/printergui.cpp13
-rw-r--r--src/pwgui/main.cpp33
2 files changed, 34 insertions, 12 deletions
diff --git a/src/maingui/printergui.cpp b/src/maingui/printergui.cpp
index 90d4731..5e2ba39 100644
--- a/src/maingui/printergui.cpp
+++ b/src/maingui/printergui.cpp
@@ -3,6 +3,7 @@
#include <QMessageBox>
#include <unistd.h>
#include <QTimer>
+#include <pwd.h>
// ____________________________________________________________________________
PrinterGui::PrinterGui(char *argv[], QWidget *parent) :
@@ -13,10 +14,11 @@ PrinterGui::PrinterGui(char *argv[], QWidget *parent) :
// When called it is guaranteed that argv has (at least) 3 elements
// Set username
- char buf[200];
- if (getlogin_r(buf, 200) == 0) {
+ // Do not use getlogin[_r] as it doesn't fucking work!
+ struct passwd *pw = getpwuid(getuid());
+ if (pw != NULL && pw->pw_name != NULL) {
// Detect real name
- this->user = strdup(buf);
+ this->user = strdup(pw->pw_name);
} else {
// Fallback to what command line says
this->user = strdup(argv[1]);
@@ -90,6 +92,7 @@ void PrinterGui::initializeUI()
QRect desktopRect = QApplication::desktop()->screenGeometry(this);
this->move( desktopRect.width()/2-this->width()/2,
desktopRect.height()/2-this->height()/2);
+ this->setWindowTitle(QString::fromUtf8("Drucken - %1").arg(this->user));
}
// ____________________________________________________________________________
@@ -215,7 +218,7 @@ void PrinterGui::on_buttonPrint_clicked()
cupsSetUser(this->user);
char jobtitle[100];
- snprintf(jobtitle, 100, "gui-%d", (int)getpid());
+ snprintf(jobtitle, 100, "gui-%d-%s", (int)getpid(), this->user);
// Drucken
if( 0 == cupsPrintFile(dest->name,
@@ -239,7 +242,7 @@ void PrinterGui::on_bgTimer_timeout()
}
if (++this->bgTimeout > 4) {
// Job was sent, GUI is invisible, quit after a few seconds
- QCoreApplication::instance()->quit();
+ QCoreApplication::instance()->exit(0);
}
}
diff --git a/src/pwgui/main.cpp b/src/pwgui/main.cpp
index 88e0486..6e12eee 100644
--- a/src/pwgui/main.cpp
+++ b/src/pwgui/main.cpp
@@ -17,6 +17,7 @@
#define NAMELEN 400
#define BUFLEN 1000
+#define ENVLEN 10000
static int pid = -1;
// UID and GUI of user we should drop privileges to
@@ -24,7 +25,7 @@ static int ruid = 65534, rgid = 65534;
static char ruser[NAMELEN] = "";
// Copy of the GUIs environment, so we can access X
// Whatever you do, make sure this has at least two nullchars at the end!
-static char gui_env[BUFLEN] = "\0\0\0";
+static char gui_env[ENVLEN] = "\0\0\0";
static int run_backend(char *backend, char *uri, char *jobid, char *user, char *title, char *copies, char *options, char *file, char *password);
@@ -81,6 +82,7 @@ int main(int argc, char *argv[])
helper_loadlpuser();
struct stat st;
if (stat(backend, &st) != 0 || (st.st_mode & 0011) != 0) helper_dropprivs();
+ kill(pid, SIGTERM);
execv(backend, argv);
exit(127);
}
@@ -128,7 +130,7 @@ int main(int argc, char *argv[])
// Seems we need the dialog
int status;
char creds[NAMELEN], *pass = NULL;
- snprintf(creds, NAMELEN, "%s", argv[3]);
+ snprintf(creds, NAMELEN, "%s", argv[2]);
do {
int pfd[2];
if (pipe(pfd) != 0) {
@@ -166,6 +168,7 @@ int main(int argc, char *argv[])
status = run_backend(backend, device, argv[1], creds, argv[3], argv[4], argv[5], tmpfile, pass);
} while (status != CUPS_BACKEND_OK);
remove(tmpfile);
+ fprintf(stderr, "Job submitted.\n");
return CUPS_BACKEND_OK;
}
@@ -213,13 +216,13 @@ static bool helper_getpiduid(char *user, char *title)
fprintf(stderr, "WARNING: Job Title doesnt start with 'gui-' (Is: %s)\n", title);
return false; // Wrong job title
}
+ int p = atoi(title + 4);
struct stat st;
struct passwd *pw = getpwnam(user);
if (pw == NULL) {
fprintf(stderr, "WARNING: Cannot getpwnam %s\n", user);
return false;
}
- int p = atoi(title + 4);
char bin[PATH_MAX+1], tmp[100];
snprintf(tmp, 100, "/proc/%d/exe", p);
if (realpath(tmp, bin) == NULL) {
@@ -227,10 +230,19 @@ static bool helper_getpiduid(char *user, char *title)
return false;
}
char *last = strrchr(bin, '/');
- if (last == NULL || strcmp(last, "/printergui") != 0) return false; // Wrong process
+ if (last == NULL || strcmp(last, "/printergui") != 0) {
+ fprintf(stderr, "WARNING: %s does not end in /printergui\n", bin);
+ return false; // Wrong process
+ }
// PID passed via job title seems to be the printergui
- if (lstat(tmp, &st) < 0) return false;
- if (st.st_uid != pw->pw_uid) return false; // Print job user doesn't match printergui process owner
+ if (lstat(tmp, &st) < 0) {
+ fprintf(stderr, "WARNING: Could not lstat() %s\n", tmp);
+ return false;
+ }
+ if (st.st_uid != pw->pw_uid) {
+ fprintf(stderr, "WARNING: Owner of %s: %d, owner of job: %d (%s)\n", tmp, (int)st.st_uid, (int)pw->pw_uid, user);
+ return false; // Print job user doesn't match printergui process owner
+ }
// All checks passed, make stuff global
pid = p;
ruid = pw->pw_uid;
@@ -240,13 +252,20 @@ static bool helper_getpiduid(char *user, char *title)
snprintf(tmp, 100, "/proc/%d/environ", p);
int fh = open(tmp, O_RDONLY);
if (fh >= 0) {
- int bytes = read(fh, gui_env, BUFLEN - 2);
+ char *ptr = gui_env;
+ int bytes = 0, ret;
+ while ((ret = read(fh, ptr, ENVLEN - (ptr - gui_env) - 2)) > 0) {
+ bytes += ret;
+ ptr += ret;
+ if (bytes + 3 >= ENVLEN) break;
+ }
close(fh);
if (bytes >= 0) {
gui_env[bytes+0] = '\0';
gui_env[bytes+1] = '\0';
}
}
+ fprintf(stderr, "DEBUG: getpiduid successful!\n");
return true;
}