From: Michal Vyskocil Subject: Backport old privs at since 3.10 have substantially changed the priviledge model, which is tied to Debian setup of at. As SUSE does use a different layout, this patch introduces back the PRIV_START/PRIV_END + fchown where needed. References: https://bugzilla.novell.com/show_bug.cgi?id=849720 --- at.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) Index: at-3.2.4/at.c =================================================================== --- at-3.2.4.orig/at.c +++ at-3.2.4/at.c @@ -155,18 +155,11 @@ sigc(int signo) /* If the user presses ^C, remove the spool file and exit */ if (fcreated) { - /* PRIV_START - We need the unprivileged uid here since the file is owned by the real - (not effective) uid. - */ - setregid(real_gid, effective_gid); unlink(atfile); - setregid(effective_gid, real_gid); - /* + PRIV_END - */ } exit(EXIT_FAILURE); } @@ -326,18 +319,14 @@ writefile(time_t runtimer, char queue) * bit. Yes, this is a kluge. */ cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR); - seteuid(real_uid); if ((fd = open(atfile, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY | O_SYNC, S_IRUSR)) == -1) perr("Cannot create atjob file %.500s", atfile); - seteuid(effective_uid); if ((fd2 = dup(fd)) < 0) perr("Error in dup() of job file"); - /* if (fchown(fd2, real_uid, real_gid) != 0) perr("Cannot give away file"); - */ PRIV_END @@ -729,11 +718,7 @@ process_jobs(int argc, char **argv, int switch (what) { case ATRM: - /* - We need the unprivileged uid here since the file is owned by the real - (not effective) uid. - */ - setregid(real_gid, effective_gid); + PRIV_START if (queue == '=') { fprintf(stderr, "Warning: deleting running job\n"); @@ -743,7 +728,7 @@ process_jobs(int argc, char **argv, int rc = EXIT_FAILURE; } - setregid(effective_gid, real_gid); + PRIV_END done = 1; break; @@ -753,22 +738,26 @@ process_jobs(int argc, char **argv, int FILE *fp; int ch; - setregid(real_gid, effective_gid); - fp = fopen(dirent->d_name, "r"); + PRIV_START + + fp = fopen(dirent->d_name, "r"); + + PRIV_END if (fp) { while ((ch = getc(fp)) != EOF) { putchar(ch); } done = 1; + PRIV_START fclose(fp); + PRIV_END fp = NULL; } else { perr("Cannot open %.500s", dirent->d_name); rc = EXIT_FAILURE; } - setregid(effective_gid, real_gid); } break;