summaryrefslogtreecommitdiff
path: root/scheduler/cups-deviced.c
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2007-07-19 23:13:28 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2007-07-19 23:13:28 +0000
commitcc0d019f5e08f870f94b8fee5f264b287fcecc3c (patch)
treec5cff932a47ff16a51ea352ca3fd949c6801bb02 /scheduler/cups-deviced.c
parentbc44d92092094935265183305a38196ce2822756 (diff)
downloadcups-cc0d019f5e08f870f94b8fee5f264b287fcecc3c.tar.gz
Update to CUPS trunk r6695.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@352 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'scheduler/cups-deviced.c')
-rw-r--r--scheduler/cups-deviced.c113
1 files changed, 85 insertions, 28 deletions
diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c
index 55aa577f4..9a92732b5 100644
--- a/scheduler/cups-deviced.c
+++ b/scheduler/cups-deviced.c
@@ -1,5 +1,5 @@
/*
- * "$Id: cups-deviced.c 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id: cups-deviced.c 6693 2007-07-19 21:02:36Z mike $"
*
* Device scanning mini-daemon for the Common UNIX Printing System (CUPS).
*
@@ -17,6 +17,7 @@
* main() - Scan for devices and return an IPP response.
* add_dev() - Add a new device to the list.
* compare_devs() - Compare device names for sorting.
+ * run_backend() - Run a backend to gather the available devices.
* sigalrm_handler() - Handle alarm signals for backends that get hung
*/
@@ -27,10 +28,7 @@
#include "util.h"
#include <cups/array.h>
#include <cups/dir.h>
-
-#ifdef __hpux
-# define seteuid(uid) setresuid(-1, (uid), -1)
-#endif /* __hpux */
+#include <fcntl.h>
/*
@@ -66,6 +64,7 @@ static dev_info_t *add_dev(const char *device_class,
const char *device_uri,
const char *device_id);
static int compare_devs(dev_info_t *p0, dev_info_t *p1);
+static FILE *run_backend(const char *backend, int uid, int *pid);
static void sigalrm_handler(int sig);
@@ -87,6 +86,7 @@ main(int argc, /* I - Number of command-line args */
int count; /* Number of devices from backend */
int compat; /* Compatibility device? */
FILE *fp; /* Pipe to device backend */
+ int pid; /* Process ID of backend */
cups_dir_t *dir; /* Directory pointer */
cups_dentry_t *dent; /* Directory entry */
char filename[1024], /* Name of backend */
@@ -204,25 +204,23 @@ main(int argc, /* I - Number of command-line args */
* Change effective users depending on the backend permissions...
*/
- if (!getuid())
- {
- /*
- * Backends without permissions for normal users run as root,
- * all others run as the unprivileged user...
- */
+ snprintf(filename, sizeof(filename), "%s/%s", backends, dent->filename);
- if (!(dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO)))
- seteuid(0);
- else
- seteuid(normal_user);
- }
+ /*
+ * Backends without permissions for normal users run as root,
+ * all others run as the unprivileged user...
+ */
+
+ fp = run_backend(filename,
+ (dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO))
+ ? normal_user : 0,
+ &pid);
/*
- * Run the backend with no arguments and collect the output...
+ * Collect the output from the backend...
*/
- snprintf(filename, sizeof(filename), "%s/%s", backends, dent->filename);
- if ((fp = popen(filename, "r")) != NULL)
+ if (fp)
{
/*
* Set an alarm for the first read from the backend; this avoids
@@ -312,7 +310,8 @@ main(int argc, /* I - Number of command-line args */
fprintf(stderr, "WARNING: [cups-deviced] Backend \"%s\" did not "
"respond within 30 seconds!\n", dent->filename);
- pclose(fp);
+ fclose(fp);
+ kill(pid, SIGTERM);
/*
* Hack for backends that don't support the CUPS 1.1 calling convention:
@@ -343,13 +342,6 @@ main(int argc, /* I - Number of command-line args */
cupsDirClose(dir);
/*
- * Switch back to root as needed...
- */
-
- if (!getuid() && geteuid())
- seteuid(0);
-
- /*
* Output the list of devices...
*/
@@ -477,6 +469,71 @@ compare_devs(dev_info_t *d0, /* I - First device */
/*
+ * 'run_backend()' - Run a backend to gather the available devices.
+ */
+
+static FILE * /* O - stdout of backend */
+run_backend(const char *backend, /* I - Backend to run */
+ int uid, /* I - User ID to run as */
+ int *pid) /* O - Process ID of backend */
+{
+ int fds[2]; /* Pipe file descriptors */
+
+
+ if (pipe(fds))
+ {
+ fprintf(stderr, "ERROR: Unable to create a pipe for \"%s\" - %s\n",
+ backend, strerror(errno));
+ return (NULL);
+ }
+
+ if ((*pid = fork()) < 0)
+ {
+ /*
+ * Error!
+ */
+
+ fprintf(stderr, "ERROR: Unable to fork for \"%s\" - %s\n", backend,
+ strerror(errno));
+ close(fds[0]);
+ close(fds[1]);
+ return (NULL);
+ }
+ else if (!*pid)
+ {
+ /*
+ * Child comes here...
+ */
+
+ if (!getuid() && uid)
+ setuid(uid); /* Run as restricted user */
+
+ close(0); /* </dev/null */
+ open("/dev/null", O_RDONLY);
+
+ close(1); /* >pipe */
+ dup(fds[1]);
+
+ close(fds[0]); /* Close copies of pipes */
+ close(fds[1]);
+
+ execl(backend, backend, (char *)0); /* Run it! */
+ fprintf(stderr, "ERROR: Unable to execute \"%s\" - %s\n", backend,
+ strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Parent comes here, make a FILE * from the input side of the pipe...
+ */
+
+ close(fds[1]);
+
+ return (fdopen(fds[0], "r"));
+}
+
+
+/*
* 'sigalrm_handler()' - Handle alarm signals for backends that get hung
* trying to list the available devices...
*/
@@ -491,5 +548,5 @@ sigalrm_handler(int sig) /* I - Signal number */
/*
- * End of "$Id: cups-deviced.c 6649 2007-07-11 21:46:42Z mike $".
+ * End of "$Id: cups-deviced.c 6693 2007-07-19 21:02:36Z mike $".
*/