/*
- * "$Id: cups-deviced.c 4881 2005-12-15 22:03:40Z mike $"
+ * "$Id: cups-deviced.c 5044 2006-02-01 21:35:30Z mike $"
*
* Device scanning mini-daemon for the Common UNIX Printing System (CUPS).
*
static int alarm_tripped; /* Non-zero if alarm was tripped */
static cups_array_t *devs; /* Device info */
+static int normal_user; /* Normal user ID */
/*
{
const char *server_bin; /* CUPS_SERVERBIN environment variable */
char backends[1024]; /* Location of backends */
+ int request_id; /* Request ID */
int count; /* Number of devices from backend */
int compat; /* Compatibility device? */
FILE *fp; /* Pipe to device backend */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+ setbuf(stderr, NULL);
+
/*
* Check the command-line...
*/
- if (argc != 4)
+ if (argc > 1)
+ request_id = atoi(argv[1]);
+ else
+ request_id = 1;
+
+ if (argc != 5)
+ {
+ fputs("Usage: cups-deviced request-id limit user-id options\n", stderr);
+
+ cupsdSendIPPHeader(IPP_BAD_REQUEST, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message",
+ "Bad command-line arguments passed to cups-deviced!");
+ cupsdSendIPPTrailer();
+
+ return (1);
+ }
+
+ if (request_id < 1)
{
- fputs("Usage: cups-deviced request_id limit options\n", stderr);
+ fprintf(stderr, "cups-deviced: Bad request ID %d!\n", request_id);
+
+ cupsdSendIPPHeader(IPP_BAD_REQUEST, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message",
+ "Bad request ID argument passed to cups-deviced!");
+ cupsdSendIPPTrailer();
+
return (1);
}
- num_options = cupsParseOptions(argv[3], 0, &options);
+ normal_user = atoi(argv[3]);
+ if (normal_user <= 0)
+ {
+ fprintf(stderr, "cups-deviced: Bad user %d!\n", normal_user);
+
+ cupsdSendIPPHeader(IPP_BAD_REQUEST, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message",
+ "Bad user ID argument passed to cups-deviced!");
+ cupsdSendIPPTrailer();
+
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[4], 0, &options);
requested = cupsGetOption("requested-attributes", num_options, options);
if (!requested || strstr(requested, "all"))
if ((dir = cupsDirOpen(backends)) == NULL)
{
- fprintf(stderr, "ERROR: [cups-deviced] Unable to open backend directory \"%s\": %s",
- backends, strerror(errno));
+ fprintf(stderr, "ERROR: [cups-deviced] Unable to open backend directory "
+ "\"%s\": %s", backends, strerror(errno));
+
+ snprintf(line, sizeof(line), "Unable to open backend directory \"%s\": %s",
+ backends, strerror(errno));
+ cupsdSendIPPHeader(IPP_BAD_REQUEST, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", line);
+ cupsdSendIPPTrailer();
+
return (1);
}
while ((dent = cupsDirRead(dir)) != NULL)
{
+ /*
+ * Skip entries that are not executable files...
+ */
+
+ if (!S_ISREG(dent->fileinfo.st_mode) ||
+ (dent->fileinfo.st_mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR))
+ continue;
+
+ /*
+ * 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...
+ */
+
+ if (!(dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO)))
+ seteuid(0);
+ else
+ seteuid(normal_user);
+ }
+
/*
* Run the backend with no arguments and collect the output...
*/
return (1);
}
- fprintf(stderr, "DEBUG: [cups-deviced] Added device \"%s\"...\n", uri);
+ fprintf(stderr, "DEBUG: [cups-deviced] Added device \"%s\"...\n",
+ uri);
count ++;
}
}
alarm(0);
if (alarm_tripped)
- fprintf(stderr, "WARNING: [cups-deviced] Backend \"%s\" did not respond within 30 seconds!\n",
- dent->filename);
+ fprintf(stderr, "WARNING: [cups-deviced] Backend \"%s\" did not "
+ "respond within 30 seconds!\n", dent->filename);
pclose(fp);
return (1);
}
- fprintf(stderr, "DEBUG: [cups-deviced] Compatibility device \"%s\"...\n",
- dent->filename);
+ fprintf(stderr, "DEBUG: [cups-deviced] Compatibility device "
+ "\"%s\"...\n", dent->filename);
}
}
else
- fprintf(stderr, "WARNING: [cups-deviced] Unable to execute \"%s\" backend: %s\n",
- dent->filename, strerror(errno));
+ fprintf(stderr, "WARNING: [cups-deviced] Unable to execute \"%s\" "
+ "backend: %s\n", dent->filename, strerror(errno));
}
cupsDirClose(dir);
+ /*
+ * Switch back to root as needed...
+ */
+
+ if (!getuid() && geteuid())
+ seteuid(0);
+
/*
* Output the list of devices...
*/
puts("Content-Type: application/ipp\n");
- cupsdSendIPPHeader(IPP_OK, atoi(argv[1]));
+ cupsdSendIPPHeader(IPP_OK, request_id);
cupsdSendIPPGroup(IPP_TAG_OPERATION);
cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
/*
- * End of "$Id: cups-deviced.c 4881 2005-12-15 22:03:40Z mike $".
+ * End of "$Id: cups-deviced.c 5044 2006-02-01 21:35:30Z mike $".
*/