From 2350016aeee4c71c9afad94c32ceaa73d92b8f24 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 7 Feb 2014 20:11:48 +0100 Subject: 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 --- src/maingui/printergui.cpp | 13 ++++++++----- src/pwgui/main.cpp | 33 ++++++++++++++++++++++++++------- 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 #include #include +#include // ____________________________________________________________________________ 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; } -- cgit v1.2.3-55-g7522