diff options
Diffstat (limited to 'src/pwgui/main.cpp')
-rw-r--r-- | src/pwgui/main.cpp | 33 |
1 files changed, 26 insertions, 7 deletions
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; } |