diff options
author | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2007-07-19 23:13:28 +0000 |
---|---|---|
committer | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2007-07-19 23:13:28 +0000 |
commit | cc0d019f5e08f870f94b8fee5f264b287fcecc3c (patch) | |
tree | c5cff932a47ff16a51ea352ca3fd949c6801bb02 /scheduler/cups-deviced.c | |
parent | bc44d92092094935265183305a38196ce2822756 (diff) | |
download | cups-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.c | 113 |
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 $". */ |