size_t maxsize = 0; /* Maximum supported file size */
mime_type_t *temptype, /* MIME type looping var */
*desttype; /* Destination MIME type */
- char filename[1024], /* Full filter filename */
- *dirsep; /* Pointer to directory separator */
- struct stat fileinfo; /* File information */
+ mime_filter_t *filterptr; /* MIME filter */
+ char filename[1024]; /* Full filter filename */
cupsdLogMessage(CUPSD_LOG_DEBUG2,
}
/*
- * See if the filter program exists; if not, stop the printer and flag
- * the error!
+ * Check permissions on the filter and its containing directory...
*/
if (strcmp(program, "-"))
else
snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program);
- if (stat(filename, &fileinfo))
- {
- memset(&fileinfo, 0, sizeof(fileinfo));
-
- snprintf(p->state_message, sizeof(p->state_message),
- "Printer driver \"%s\" not available: %s", filename,
- strerror(errno));
- cupsdSetPrinterReasons(p, "+cups-missing-filter-warning");
-
- cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message);
- }
-
- /*
- * When running as root, do additional security checks...
- */
-
- else if (!RunUser)
- {
- /*
- * Only use filters that are owned by root and do not have world write
- * permissions.
- */
-
- if (fileinfo.st_uid ||
- (fileinfo.st_gid && (fileinfo.st_mode & S_IWGRP)) ||
- (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0)
- {
- snprintf(p->state_message, sizeof(p->state_message),
- "Printer driver \"%s\" has insecure permissions "
- "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode,
- (int)fileinfo.st_uid, (int)fileinfo.st_gid);
-
-#ifdef __APPLE__ /* Don't flag filters with group write for "admin" */
- if (fileinfo.st_uid ||
- (fileinfo.st_gid && fileinfo.st_gid != 80 &&
- (fileinfo.st_mode & S_IWGRP)) ||
- (fileinfo.st_mode & (S_ISUID | S_IWOTH)))
-#endif /* __APPLE__ */
- cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning");
-
- cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message);
- }
- else if (fileinfo.st_mode)
- {
- /*
- * Similarly, check that the parent directory is also owned by root and
- * does not have world write permissions.
- */
-
- if ((dirsep = strrchr(filename, '/')) != NULL)
- *dirsep = '\0';
-
- if (!stat(filename, &fileinfo) &&
- (fileinfo.st_uid ||
- (fileinfo.st_gid && (fileinfo.st_mode & S_IWGRP)) ||
- (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0))
- {
- snprintf(p->state_message, sizeof(p->state_message),
- "Printer driver directory \"%s\" has insecure permissions "
- "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode,
- (int)fileinfo.st_uid, (int)fileinfo.st_gid);
-
- cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning");
-
- cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message);
- }
- }
- }
+ cupsdCheckProgram(filename, p);
}
/*
"%s", p->name, temptype->super, temptype->type,
desttype->super, desttype->type,
cost, program);
- mimeAddFilter(MimeDatabase, temptype, desttype, cost, program);
+ filterptr = mimeAddFilter(MimeDatabase, temptype, desttype, cost,
+ program);
if (!mimeFilterLookup(MimeDatabase, desttype, filtertype))
{
"%s", p->name, temptype->super, temptype->type,
filtertype->super, filtertype->type,
cost, program);
- mimeAddFilter(MimeDatabase, temptype, filtertype, cost, program);
+ filterptr = mimeAddFilter(MimeDatabase, temptype, filtertype, cost,
+ program);
}
+
+ if (filterptr)
+ filterptr->maxsize = maxsize;
}
}
*
* Contents:
*
+ * cupsdCheckProgram() - Check the permissions of the given program and its
+ * containing directory.
* cupsdCreateProfile() - Create an execution profile for a subprocess.
* cupsdDestroyProfile() - Delete an execution profile.
* cupsdEndProcess() - End a process.
#endif /* HAVE_SANDBOX_H */
+/*
+ * 'cupsdCheckProgram()' - Check the permissions of the given program and its
+ * containing directory.
+ */
+
+int /* O - 1 if OK, 0 if not OK */
+cupsdCheckProgram(
+ const char *filename, /* I - Filename to check */
+ cupsd_printer_t *p) /* I - Printer, if any */
+{
+ struct stat fileinfo; /* File information */
+ char temp[1024], /* Parent directory filename */
+ *ptr; /* Pointer into parent directory */
+
+
+ /*
+ * Does the program even exist and is it accessible?
+ */
+
+ if (stat(filename, &fileinfo))
+ {
+ /*
+ * Nope...
+ */
+
+ if (p)
+ {
+ snprintf(p->state_message, sizeof(p->state_message),
+ "Printer driver \"%s\" not available: %s", filename,
+ strerror(errno));
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message);
+
+ if (cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"))
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL,
+ "Printer driver \"%s\" not available.", filename);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Program \"%s\" not available: %s",
+ filename, strerror(errno));
+
+ return (0);
+ }
+
+ /*
+ * Are we running as root?
+ */
+
+ if (RunUser)
+ {
+ /*
+ * Nope, so anything goes...
+ */
+
+ return (1);
+ }
+
+ /*
+ * Verify permission of the program itself:
+ *
+ * 1. Must be owned by root
+ * 2. Must not be writable by group unless group is root/wheel/admin
+ * 3. Must not be setuid
+ * 4. Must not be writable by others
+ */
+
+ if (fileinfo.st_uid || /* 1. Must be owned by root */
+#ifdef __APPLE__
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid &&
+ fileinfo.st_gid != 80) || /* 2. Must not be writable by group */
+#else
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid) ||
+ /* 2. Must not be writable by group */
+#endif /* __APPLE__ */
+ (fileinfo.st_mode & S_ISUID) || /* 3. Must not be setuid */
+ (fileinfo.st_mode & S_IWOTH)) /* 4. Must not be writable by others */
+ {
+ if (p)
+ {
+ snprintf(p->state_message, sizeof(p->state_message),
+ "Printer driver \"%s\" has insecure permissions "
+ "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode,
+ (int)fileinfo.st_uid, (int)fileinfo.st_gid);
+
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message);
+
+ if (cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"))
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL, "%s",
+ p->state_message);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Program \"%s\" has insecure permissions "
+ "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode,
+ (int)fileinfo.st_uid, (int)fileinfo.st_gid);
+
+ errno = EPERM;
+
+ return (0);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "%s%s \"%s\" permissions OK "
+ "(0%o/uid=%d/gid=%d).", p ? p->name : "",
+ p ? ": Printer driver" : "Program", filename,
+ fileinfo.st_mode, (int)fileinfo.st_uid,
+ (int)fileinfo.st_gid);
+
+ /*
+ * Now check the containing directory...
+ */
+
+ strlcpy(temp, filename, sizeof(temp));
+ if ((ptr = strrchr(temp, '/')) != NULL)
+ {
+ if (ptr == temp)
+ ptr[1] = '\0';
+ else
+ *ptr = '\0';
+ }
+
+ if (stat(temp, &fileinfo))
+ {
+ /*
+ * Doesn't exist...
+ */
+
+ if (p)
+ {
+ snprintf(p->state_message, sizeof(p->state_message),
+ "Printer driver directory \"%s\" not available: %s", temp,
+ strerror(errno));
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message);
+
+ if (cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"))
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL,
+ "Printer driver directory \"%s\" not available.", temp);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Program directory \"%s\" not available: %s", temp,
+ strerror(errno));
+
+ return (0);
+ }
+
+ if (fileinfo.st_uid || /* 1. Must be owned by root */
+#ifdef __APPLE__
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid &&
+ fileinfo.st_gid != 80) || /* 2. Must not be writable by group */
+#else
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid) ||
+ /* 2. Must not be writable by group */
+#endif /* __APPLE__ */
+ (fileinfo.st_mode & S_ISUID) || /* 3. Must not be setuid */
+ (fileinfo.st_mode & S_IWOTH)) /* 4. Must not be writable by others */
+ {
+ if (p)
+ {
+ snprintf(p->state_message, sizeof(p->state_message),
+ "Printer driver directory \"%s\" has insecure permissions "
+ "(0%o/uid=%d/gid=%d).", temp, fileinfo.st_mode,
+ (int)fileinfo.st_uid, (int)fileinfo.st_gid);
+
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message);
+
+ if (cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"))
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL, "%s",
+ p->state_message);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Program directory \"%s\" has insecure permissions "
+ "(0%o/uid=%d/gid=%d).", temp, fileinfo.st_mode,
+ (int)fileinfo.st_uid, (int)fileinfo.st_gid);
+
+ errno = EPERM;
+
+ return (0);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "%s%s directory \"%s\" permissions OK "
+ "(0%o/uid=%d/gid=%d).", p ? p->name : "",
+ p ? ": Printer driver" : "Program", temp,
+ fileinfo.st_mode, (int)fileinfo.st_uid,
+ (int)fileinfo.st_gid);
+
+ /*
+ * If we get here then we can "safely" run this program...
+ */
+
+ return (1);
+}
+
+
/*
* 'cupsdCreateProfile()' - Create an execution profile for a subprocess.
*/
char *real_argv[103], /* Real command-line arguments */
cups_exec[1024]; /* Path to "cups-exec" program */
int user; /* Command UID */
- struct stat commandinfo; /* Command file information */
cupsd_proc_t *proc; /* New process record */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* POSIX signal handler */
#endif /* __APPLE__ */
+ *pid = 0;
+
/*
* Figure out the UID for the child process...
*/
* Check the permissions of the command we are running...
*/
- if (stat(command, &commandinfo))
- {
- *pid = 0;
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, "
- "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, "
- "profile=%p, job=%p(%d), pid=%p) = %d",
- command, argv, envp, infd, outfd, errfd, backfd, sidefd,
- root, profile, job, job ? job->id : 0, pid, *pid);
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "%s%s \"%s\" not available: %s",
- job && job->printer ? job->printer->name : "",
- job && job->printer ? ": Printer driver" : "Program",
- command, strerror(errno));
-
- if (job && job->printer)
- {
- if (cupsdSetPrinterReasons(job->printer, "+cups-missing-filter-warning"))
- cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL,
- "Printer driver \"%s\" not available.", command);
- }
-
- return (0);
- }
- else if (!RunUser &&
- ((commandinfo.st_mode & (S_ISUID | S_IWOTH)) ||
- commandinfo.st_uid))
- {
- *pid = 0;
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, "
- "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, "
- "profile=%p, job=%p(%d), pid=%p) = %d",
- command, argv, envp, infd, outfd, errfd, backfd, sidefd,
- root, profile, job, job ? job->id : 0, pid, *pid);
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "%s%s \"%s\" has insecure permissions "
- "(0%o/uid=%d/gid=%d).",
- job && job->printer ? job->printer->name : "",
- job && job->printer ? ": Printer driver" : "Program",
- command, commandinfo.st_mode,
- (int)commandinfo.st_uid, (int)commandinfo.st_gid);
-
- if (job && job->printer)
- {
- if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning"))
- cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL,
- "Printer driver \"%s\" has insecure permissions "
- "(0%o/uid=%d/gid=%d).", command, commandinfo.st_mode,
- (int)commandinfo.st_uid, (int)commandinfo.st_gid);
- }
-
- errno = EPERM;
-
- return (0);
- }
- else if ((commandinfo.st_uid != user || !(commandinfo.st_mode & S_IXUSR)) &&
- (commandinfo.st_gid != Group || !(commandinfo.st_mode & S_IXGRP)) &&
- !(commandinfo.st_mode & S_IXOTH))
- {
- *pid = 0;
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, "
- "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, "
- "profile=%p, job=%p(%d), pid=%p) = %d",
- command, argv, envp, infd, outfd, errfd, backfd, sidefd,
- root, profile, job, job ? job->id : 0, pid, *pid);
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "%s%s \"%s\" does not have execute permissions "
- "(0%o/uid=%d/gid=%d).",
- job && job->printer ? job->printer->name : "",
- job && job->printer ? ": Printer driver" : "Program",
- command, commandinfo.st_mode, (int)commandinfo.st_uid,
- (int)commandinfo.st_gid);
-
- errno = EPERM;
+ if (!cupsdCheckProgram(command, job ? job->printer : NULL))
return (0);
- }
- else if (!RunUser && commandinfo.st_gid && (commandinfo.st_mode & S_IWGRP))
- {
- cupsdLogMessage(CUPSD_LOG_WARN,
- "%s%s \"%s\" has insecure permissions "
- "(0%o/uid=%d/gid=%d).",
- job && job->printer ? job->printer->name : "",
- job && job->printer ? ": Printer driver" : "Program",
- command, commandinfo.st_mode,
- (int)commandinfo.st_uid, (int)commandinfo.st_gid);
-
-#ifdef __APPLE__ /* Don't flag filters with group write for "admin" */
- if (commandinfo.st_gid != 80 && job && job->printer)
-#else
- if (job && job->printer)
-#endif /* __APPLE__ */
- {
- if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning"))
- cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL,
- "Printer driver \"%s\" has insecure permissions "
- "(0%o/uid=%d/gid=%d).", command, commandinfo.st_mode,
- (int)commandinfo.st_uid, (int)commandinfo.st_gid);
- }
- }
#if defined(__APPLE__)
if (envp)
*
* Mini-daemon utility functions for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
*
* Contents:
*
+ * cupsdCheckProgram() - Check the permissions of the given program and
+ * its containing directory.
* cupsdCompareNames() - Compare two names.
* cupsdCreateStringsArray() - Create a CUPS array of strings.
* cupsdExec() - Run a program with the correct environment.
#endif /* __APPLE__ */
+/*
+ * 'cupsdCheckProgram()' - Check the permissions of the given program and its
+ * containing directory.
+ *
+ * Note: This function is a parallel implementation of the scheduler function
+ * of the same name.
+ */
+
+int /* O - 1 if OK, 0 if not OK */
+cupsdCheckProgram(
+ const char *filename) /* I - Filename to check */
+{
+ struct stat fileinfo; /* File information */
+ char temp[1024], /* Parent directory filename */
+ *ptr; /* Pointer into parent directory */
+
+
+ /*
+ * Does the program even exist and is it accessible?
+ */
+
+ if (stat(filename, &fileinfo))
+ {
+ /*
+ * Nope...
+ */
+
+ fprintf(stderr, "ERROR: Program \"%s\" not available: %s", filename,
+ strerror(errno));
+
+ return (0);
+ }
+
+ /*
+ * Are we running as root?
+ */
+
+ if (geteuid())
+ {
+ /*
+ * Nope, so anything goes...
+ */
+
+ return (1);
+ }
+
+ /*
+ * Verify permission of the program itself:
+ *
+ * 1. Must be owned by root
+ * 2. Must not be writable by group unless group is root/wheel/admin
+ * 3. Must not be setuid
+ * 4. Must not be writable by others
+ */
+
+ if (fileinfo.st_uid || /* 1. Must be owned by root */
+#ifdef __APPLE__
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid &&
+ fileinfo.st_gid != 80) || /* 2. Must not be writable by group */
+#else
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid) ||
+ /* 2. Must not be writable by group */
+#endif /* __APPLE__ */
+ (fileinfo.st_mode & S_ISUID) || /* 3. Must not be setuid */
+ (fileinfo.st_mode & S_IWOTH)) /* 4. Must not be writable by others */
+ {
+ fprintf(stderr,
+ "ERROR: Program \"%s\" has insecure permissions "
+ "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode,
+ (int)fileinfo.st_uid, (int)fileinfo.st_gid);
+
+ errno = EPERM;
+
+ return (0);
+ }
+
+ fprintf(stderr, "DEBUG2: Program \"%s\" permissions OK (0%o/uid=%d/gid=%d).",
+ filename, fileinfo.st_mode, (int)fileinfo.st_uid,
+ (int)fileinfo.st_gid);
+
+ /*
+ * Now check the containing directory...
+ */
+
+ strlcpy(temp, filename, sizeof(temp));
+ if ((ptr = strrchr(temp, '/')) != NULL)
+ {
+ if (ptr == temp)
+ ptr[1] = '\0';
+ else
+ *ptr = '\0';
+ }
+
+ if (stat(temp, &fileinfo))
+ {
+ /*
+ * Doesn't exist...
+ */
+
+ fprintf(stderr, "ERROR: Program directory \"%s\" not available: %s", temp,
+ strerror(errno));
+
+ return (0);
+ }
+
+ if (fileinfo.st_uid || /* 1. Must be owned by root */
+#ifdef __APPLE__
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid &&
+ fileinfo.st_gid != 80) || /* 2. Must not be writable by group */
+#else
+ ((fileinfo.st_mode & S_IWGRP) && fileinfo.st_gid) ||
+ /* 2. Must not be writable by group */
+#endif /* __APPLE__ */
+ (fileinfo.st_mode & S_ISUID) || /* 3. Must not be setuid */
+ (fileinfo.st_mode & S_IWOTH)) /* 4. Must not be writable by others */
+ {
+ fprintf(stderr,
+ "ERROR: Program directory \"%s\" has insecure permissions "
+ "(0%o/uid=%d/gid=%d).", temp, fileinfo.st_mode,
+ (int)fileinfo.st_uid, (int)fileinfo.st_gid);
+
+ errno = EPERM;
+
+ return (0);
+ }
+
+ fprintf(stderr,
+ "DEBUG2: Program directory \"%s\" permissions OK "
+ "(0%o/uid=%d/gid=%d).", temp, fileinfo.st_mode, (int)fileinfo.st_uid,
+ (int)fileinfo.st_gid);
+
+ /*
+ * If we get here then we can "safely" run this program...
+ */
+
+ return (1);
+}
+
+
/*
* 'cupsdCompareNames()' - Compare two names.
*